ActivityManagerService.java revision 46f7f1c245e3bd297ce594a4e3aa7e89363b5e05
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.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21import static android.Manifest.permission.INTERACT_ACROSS_USERS;
22import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
23import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
24import static android.Manifest.permission.READ_FRAME_BUFFER;
25import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
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_ACTIVITIES_ON_SECONDARY_DISPLAYS;
34import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
35import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
36import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
37import static android.content.pm.PackageManager.GET_PROVIDERS;
38import static android.content.pm.PackageManager.MATCH_ANY_USER;
39import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
40import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
41import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
42import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
43import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
44import static android.content.pm.PackageManager.PERMISSION_GRANTED;
45import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
46import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
47import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
48import static android.os.Build.VERSION_CODES.N;
49import static android.os.Process.BLUETOOTH_UID;
50import static android.os.Process.FIRST_APPLICATION_UID;
51import static android.os.Process.FIRST_ISOLATED_UID;
52import static android.os.Process.LAST_ISOLATED_UID;
53import static android.os.Process.NFC_UID;
54import static android.os.Process.PHONE_UID;
55import static android.os.Process.PROC_CHAR;
56import static android.os.Process.PROC_OUT_LONG;
57import static android.os.Process.PROC_PARENS;
58import static android.os.Process.PROC_SPACE_TERM;
59import static android.os.Process.ProcessStartResult;
60import static android.os.Process.ROOT_UID;
61import static android.os.Process.SCHED_FIFO;
62import static android.os.Process.SCHED_OTHER;
63import static android.os.Process.SCHED_RESET_ON_FORK;
64import static android.os.Process.SHELL_UID;
65import static android.os.Process.SIGNAL_QUIT;
66import static android.os.Process.SIGNAL_USR1;
67import static android.os.Process.SYSTEM_UID;
68import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
69import static android.os.Process.THREAD_GROUP_DEFAULT;
70import static android.os.Process.THREAD_GROUP_TOP_APP;
71import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
72import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
73import static android.os.Process.getFreeMemory;
74import static android.os.Process.getTotalMemory;
75import static android.os.Process.isThreadInProcess;
76import static android.os.Process.killProcess;
77import static android.os.Process.killProcessQuiet;
78import static android.os.Process.myPid;
79import static android.os.Process.myUid;
80import static android.os.Process.readProcFile;
81import static android.os.Process.removeAllProcessGroups;
82import static android.os.Process.sendSignal;
83import static android.os.Process.setProcessGroup;
84import static android.os.Process.setThreadPriority;
85import static android.os.Process.setThreadScheduler;
86import static android.os.Process.startWebView;
87import static android.os.Process.zygoteProcess;
88import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
89import static android.provider.Settings.Global.DEBUG_APP;
90import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
91import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
92import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
93import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
94import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
95import static android.provider.Settings.System.FONT_SCALE;
96import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
97import static android.view.Display.DEFAULT_DISPLAY;
98import static android.view.Display.INVALID_DISPLAY;
99import static com.android.internal.util.XmlUtils.readBooleanAttribute;
100import static com.android.internal.util.XmlUtils.readIntAttribute;
101import static com.android.internal.util.XmlUtils.readLongAttribute;
102import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
103import static com.android.internal.util.XmlUtils.writeIntAttribute;
104import static com.android.internal.util.XmlUtils.writeLongAttribute;
105import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
106import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
107import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
108import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
109import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
110import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
111import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
112import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
113import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
114import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
115import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
116import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
117import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
118import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
119import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
120import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
121import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
122import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
123import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
124import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
125import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
126import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
127import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
128import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
139import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
140import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
141import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
142import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
143import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
144import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
145import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
146import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
147import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
148import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
152import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
153import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
154import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
155import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
156import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
157import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
158import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
159import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
160import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
161import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
162import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
163import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
164import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
165import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
166import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
167import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
168import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
169import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
170import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
171import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
172import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
173import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
174import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
175import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
176import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
177import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
178import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
179import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
180import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
181import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
182import static com.android.server.wm.AppTransition.TRANSIT_NONE;
183import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
184import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
185import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
186import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
187import static org.xmlpull.v1.XmlPullParser.START_TAG;
188
189import android.Manifest;
190import android.Manifest.permission;
191import android.annotation.NonNull;
192import android.annotation.Nullable;
193import android.annotation.UserIdInt;
194import android.app.Activity;
195import android.app.ActivityManager;
196import android.app.ActivityManager.RunningTaskInfo;
197import android.app.ActivityManager.StackId;
198import android.app.ActivityManager.StackInfo;
199import android.app.ActivityManager.TaskSnapshot;
200import android.app.ActivityManager.TaskThumbnailInfo;
201import android.app.ActivityManagerInternal;
202import android.app.ActivityManagerInternal.SleepToken;
203import android.app.ActivityOptions;
204import android.app.ActivityThread;
205import android.app.AlertDialog;
206import android.app.AppGlobals;
207import android.app.AppOpsManager;
208import android.app.ApplicationErrorReport;
209import android.app.ApplicationThreadConstants;
210import android.app.BroadcastOptions;
211import android.app.ContentProviderHolder;
212import android.app.Dialog;
213import android.app.IActivityContainer;
214import android.app.IActivityContainerCallback;
215import android.app.IActivityController;
216import android.app.IActivityManager;
217import android.app.IAppTask;
218import android.app.IApplicationThread;
219import android.app.IInstrumentationWatcher;
220import android.app.INotificationManager;
221import android.app.IProcessObserver;
222import android.app.IServiceConnection;
223import android.app.IStopUserCallback;
224import android.app.ITaskStackListener;
225import android.app.IUiAutomationConnection;
226import android.app.IUidObserver;
227import android.app.IUserSwitchObserver;
228import android.app.Instrumentation;
229import android.app.Notification;
230import android.app.NotificationManager;
231import android.app.PendingIntent;
232import android.app.PictureInPictureArgs;
233import android.app.ProfilerInfo;
234import android.app.RemoteAction;
235import android.app.WaitResult;
236import android.app.admin.DevicePolicyManager;
237import android.app.assist.AssistContent;
238import android.app.assist.AssistStructure;
239import android.app.backup.IBackupManager;
240import android.app.usage.UsageEvents;
241import android.app.usage.UsageStatsManagerInternal;
242import android.appwidget.AppWidgetManager;
243import android.content.ActivityNotFoundException;
244import android.content.BroadcastReceiver;
245import android.content.ClipData;
246import android.content.ComponentCallbacks2;
247import android.content.ComponentName;
248import android.content.ContentProvider;
249import android.content.ContentResolver;
250import android.content.Context;
251import android.content.DialogInterface;
252import android.content.IContentProvider;
253import android.content.IIntentReceiver;
254import android.content.IIntentSender;
255import android.content.Intent;
256import android.content.IntentFilter;
257import android.content.IntentSender;
258import android.content.pm.ActivityInfo;
259import android.content.pm.ApplicationInfo;
260import android.content.pm.ConfigurationInfo;
261import android.content.pm.IPackageDataObserver;
262import android.content.pm.IPackageManager;
263import android.content.pm.InstrumentationInfo;
264import android.content.pm.PackageInfo;
265import android.content.pm.PackageManager;
266import android.content.pm.PackageManager.NameNotFoundException;
267import android.content.pm.PackageManagerInternal;
268import android.content.pm.ParceledListSlice;
269import android.content.pm.PathPermission;
270import android.content.pm.PermissionInfo;
271import android.content.pm.ProviderInfo;
272import android.content.pm.ResolveInfo;
273import android.content.pm.SELinuxUtil;
274import android.content.pm.ServiceInfo;
275import android.content.pm.UserInfo;
276import android.content.res.CompatibilityInfo;
277import android.content.res.Configuration;
278import android.content.res.Resources;
279import android.database.ContentObserver;
280import android.graphics.Bitmap;
281import android.graphics.Point;
282import android.graphics.Rect;
283import android.location.LocationManager;
284import android.media.audiofx.AudioEffect;
285import android.metrics.LogMaker;
286import android.net.Proxy;
287import android.net.ProxyInfo;
288import android.net.Uri;
289import android.os.BatteryStats;
290import android.os.Binder;
291import android.os.Build;
292import android.os.Bundle;
293import android.os.Debug;
294import android.os.DropBoxManager;
295import android.os.Environment;
296import android.os.FactoryTest;
297import android.os.FileObserver;
298import android.os.FileUtils;
299import android.os.Handler;
300import android.os.IBinder;
301import android.os.IDeviceIdentifiersPolicyService;
302import android.os.IPermissionController;
303import android.os.IProcessInfoService;
304import android.os.IProgressListener;
305import android.os.LocaleList;
306import android.os.Looper;
307import android.os.Message;
308import android.os.Parcel;
309import android.os.ParcelFileDescriptor;
310import android.os.PersistableBundle;
311import android.os.PowerManager;
312import android.os.PowerManagerInternal;
313import android.os.Process;
314import android.os.RemoteCallbackList;
315import android.os.RemoteException;
316import android.os.ResultReceiver;
317import android.os.ServiceManager;
318import android.os.ShellCallback;
319import android.os.StrictMode;
320import android.os.SystemClock;
321import android.os.SystemProperties;
322import android.os.Trace;
323import android.os.TransactionTooLargeException;
324import android.os.UpdateLock;
325import android.os.UserHandle;
326import android.os.UserManager;
327import android.os.WorkSource;
328import android.os.storage.IStorageManager;
329import android.os.storage.StorageManager;
330import android.os.storage.StorageManagerInternal;
331import android.provider.Downloads;
332import android.provider.Settings;
333import android.service.voice.IVoiceInteractionSession;
334import android.service.voice.VoiceInteractionManagerInternal;
335import android.service.voice.VoiceInteractionSession;
336import android.telecom.TelecomManager;
337import android.text.TextUtils;
338import android.text.format.DateUtils;
339import android.text.format.Time;
340import android.text.style.SuggestionSpan;
341import android.util.ArrayMap;
342import android.util.ArraySet;
343import android.util.AtomicFile;
344import android.util.BootTimingsTraceLog;
345import android.util.DebugUtils;
346import android.util.DisplayMetrics;
347import android.util.EventLog;
348import android.util.Log;
349import android.util.Pair;
350import android.util.PrintWriterPrinter;
351import android.util.Slog;
352import android.util.SparseArray;
353import android.util.SparseIntArray;
354import android.util.TimeUtils;
355import android.util.Xml;
356import android.view.Gravity;
357import android.view.LayoutInflater;
358import android.view.View;
359import android.view.WindowManager;
360
361import com.google.android.collect.Lists;
362import com.google.android.collect.Maps;
363
364import com.android.internal.R;
365import com.android.internal.annotations.GuardedBy;
366import com.android.internal.annotations.VisibleForTesting;
367import com.android.internal.app.AssistUtils;
368import com.android.internal.app.DumpHeapActivity;
369import com.android.internal.app.IAppOpsCallback;
370import com.android.internal.app.IAppOpsService;
371import com.android.internal.app.IVoiceInteractor;
372import com.android.internal.app.ProcessMap;
373import com.android.internal.app.SystemUserHomeActivity;
374import com.android.internal.app.procstats.ProcessStats;
375import com.android.internal.logging.MetricsLogger;
376import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
377import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
378import com.android.internal.notification.SystemNotificationChannels;
379import com.android.internal.os.BackgroundThread;
380import com.android.internal.os.BatteryStatsImpl;
381import com.android.internal.os.IResultReceiver;
382import com.android.internal.os.ProcessCpuTracker;
383import com.android.internal.os.TransferPipe;
384import com.android.internal.os.Zygote;
385import com.android.internal.policy.IKeyguardDismissCallback;
386import com.android.internal.telephony.TelephonyIntents;
387import com.android.internal.util.ArrayUtils;
388import com.android.internal.util.DumpUtils;
389import com.android.internal.util.FastPrintWriter;
390import com.android.internal.util.FastXmlSerializer;
391import com.android.internal.util.MemInfoReader;
392import com.android.internal.util.Preconditions;
393import com.android.server.AppOpsService;
394import com.android.server.AttributeCache;
395import com.android.server.DeviceIdleController;
396import com.android.server.IntentResolver;
397import com.android.server.LocalServices;
398import com.android.server.LockGuard;
399import com.android.server.NetworkManagementInternal;
400import com.android.server.RescueParty;
401import com.android.server.ServiceThread;
402import com.android.server.SystemConfig;
403import com.android.server.SystemService;
404import com.android.server.SystemServiceManager;
405import com.android.server.ThreadPriorityBooster;
406import com.android.server.Watchdog;
407import com.android.server.am.ActivityStack.ActivityState;
408import com.android.server.firewall.IntentFirewall;
409import com.android.server.pm.Installer;
410import com.android.server.pm.Installer.InstallerException;
411import com.android.server.statusbar.StatusBarManagerInternal;
412import com.android.server.vr.VrManagerInternal;
413import com.android.server.wm.WindowManagerService;
414
415import org.xmlpull.v1.XmlPullParser;
416import org.xmlpull.v1.XmlPullParserException;
417import org.xmlpull.v1.XmlSerializer;
418
419import java.io.File;
420import java.io.FileDescriptor;
421import java.io.FileInputStream;
422import java.io.FileNotFoundException;
423import java.io.FileOutputStream;
424import java.io.IOException;
425import java.io.InputStreamReader;
426import java.io.PrintWriter;
427import java.io.StringWriter;
428import java.io.UnsupportedEncodingException;
429import java.lang.ref.WeakReference;
430import java.nio.charset.StandardCharsets;
431import java.util.ArrayList;
432import java.util.Arrays;
433import java.util.Collections;
434import java.util.Comparator;
435import java.util.HashMap;
436import java.util.HashSet;
437import java.util.Iterator;
438import java.util.List;
439import java.util.Locale;
440import java.util.Map;
441import java.util.Objects;
442import java.util.Set;
443import java.util.concurrent.CountDownLatch;
444import java.util.concurrent.atomic.AtomicBoolean;
445import java.util.concurrent.atomic.AtomicLong;
446
447import dalvik.system.VMRuntime;
448import libcore.io.IoUtils;
449import libcore.util.EmptyArray;
450
451public class ActivityManagerService extends IActivityManager.Stub
452        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
453
454    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
455    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
456    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
457    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
458    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
459    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
460    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
461    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
462    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
463    private static final String TAG_LRU = TAG + POSTFIX_LRU;
464    private static final String TAG_MU = TAG + POSTFIX_MU;
465    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
466    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
467    private static final String TAG_POWER = TAG + POSTFIX_POWER;
468    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
469    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
470    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
471    private static final String TAG_PSS = TAG + POSTFIX_PSS;
472    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
473    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
474    private static final String TAG_STACK = TAG + POSTFIX_STACK;
475    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
476    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
477    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
478    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
479    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
480
481    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
482    // here so that while the job scheduler can depend on AMS, the other way around
483    // need not be the case.
484    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
485
486    /** Control over CPU and battery monitoring */
487    // write battery stats every 30 minutes.
488    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
489    static final boolean MONITOR_CPU_USAGE = true;
490    // don't sample cpu less than every 5 seconds.
491    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
492    // wait possibly forever for next cpu sample.
493    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
494    static final boolean MONITOR_THREAD_CPU_USAGE = false;
495
496    // The flags that are set for all calls we make to the package manager.
497    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
498
499    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
500
501    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
502
503    // Amount of time after a call to stopAppSwitches() during which we will
504    // prevent further untrusted switches from happening.
505    static final long APP_SWITCH_DELAY_TIME = 5*1000;
506
507    // How long we wait for a launched process to attach to the activity manager
508    // before we decide it's never going to come up for real.
509    static final int PROC_START_TIMEOUT = 10*1000;
510    // How long we wait for an attached process to publish its content providers
511    // before we decide it must be hung.
512    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
513
514    // How long we will retain processes hosting content providers in the "last activity"
515    // state before allowing them to drop down to the regular cached LRU list.  This is
516    // to avoid thrashing of provider processes under low memory situations.
517    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
518
519    // How long we wait for a launched process to attach to the activity manager
520    // before we decide it's never going to come up for real, when the process was
521    // started with a wrapper for instrumentation (such as Valgrind) because it
522    // could take much longer than usual.
523    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
524
525    // How long to wait after going idle before forcing apps to GC.
526    static final int GC_TIMEOUT = 5*1000;
527
528    // The minimum amount of time between successive GC requests for a process.
529    static final int GC_MIN_INTERVAL = 60*1000;
530
531    // The minimum amount of time between successive PSS requests for a process.
532    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
533
534    // The minimum amount of time between successive PSS requests for a process
535    // when the request is due to the memory state being lowered.
536    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
537
538    // The rate at which we check for apps using excessive power -- 15 mins.
539    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
540
541    // The minimum sample duration we will allow before deciding we have
542    // enough data on wake locks to start killing things.
543    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
544
545    // The minimum sample duration we will allow before deciding we have
546    // enough data on CPU usage to start killing things.
547    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
548
549    // How long we allow a receiver to run before giving up on it.
550    static final int BROADCAST_FG_TIMEOUT = 10*1000;
551    static final int BROADCAST_BG_TIMEOUT = 60*1000;
552
553    // How long we wait until we timeout on key dispatching.
554    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
555
556    // How long we wait until we timeout on key dispatching during instrumentation.
557    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
558
559    // This is the amount of time an app needs to be running a foreground service before
560    // we will consider it to be doing interaction for usage stats.
561    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
562
563    // Maximum amount of time we will allow to elapse before re-reporting usage stats
564    // interaction with foreground processes.
565    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
566
567    // This is the amount of time we allow an app to settle after it goes into the background,
568    // before we start restricting what it can do.
569    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
570
571    // How long to wait in getAssistContextExtras for the activity and foreground services
572    // to respond with the result.
573    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
574
575    // How long top wait when going through the modern assist (which doesn't need to block
576    // on getting this result before starting to launch its UI).
577    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
578
579    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
580    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
581
582    // Maximum number of persisted Uri grants a package is allowed
583    static final int MAX_PERSISTED_URI_GRANTS = 128;
584
585    static final int MY_PID = myPid();
586
587    static final String[] EMPTY_STRING_ARRAY = new String[0];
588
589    // How many bytes to write into the dropbox log before truncating
590    static final int DROPBOX_MAX_SIZE = 192 * 1024;
591    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
592    // as one line, but close enough for now.
593    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
594
595    // Access modes for handleIncomingUser.
596    static final int ALLOW_NON_FULL = 0;
597    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
598    static final int ALLOW_FULL_ONLY = 2;
599
600    // Necessary ApplicationInfo flags to mark an app as persistent
601    private static final int PERSISTENT_MASK =
602            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
603
604    // Intent sent when remote bugreport collection has been completed
605    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
606            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
607
608    // Used to indicate that an app transition should be animated.
609    static final boolean ANIMATE = true;
610
611    // Determines whether to take full screen screenshots
612    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
613
614    // STOPSHIP: Update default to a smaller value.
615    /**
616     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
617     */
618    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 2000; // 2 sec
619
620    /**
621     * State indicating that there is no need for any blocking for network.
622     */
623    @VisibleForTesting
624    static final int NETWORK_STATE_NO_CHANGE = 0;
625
626    /**
627     * State indicating that the main thread needs to be informed about the network wait.
628     */
629    @VisibleForTesting
630    static final int NETWORK_STATE_BLOCK = 1;
631
632    /**
633     * State indicating that any threads waiting for network state to get updated can be unblocked.
634     */
635    @VisibleForTesting
636    static final int NETWORK_STATE_UNBLOCK = 2;
637
638    // Max character limit for a notification title. If the notification title is larger than this
639    // the notification will not be legible to the user.
640    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
641
642    /** All system services */
643    SystemServiceManager mSystemServiceManager;
644    AssistUtils mAssistUtils;
645
646    private Installer mInstaller;
647
648    /** Run all ActivityStacks through this */
649    final ActivityStackSupervisor mStackSupervisor;
650    private final KeyguardController mKeyguardController;
651
652    final ActivityStarter mActivityStarter;
653
654    final TaskChangeNotificationController mTaskChangeNotificationController;
655
656    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
657
658    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
659
660    public final IntentFirewall mIntentFirewall;
661
662    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
663    // default action automatically.  Important for devices without direct input
664    // devices.
665    private boolean mShowDialogs = true;
666
667    private final VrController mVrController;
668
669    // VR Compatibility Display Id.
670    int mVrCompatibilityDisplayId = INVALID_DISPLAY;
671
672    // Whether we should use SCHED_FIFO for UI and RenderThreads.
673    private boolean mUseFifoUiScheduling = false;
674
675    BroadcastQueue mFgBroadcastQueue;
676    BroadcastQueue mBgBroadcastQueue;
677    // Convenient for easy iteration over the queues. Foreground is first
678    // so that dispatch of foreground broadcasts gets precedence.
679    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
680
681    BroadcastStats mLastBroadcastStats;
682    BroadcastStats mCurBroadcastStats;
683
684    BroadcastQueue broadcastQueueForIntent(Intent intent) {
685        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
686        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
687                "Broadcast intent " + intent + " on "
688                + (isFg ? "foreground" : "background") + " queue");
689        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
690    }
691
692    /**
693     * The last resumed activity. This is identical to the current resumed activity most
694     * of the time but could be different when we're pausing one activity before we resume
695     * another activity.
696     */
697    private ActivityRecord mLastResumedActivity;
698
699    /**
700     * If non-null, we are tracking the time the user spends in the currently focused app.
701     */
702    private AppTimeTracker mCurAppTimeTracker;
703
704    /**
705     * List of intents that were used to start the most recent tasks.
706     */
707    final RecentTasks mRecentTasks;
708
709    /**
710     * For addAppTask: cached of the last activity component that was added.
711     */
712    ComponentName mLastAddedTaskComponent;
713
714    /**
715     * For addAppTask: cached of the last activity uid that was added.
716     */
717    int mLastAddedTaskUid;
718
719    /**
720     * For addAppTask: cached of the last ActivityInfo that was added.
721     */
722    ActivityInfo mLastAddedTaskActivity;
723
724    /**
725     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
726     */
727    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
728
729    /**
730     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
731     */
732    String mDeviceOwnerName;
733
734    final UserController mUserController;
735
736    final AppErrors mAppErrors;
737
738    /**
739     * Indicates the maximum time spent waiting for the network rules to get updated.
740     */
741    @VisibleForTesting
742    long mWaitForNetworkTimeoutMs;
743
744    public boolean canShowErrorDialogs() {
745        return mShowDialogs && !mSleeping && !mShuttingDown
746                && !mKeyguardController.isKeyguardShowing();
747    }
748
749    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
750            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
751
752    static void boostPriorityForLockedSection() {
753        sThreadPriorityBooster.boost();
754    }
755
756    static void resetPriorityAfterLockedSection() {
757        sThreadPriorityBooster.reset();
758    }
759
760    public class PendingAssistExtras extends Binder implements Runnable {
761        public final ActivityRecord activity;
762        public boolean isHome;
763        public final Bundle extras;
764        public final Intent intent;
765        public final String hint;
766        public final IResultReceiver receiver;
767        public final int userHandle;
768        public boolean haveResult = false;
769        public Bundle result = null;
770        public AssistStructure structure = null;
771        public AssistContent content = null;
772        public Bundle receiverExtras;
773
774        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
775                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
776            activity = _activity;
777            extras = _extras;
778            intent = _intent;
779            hint = _hint;
780            receiver = _receiver;
781            receiverExtras = _receiverExtras;
782            userHandle = _userHandle;
783        }
784
785        @Override
786        public void run() {
787            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
788            synchronized (this) {
789                haveResult = true;
790                notifyAll();
791            }
792            pendingAssistExtrasTimedOut(this);
793        }
794    }
795
796    final ArrayList<PendingAssistExtras> mPendingAssistExtras
797            = new ArrayList<PendingAssistExtras>();
798
799    /**
800     * Process management.
801     */
802    final ProcessList mProcessList = new ProcessList();
803
804    /**
805     * All of the applications we currently have running organized by name.
806     * The keys are strings of the application package name (as
807     * returned by the package manager), and the keys are ApplicationRecord
808     * objects.
809     */
810    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
811
812    /**
813     * Tracking long-term execution of processes to look for abuse and other
814     * bad app behavior.
815     */
816    final ProcessStatsService mProcessStats;
817
818    /**
819     * The currently running isolated processes.
820     */
821    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
822
823    /**
824     * Counter for assigning isolated process uids, to avoid frequently reusing the
825     * same ones.
826     */
827    int mNextIsolatedProcessUid = 0;
828
829    /**
830     * The currently running heavy-weight process, if any.
831     */
832    ProcessRecord mHeavyWeightProcess = null;
833
834    /**
835     * Non-persistent app uid whitelist for background restrictions
836     */
837    int[] mBackgroundUidWhitelist = new int[] {
838            BLUETOOTH_UID
839    };
840
841    /**
842     * Broadcast actions that will always be deliverable to unlaunched/background apps
843     */
844    ArraySet<String> mBackgroundLaunchBroadcasts;
845
846    /**
847     * All of the processes we currently have running organized by pid.
848     * The keys are the pid running the application.
849     *
850     * <p>NOTE: This object is protected by its own lock, NOT the global
851     * activity manager lock!
852     */
853    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
854
855    /**
856     * All of the processes that have been forced to be foreground.  The key
857     * is the pid of the caller who requested it (we hold a death
858     * link on it).
859     */
860    abstract class ForegroundToken implements IBinder.DeathRecipient {
861        int pid;
862        IBinder token;
863    }
864    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
865
866    /**
867     * List of records for processes that someone had tried to start before the
868     * system was ready.  We don't start them at that point, but ensure they
869     * are started by the time booting is complete.
870     */
871    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
872
873    /**
874     * List of persistent applications that are in the process
875     * of being started.
876     */
877    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
878
879    /**
880     * Processes that are being forcibly torn down.
881     */
882    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
883
884    /**
885     * List of running applications, sorted by recent usage.
886     * The first entry in the list is the least recently used.
887     */
888    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
889
890    /**
891     * Where in mLruProcesses that the processes hosting activities start.
892     */
893    int mLruProcessActivityStart = 0;
894
895    /**
896     * Where in mLruProcesses that the processes hosting services start.
897     * This is after (lower index) than mLruProcessesActivityStart.
898     */
899    int mLruProcessServiceStart = 0;
900
901    /**
902     * List of processes that should gc as soon as things are idle.
903     */
904    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
905
906    /**
907     * Processes we want to collect PSS data from.
908     */
909    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
910
911    private boolean mBinderTransactionTrackingEnabled = false;
912
913    /**
914     * Last time we requested PSS data of all processes.
915     */
916    long mLastFullPssTime = SystemClock.uptimeMillis();
917
918    /**
919     * If set, the next time we collect PSS data we should do a full collection
920     * with data from native processes and the kernel.
921     */
922    boolean mFullPssPending = false;
923
924    /**
925     * This is the process holding what we currently consider to be
926     * the "home" activity.
927     */
928    ProcessRecord mHomeProcess;
929
930    /**
931     * This is the process holding the activity the user last visited that
932     * is in a different process from the one they are currently in.
933     */
934    ProcessRecord mPreviousProcess;
935
936    /**
937     * The time at which the previous process was last visible.
938     */
939    long mPreviousProcessVisibleTime;
940
941    /**
942     * Track all uids that have actively running processes.
943     */
944    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
945
946    /**
947     * This is for verifying the UID report flow.
948     */
949    static final boolean VALIDATE_UID_STATES = true;
950    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
951
952    /**
953     * Packages that the user has asked to have run in screen size
954     * compatibility mode instead of filling the screen.
955     */
956    final CompatModePackages mCompatModePackages;
957
958    /**
959     * Set of IntentSenderRecord objects that are currently active.
960     */
961    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
962            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
963
964    /**
965     * Fingerprints (hashCode()) of stack traces that we've
966     * already logged DropBox entries for.  Guarded by itself.  If
967     * something (rogue user app) forces this over
968     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
969     */
970    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
971    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
972
973    /**
974     * Strict Mode background batched logging state.
975     *
976     * The string buffer is guarded by itself, and its lock is also
977     * used to determine if another batched write is already
978     * in-flight.
979     */
980    private final StringBuilder mStrictModeBuffer = new StringBuilder();
981
982    /**
983     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
984     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
985     */
986    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
987
988    /**
989     * Resolver for broadcast intents to registered receivers.
990     * Holds BroadcastFilter (subclass of IntentFilter).
991     */
992    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
993            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
994        @Override
995        protected boolean allowFilterResult(
996                BroadcastFilter filter, List<BroadcastFilter> dest) {
997            IBinder target = filter.receiverList.receiver.asBinder();
998            for (int i = dest.size() - 1; i >= 0; i--) {
999                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1000                    return false;
1001                }
1002            }
1003            return true;
1004        }
1005
1006        @Override
1007        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1008            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1009                    || userId == filter.owningUserId) {
1010                return super.newResult(filter, match, userId);
1011            }
1012            return null;
1013        }
1014
1015        @Override
1016        protected BroadcastFilter[] newArray(int size) {
1017            return new BroadcastFilter[size];
1018        }
1019
1020        @Override
1021        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1022            return packageName.equals(filter.packageName);
1023        }
1024    };
1025
1026    /**
1027     * State of all active sticky broadcasts per user.  Keys are the action of the
1028     * sticky Intent, values are an ArrayList of all broadcasted intents with
1029     * that action (which should usually be one).  The SparseArray is keyed
1030     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1031     * for stickies that are sent to all users.
1032     */
1033    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1034            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1035
1036    final ActiveServices mServices;
1037
1038    final static class Association {
1039        final int mSourceUid;
1040        final String mSourceProcess;
1041        final int mTargetUid;
1042        final ComponentName mTargetComponent;
1043        final String mTargetProcess;
1044
1045        int mCount;
1046        long mTime;
1047
1048        int mNesting;
1049        long mStartTime;
1050
1051        // states of the source process when the bind occurred.
1052        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1053        long mLastStateUptime;
1054        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1055                - ActivityManager.MIN_PROCESS_STATE+1];
1056
1057        Association(int sourceUid, String sourceProcess, int targetUid,
1058                ComponentName targetComponent, String targetProcess) {
1059            mSourceUid = sourceUid;
1060            mSourceProcess = sourceProcess;
1061            mTargetUid = targetUid;
1062            mTargetComponent = targetComponent;
1063            mTargetProcess = targetProcess;
1064        }
1065    }
1066
1067    /**
1068     * When service association tracking is enabled, this is all of the associations we
1069     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1070     * -> association data.
1071     */
1072    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1073            mAssociations = new SparseArray<>();
1074    boolean mTrackingAssociations;
1075
1076    /**
1077     * Backup/restore process management
1078     */
1079    String mBackupAppName = null;
1080    BackupRecord mBackupTarget = null;
1081
1082    final ProviderMap mProviderMap;
1083
1084    /**
1085     * List of content providers who have clients waiting for them.  The
1086     * application is currently being launched and the provider will be
1087     * removed from this list once it is published.
1088     */
1089    final ArrayList<ContentProviderRecord> mLaunchingProviders
1090            = new ArrayList<ContentProviderRecord>();
1091
1092    /**
1093     * File storing persisted {@link #mGrantedUriPermissions}.
1094     */
1095    private final AtomicFile mGrantFile;
1096
1097    /** XML constants used in {@link #mGrantFile} */
1098    private static final String TAG_URI_GRANTS = "uri-grants";
1099    private static final String TAG_URI_GRANT = "uri-grant";
1100    private static final String ATTR_USER_HANDLE = "userHandle";
1101    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1102    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1103    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1104    private static final String ATTR_TARGET_PKG = "targetPkg";
1105    private static final String ATTR_URI = "uri";
1106    private static final String ATTR_MODE_FLAGS = "modeFlags";
1107    private static final String ATTR_CREATED_TIME = "createdTime";
1108    private static final String ATTR_PREFIX = "prefix";
1109
1110    /**
1111     * Global set of specific {@link Uri} permissions that have been granted.
1112     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1113     * to {@link UriPermission#uri} to {@link UriPermission}.
1114     */
1115    @GuardedBy("this")
1116    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1117            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1118
1119    public static class GrantUri {
1120        public final int sourceUserId;
1121        public final Uri uri;
1122        public boolean prefix;
1123
1124        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1125            this.sourceUserId = sourceUserId;
1126            this.uri = uri;
1127            this.prefix = prefix;
1128        }
1129
1130        @Override
1131        public int hashCode() {
1132            int hashCode = 1;
1133            hashCode = 31 * hashCode + sourceUserId;
1134            hashCode = 31 * hashCode + uri.hashCode();
1135            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1136            return hashCode;
1137        }
1138
1139        @Override
1140        public boolean equals(Object o) {
1141            if (o instanceof GrantUri) {
1142                GrantUri other = (GrantUri) o;
1143                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1144                        && prefix == other.prefix;
1145            }
1146            return false;
1147        }
1148
1149        @Override
1150        public String toString() {
1151            String result = uri.toString() + " [user " + sourceUserId + "]";
1152            if (prefix) result += " [prefix]";
1153            return result;
1154        }
1155
1156        public String toSafeString() {
1157            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1158            if (prefix) result += " [prefix]";
1159            return result;
1160        }
1161
1162        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1163            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1164                    ContentProvider.getUriWithoutUserId(uri), false);
1165        }
1166    }
1167
1168    CoreSettingsObserver mCoreSettingsObserver;
1169
1170    FontScaleSettingObserver mFontScaleSettingObserver;
1171
1172    private final class FontScaleSettingObserver extends ContentObserver {
1173        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1174
1175        public FontScaleSettingObserver() {
1176            super(mHandler);
1177            ContentResolver resolver = mContext.getContentResolver();
1178            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1179        }
1180
1181        @Override
1182        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1183            if (mFontScaleUri.equals(uri)) {
1184                updateFontScaleIfNeeded(userId);
1185            }
1186        }
1187    }
1188
1189    /**
1190     * Thread-local storage used to carry caller permissions over through
1191     * indirect content-provider access.
1192     */
1193    private class Identity {
1194        public final IBinder token;
1195        public final int pid;
1196        public final int uid;
1197
1198        Identity(IBinder _token, int _pid, int _uid) {
1199            token = _token;
1200            pid = _pid;
1201            uid = _uid;
1202        }
1203    }
1204
1205    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1206
1207    /**
1208     * All information we have collected about the runtime performance of
1209     * any user id that can impact battery performance.
1210     */
1211    final BatteryStatsService mBatteryStatsService;
1212
1213    /**
1214     * Information about component usage
1215     */
1216    UsageStatsManagerInternal mUsageStatsService;
1217
1218    /**
1219     * Access to DeviceIdleController service.
1220     */
1221    DeviceIdleController.LocalService mLocalDeviceIdleController;
1222
1223    /**
1224     * Set of app ids that are whitelisted for device idle and thus background check.
1225     */
1226    int[] mDeviceIdleWhitelist = new int[0];
1227
1228    /**
1229     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1230     */
1231    int[] mDeviceIdleTempWhitelist = new int[0];
1232
1233    static final class PendingTempWhitelist {
1234        final int targetUid;
1235        final long duration;
1236        final String tag;
1237
1238        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1239            targetUid = _targetUid;
1240            duration = _duration;
1241            tag = _tag;
1242        }
1243    }
1244
1245    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1246
1247    /**
1248     * Information about and control over application operations
1249     */
1250    final AppOpsService mAppOpsService;
1251
1252    /** Current sequencing integer of the configuration, for skipping old configurations. */
1253    private int mConfigurationSeq;
1254
1255    /**
1256     * Temp object used when global and/or display override configuration is updated. It is also
1257     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1258     * anyone...
1259     */
1260    private Configuration mTempConfig = new Configuration();
1261
1262    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1263            new UpdateConfigurationResult();
1264    private static final class UpdateConfigurationResult {
1265        // Configuration changes that were updated.
1266        int changes;
1267        // If the activity was relaunched to match the new configuration.
1268        boolean activityRelaunched;
1269
1270        void reset() {
1271            changes = 0;
1272            activityRelaunched = false;
1273        }
1274    }
1275
1276    boolean mSuppressResizeConfigChanges;
1277
1278    /**
1279     * Hardware-reported OpenGLES version.
1280     */
1281    final int GL_ES_VERSION;
1282
1283    /**
1284     * List of initialization arguments to pass to all processes when binding applications to them.
1285     * For example, references to the commonly used services.
1286     */
1287    HashMap<String, IBinder> mAppBindArgs;
1288    HashMap<String, IBinder> mIsolatedAppBindArgs;
1289
1290    /**
1291     * Temporary to avoid allocations.  Protected by main lock.
1292     */
1293    final StringBuilder mStringBuilder = new StringBuilder(256);
1294
1295    /**
1296     * Used to control how we initialize the service.
1297     */
1298    ComponentName mTopComponent;
1299    String mTopAction = Intent.ACTION_MAIN;
1300    String mTopData;
1301
1302    volatile boolean mProcessesReady = false;
1303    volatile boolean mSystemReady = false;
1304    volatile boolean mOnBattery = false;
1305    volatile int mFactoryTest;
1306
1307    @GuardedBy("this") boolean mBooting = false;
1308    @GuardedBy("this") boolean mCallFinishBooting = false;
1309    @GuardedBy("this") boolean mBootAnimationComplete = false;
1310    @GuardedBy("this") boolean mLaunchWarningShown = false;
1311    @GuardedBy("this") boolean mCheckedForSetup = false;
1312
1313    final Context mContext;
1314
1315    /**
1316     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1317     * change at runtime. Use mContext for non-UI purposes.
1318     */
1319    final Context mUiContext;
1320
1321    /**
1322     * The time at which we will allow normal application switches again,
1323     * after a call to {@link #stopAppSwitches()}.
1324     */
1325    long mAppSwitchesAllowedTime;
1326
1327    /**
1328     * This is set to true after the first switch after mAppSwitchesAllowedTime
1329     * is set; any switches after that will clear the time.
1330     */
1331    boolean mDidAppSwitch;
1332
1333    /**
1334     * Last time (in realtime) at which we checked for power usage.
1335     */
1336    long mLastPowerCheckRealtime;
1337
1338    /**
1339     * Last time (in uptime) at which we checked for power usage.
1340     */
1341    long mLastPowerCheckUptime;
1342
1343    /**
1344     * Set while we are wanting to sleep, to prevent any
1345     * activities from being started/resumed.
1346     *
1347     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1348     *
1349     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1350     * while in the sleep state until there is a pending transition out of sleep, in which case
1351     * mSleeping is set to false, and remains false while awake.
1352     *
1353     * Whether mSleeping can quickly toggled between true/false without the device actually
1354     * display changing states is undefined.
1355     */
1356    private boolean mSleeping = false;
1357
1358    /**
1359     * The process state used for processes that are running the top activities.
1360     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1361     */
1362    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1363
1364    /**
1365     * Set while we are running a voice interaction.  This overrides
1366     * sleeping while it is active.
1367     */
1368    private IVoiceInteractionSession mRunningVoice;
1369
1370    /**
1371     * For some direct access we need to power manager.
1372     */
1373    PowerManagerInternal mLocalPowerManager;
1374
1375    /**
1376     * We want to hold a wake lock while running a voice interaction session, since
1377     * this may happen with the screen off and we need to keep the CPU running to
1378     * be able to continue to interact with the user.
1379     */
1380    PowerManager.WakeLock mVoiceWakeLock;
1381
1382    /**
1383     * State of external calls telling us if the device is awake or asleep.
1384     */
1385    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1386
1387    /**
1388     * A list of tokens that cause the top activity to be put to sleep.
1389     * They are used by components that may hide and block interaction with underlying
1390     * activities.
1391     */
1392    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1393
1394    /**
1395     * Set if we are shutting down the system, similar to sleeping.
1396     */
1397    boolean mShuttingDown = false;
1398
1399    /**
1400     * Current sequence id for oom_adj computation traversal.
1401     */
1402    int mAdjSeq = 0;
1403
1404    /**
1405     * Current sequence id for process LRU updating.
1406     */
1407    int mLruSeq = 0;
1408
1409    /**
1410     * Keep track of the non-cached/empty process we last found, to help
1411     * determine how to distribute cached/empty processes next time.
1412     */
1413    int mNumNonCachedProcs = 0;
1414
1415    /**
1416     * Keep track of the number of cached hidden procs, to balance oom adj
1417     * distribution between those and empty procs.
1418     */
1419    int mNumCachedHiddenProcs = 0;
1420
1421    /**
1422     * Keep track of the number of service processes we last found, to
1423     * determine on the next iteration which should be B services.
1424     */
1425    int mNumServiceProcs = 0;
1426    int mNewNumAServiceProcs = 0;
1427    int mNewNumServiceProcs = 0;
1428
1429    /**
1430     * Allow the current computed overall memory level of the system to go down?
1431     * This is set to false when we are killing processes for reasons other than
1432     * memory management, so that the now smaller process list will not be taken as
1433     * an indication that memory is tighter.
1434     */
1435    boolean mAllowLowerMemLevel = false;
1436
1437    /**
1438     * The last computed memory level, for holding when we are in a state that
1439     * processes are going away for other reasons.
1440     */
1441    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1442
1443    /**
1444     * The last total number of process we have, to determine if changes actually look
1445     * like a shrinking number of process due to lower RAM.
1446     */
1447    int mLastNumProcesses;
1448
1449    /**
1450     * The uptime of the last time we performed idle maintenance.
1451     */
1452    long mLastIdleTime = SystemClock.uptimeMillis();
1453
1454    /**
1455     * Total time spent with RAM that has been added in the past since the last idle time.
1456     */
1457    long mLowRamTimeSinceLastIdle = 0;
1458
1459    /**
1460     * If RAM is currently low, when that horrible situation started.
1461     */
1462    long mLowRamStartTime = 0;
1463
1464    /**
1465     * For reporting to battery stats the current top application.
1466     */
1467    private String mCurResumedPackage = null;
1468    private int mCurResumedUid = -1;
1469
1470    /**
1471     * For reporting to battery stats the apps currently running foreground
1472     * service.  The ProcessMap is package/uid tuples; each of these contain
1473     * an array of the currently foreground processes.
1474     */
1475    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1476            = new ProcessMap<ArrayList<ProcessRecord>>();
1477
1478    /**
1479     * This is set if we had to do a delayed dexopt of an app before launching
1480     * it, to increase the ANR timeouts in that case.
1481     */
1482    boolean mDidDexOpt;
1483
1484    /**
1485     * Set if the systemServer made a call to enterSafeMode.
1486     */
1487    boolean mSafeMode;
1488
1489    /**
1490     * If true, we are running under a test environment so will sample PSS from processes
1491     * much more rapidly to try to collect better data when the tests are rapidly
1492     * running through apps.
1493     */
1494    boolean mTestPssMode = false;
1495
1496    String mDebugApp = null;
1497    boolean mWaitForDebugger = false;
1498    boolean mDebugTransient = false;
1499    String mOrigDebugApp = null;
1500    boolean mOrigWaitForDebugger = false;
1501    boolean mAlwaysFinishActivities = false;
1502    boolean mForceResizableActivities;
1503    boolean mSupportsMultiWindow;
1504    boolean mSupportsSplitScreenMultiWindow;
1505    boolean mSupportsFreeformWindowManagement;
1506    boolean mSupportsPictureInPicture;
1507    boolean mSupportsMultiDisplay;
1508    boolean mSupportsLeanbackOnly;
1509    IActivityController mController = null;
1510    boolean mControllerIsAMonkey = false;
1511    String mProfileApp = null;
1512    ProcessRecord mProfileProc = null;
1513    String mProfileFile;
1514    ParcelFileDescriptor mProfileFd;
1515    int mSamplingInterval = 0;
1516    boolean mAutoStopProfiler = false;
1517    boolean mStreamingOutput = false;
1518    int mProfileType = 0;
1519    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1520    String mMemWatchDumpProcName;
1521    String mMemWatchDumpFile;
1522    int mMemWatchDumpPid;
1523    int mMemWatchDumpUid;
1524    String mTrackAllocationApp = null;
1525    String mNativeDebuggingApp = null;
1526
1527    final long[] mTmpLong = new long[2];
1528
1529    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1530
1531    /**
1532     * A global counter for generating sequence numbers.
1533     * This value will be used when incrementing sequence numbers in individual uidRecords.
1534     *
1535     * Having a global counter ensures that seq numbers are monotonically increasing for a
1536     * particular uid even when the uidRecord is re-created.
1537     */
1538    @GuardedBy("this")
1539    @VisibleForTesting
1540    long mProcStateSeqCounter = 0;
1541
1542    private final Injector mInjector;
1543
1544    static final class ProcessChangeItem {
1545        static final int CHANGE_ACTIVITIES = 1<<0;
1546        int changes;
1547        int uid;
1548        int pid;
1549        int processState;
1550        boolean foregroundActivities;
1551    }
1552
1553    static final class UidObserverRegistration {
1554        final int uid;
1555        final String pkg;
1556        final int which;
1557        final int cutpoint;
1558
1559        final SparseIntArray lastProcStates;
1560
1561        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1562            uid = _uid;
1563            pkg = _pkg;
1564            which = _which;
1565            cutpoint = _cutpoint;
1566            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1567                lastProcStates = new SparseIntArray();
1568            } else {
1569                lastProcStates = null;
1570            }
1571        }
1572    }
1573
1574    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1575    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1576
1577    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1578    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1579
1580    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1581    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1582
1583    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1584    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1585
1586    /**
1587     * Runtime CPU use collection thread.  This object's lock is used to
1588     * perform synchronization with the thread (notifying it to run).
1589     */
1590    final Thread mProcessCpuThread;
1591
1592    /**
1593     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1594     * Must acquire this object's lock when accessing it.
1595     * NOTE: this lock will be held while doing long operations (trawling
1596     * through all processes in /proc), so it should never be acquired by
1597     * any critical paths such as when holding the main activity manager lock.
1598     */
1599    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1600            MONITOR_THREAD_CPU_USAGE);
1601    final AtomicLong mLastCpuTime = new AtomicLong(0);
1602    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1603    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1604
1605    long mLastWriteTime = 0;
1606
1607    /**
1608     * Used to retain an update lock when the foreground activity is in
1609     * immersive mode.
1610     */
1611    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1612
1613    /**
1614     * Set to true after the system has finished booting.
1615     */
1616    boolean mBooted = false;
1617
1618    WindowManagerService mWindowManager;
1619    final ActivityThread mSystemThread;
1620
1621    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1622        final ProcessRecord mApp;
1623        final int mPid;
1624        final IApplicationThread mAppThread;
1625
1626        AppDeathRecipient(ProcessRecord app, int pid,
1627                IApplicationThread thread) {
1628            if (DEBUG_ALL) Slog.v(
1629                TAG, "New death recipient " + this
1630                + " for thread " + thread.asBinder());
1631            mApp = app;
1632            mPid = pid;
1633            mAppThread = thread;
1634        }
1635
1636        @Override
1637        public void binderDied() {
1638            if (DEBUG_ALL) Slog.v(
1639                TAG, "Death received in " + this
1640                + " for thread " + mAppThread.asBinder());
1641            synchronized(ActivityManagerService.this) {
1642                appDiedLocked(mApp, mPid, mAppThread, true);
1643            }
1644        }
1645    }
1646
1647    static final int SHOW_ERROR_UI_MSG = 1;
1648    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1649    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1650    static final int UPDATE_CONFIGURATION_MSG = 4;
1651    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1652    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1653    static final int SERVICE_TIMEOUT_MSG = 12;
1654    static final int UPDATE_TIME_ZONE = 13;
1655    static final int SHOW_UID_ERROR_UI_MSG = 14;
1656    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1657    static final int PROC_START_TIMEOUT_MSG = 20;
1658    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1659    static final int KILL_APPLICATION_MSG = 22;
1660    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1661    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1662    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1663    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1664    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1665    static final int CLEAR_DNS_CACHE_MSG = 28;
1666    static final int UPDATE_HTTP_PROXY_MSG = 29;
1667    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1668    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1669    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1670    static final int REPORT_MEM_USAGE_MSG = 33;
1671    static final int REPORT_USER_SWITCH_MSG = 34;
1672    static final int CONTINUE_USER_SWITCH_MSG = 35;
1673    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1674    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1675    static final int PERSIST_URI_GRANTS_MSG = 38;
1676    static final int REQUEST_ALL_PSS_MSG = 39;
1677    static final int START_PROFILES_MSG = 40;
1678    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1679    static final int SYSTEM_USER_START_MSG = 42;
1680    static final int SYSTEM_USER_CURRENT_MSG = 43;
1681    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1682    static final int FINISH_BOOTING_MSG = 45;
1683    static final int START_USER_SWITCH_UI_MSG = 46;
1684    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1685    static final int DISMISS_DIALOG_UI_MSG = 48;
1686    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1687    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1688    static final int DELETE_DUMPHEAP_MSG = 51;
1689    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1690    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1691    static final int REPORT_TIME_TRACKER_MSG = 54;
1692    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1693    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1694    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1695    static final int IDLE_UIDS_MSG = 58;
1696    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1697    static final int LOG_STACK_STATE = 60;
1698    static final int VR_MODE_CHANGE_MSG = 61;
1699    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1700    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1701    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1702    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1703    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1704    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1705    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1706    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1707    static final int START_USER_SWITCH_FG_MSG = 712;
1708
1709    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1710    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1711    static final int FIRST_COMPAT_MODE_MSG = 300;
1712    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1713
1714    static ServiceThread sKillThread = null;
1715    static KillHandler sKillHandler = null;
1716
1717    CompatModeDialog mCompatModeDialog;
1718    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1719    long mLastMemUsageReportTime = 0;
1720
1721    /**
1722     * Flag whether the current user is a "monkey", i.e. whether
1723     * the UI is driven by a UI automation tool.
1724     */
1725    private boolean mUserIsMonkey;
1726
1727    /** Flag whether the device has a Recents UI */
1728    boolean mHasRecents;
1729
1730    /** The dimensions of the thumbnails in the Recents UI. */
1731    int mThumbnailWidth;
1732    int mThumbnailHeight;
1733    float mFullscreenThumbnailScale;
1734
1735    final ServiceThread mHandlerThread;
1736    final MainHandler mHandler;
1737    final Handler mUiHandler;
1738
1739    final ActivityManagerConstants mConstants;
1740
1741    PackageManagerInternal mPackageManagerInt;
1742
1743    // VoiceInteraction session ID that changes for each new request except when
1744    // being called for multiwindow assist in a single session.
1745    private int mViSessionId = 1000;
1746
1747    final boolean mPermissionReviewRequired;
1748
1749    /**
1750     * Current global configuration information. Contains general settings for the entire system,
1751     * also corresponds to the merged configuration of the default display.
1752     */
1753    Configuration getGlobalConfiguration() {
1754        return mStackSupervisor.getConfiguration();
1755    }
1756
1757    final class KillHandler extends Handler {
1758        static final int KILL_PROCESS_GROUP_MSG = 4000;
1759
1760        public KillHandler(Looper looper) {
1761            super(looper, null, true);
1762        }
1763
1764        @Override
1765        public void handleMessage(Message msg) {
1766            switch (msg.what) {
1767                case KILL_PROCESS_GROUP_MSG:
1768                {
1769                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1770                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1771                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1772                }
1773                break;
1774
1775                default:
1776                    super.handleMessage(msg);
1777            }
1778        }
1779    }
1780
1781    final class UiHandler extends Handler {
1782        public UiHandler() {
1783            super(com.android.server.UiThread.get().getLooper(), null, true);
1784        }
1785
1786        @Override
1787        public void handleMessage(Message msg) {
1788            switch (msg.what) {
1789            case SHOW_ERROR_UI_MSG: {
1790                mAppErrors.handleShowAppErrorUi(msg);
1791                ensureBootCompleted();
1792            } break;
1793            case SHOW_NOT_RESPONDING_UI_MSG: {
1794                mAppErrors.handleShowAnrUi(msg);
1795                ensureBootCompleted();
1796            } break;
1797            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1798                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1799                synchronized (ActivityManagerService.this) {
1800                    ProcessRecord proc = (ProcessRecord) data.get("app");
1801                    if (proc == null) {
1802                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1803                        break;
1804                    }
1805                    if (proc.crashDialog != null) {
1806                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1807                        return;
1808                    }
1809                    AppErrorResult res = (AppErrorResult) data.get("result");
1810                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1811                        Dialog d = new StrictModeViolationDialog(mContext,
1812                                ActivityManagerService.this, res, proc);
1813                        d.show();
1814                        proc.crashDialog = d;
1815                    } else {
1816                        // The device is asleep, so just pretend that the user
1817                        // saw a crash dialog and hit "force quit".
1818                        res.set(0);
1819                    }
1820                }
1821                ensureBootCompleted();
1822            } break;
1823            case SHOW_FACTORY_ERROR_UI_MSG: {
1824                Dialog d = new FactoryErrorDialog(
1825                        mUiContext, msg.getData().getCharSequence("msg"));
1826                d.show();
1827                ensureBootCompleted();
1828            } break;
1829            case WAIT_FOR_DEBUGGER_UI_MSG: {
1830                synchronized (ActivityManagerService.this) {
1831                    ProcessRecord app = (ProcessRecord)msg.obj;
1832                    if (msg.arg1 != 0) {
1833                        if (!app.waitedForDebugger) {
1834                            Dialog d = new AppWaitingForDebuggerDialog(
1835                                    ActivityManagerService.this,
1836                                    mUiContext, app);
1837                            app.waitDialog = d;
1838                            app.waitedForDebugger = true;
1839                            d.show();
1840                        }
1841                    } else {
1842                        if (app.waitDialog != null) {
1843                            app.waitDialog.dismiss();
1844                            app.waitDialog = null;
1845                        }
1846                    }
1847                }
1848            } break;
1849            case SHOW_UID_ERROR_UI_MSG: {
1850                if (mShowDialogs) {
1851                    AlertDialog d = new BaseErrorDialog(mUiContext);
1852                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1853                    d.setCancelable(false);
1854                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1855                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1856                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1857                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1858                    d.show();
1859                }
1860            } break;
1861            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1862                if (mShowDialogs) {
1863                    AlertDialog d = new BaseErrorDialog(mUiContext);
1864                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1865                    d.setCancelable(false);
1866                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1867                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1868                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1869                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1870                    d.show();
1871                }
1872            } break;
1873            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1874                synchronized (ActivityManagerService.this) {
1875                    ActivityRecord ar = (ActivityRecord) msg.obj;
1876                    if (mCompatModeDialog != null) {
1877                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1878                                ar.info.applicationInfo.packageName)) {
1879                            return;
1880                        }
1881                        mCompatModeDialog.dismiss();
1882                        mCompatModeDialog = null;
1883                    }
1884                    if (ar != null && false) {
1885                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1886                                ar.packageName)) {
1887                            int mode = mCompatModePackages.computeCompatModeLocked(
1888                                    ar.info.applicationInfo);
1889                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1890                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1891                                mCompatModeDialog = new CompatModeDialog(
1892                                        ActivityManagerService.this, mUiContext,
1893                                        ar.info.applicationInfo);
1894                                mCompatModeDialog.show();
1895                            }
1896                        }
1897                    }
1898                }
1899                break;
1900            }
1901            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1902                synchronized (ActivityManagerService.this) {
1903                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1904                    if (mUnsupportedDisplaySizeDialog != null) {
1905                        mUnsupportedDisplaySizeDialog.dismiss();
1906                        mUnsupportedDisplaySizeDialog = null;
1907                    }
1908                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1909                            ar.packageName)) {
1910                        // TODO(multi-display): Show dialog on appropriate display.
1911                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1912                                ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1913                        mUnsupportedDisplaySizeDialog.show();
1914                    }
1915                }
1916                break;
1917            }
1918            case START_USER_SWITCH_UI_MSG: {
1919                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1920                break;
1921            }
1922            case DISMISS_DIALOG_UI_MSG: {
1923                final Dialog d = (Dialog) msg.obj;
1924                d.dismiss();
1925                break;
1926            }
1927            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1928                dispatchProcessesChanged();
1929                break;
1930            }
1931            case DISPATCH_PROCESS_DIED_UI_MSG: {
1932                final int pid = msg.arg1;
1933                final int uid = msg.arg2;
1934                dispatchProcessDied(pid, uid);
1935                break;
1936            }
1937            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1938                dispatchUidsChanged();
1939            } break;
1940            case PUSH_TEMP_WHITELIST_UI_MSG: {
1941                pushTempWhitelist();
1942            } break;
1943            }
1944        }
1945    }
1946
1947    final class MainHandler extends Handler {
1948        public MainHandler(Looper looper) {
1949            super(looper, null, true);
1950        }
1951
1952        @Override
1953        public void handleMessage(Message msg) {
1954            switch (msg.what) {
1955            case UPDATE_CONFIGURATION_MSG: {
1956                final ContentResolver resolver = mContext.getContentResolver();
1957                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1958                        msg.arg1);
1959            } break;
1960            case GC_BACKGROUND_PROCESSES_MSG: {
1961                synchronized (ActivityManagerService.this) {
1962                    performAppGcsIfAppropriateLocked();
1963                }
1964            } break;
1965            case SERVICE_TIMEOUT_MSG: {
1966                if (mDidDexOpt) {
1967                    mDidDexOpt = false;
1968                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1969                    nmsg.obj = msg.obj;
1970                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1971                    return;
1972                }
1973                mServices.serviceTimeout((ProcessRecord)msg.obj);
1974            } break;
1975            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1976                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1977            } break;
1978            case SERVICE_FOREGROUND_CRASH_MSG: {
1979                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1980            } break;
1981            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1982                RemoteCallbackList<IResultReceiver> callbacks
1983                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
1984                int N = callbacks.beginBroadcast();
1985                for (int i = 0; i < N; i++) {
1986                    try {
1987                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1988                    } catch (RemoteException e) {
1989                    }
1990                }
1991                callbacks.finishBroadcast();
1992            } break;
1993            case UPDATE_TIME_ZONE: {
1994                synchronized (ActivityManagerService.this) {
1995                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1996                        ProcessRecord r = mLruProcesses.get(i);
1997                        if (r.thread != null) {
1998                            try {
1999                                r.thread.updateTimeZone();
2000                            } catch (RemoteException ex) {
2001                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2002                            }
2003                        }
2004                    }
2005                }
2006            } break;
2007            case CLEAR_DNS_CACHE_MSG: {
2008                synchronized (ActivityManagerService.this) {
2009                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2010                        ProcessRecord r = mLruProcesses.get(i);
2011                        if (r.thread != null) {
2012                            try {
2013                                r.thread.clearDnsCache();
2014                            } catch (RemoteException ex) {
2015                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2016                            }
2017                        }
2018                    }
2019                }
2020            } break;
2021            case UPDATE_HTTP_PROXY_MSG: {
2022                ProxyInfo proxy = (ProxyInfo)msg.obj;
2023                String host = "";
2024                String port = "";
2025                String exclList = "";
2026                Uri pacFileUrl = Uri.EMPTY;
2027                if (proxy != null) {
2028                    host = proxy.getHost();
2029                    port = Integer.toString(proxy.getPort());
2030                    exclList = proxy.getExclusionListAsString();
2031                    pacFileUrl = proxy.getPacFileUrl();
2032                }
2033                synchronized (ActivityManagerService.this) {
2034                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2035                        ProcessRecord r = mLruProcesses.get(i);
2036                        if (r.thread != null) {
2037                            try {
2038                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2039                            } catch (RemoteException ex) {
2040                                Slog.w(TAG, "Failed to update http proxy for: " +
2041                                        r.info.processName);
2042                            }
2043                        }
2044                    }
2045                }
2046            } break;
2047            case PROC_START_TIMEOUT_MSG: {
2048                if (mDidDexOpt) {
2049                    mDidDexOpt = false;
2050                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2051                    nmsg.obj = msg.obj;
2052                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
2053                    return;
2054                }
2055                ProcessRecord app = (ProcessRecord)msg.obj;
2056                synchronized (ActivityManagerService.this) {
2057                    processStartTimedOutLocked(app);
2058                }
2059            } break;
2060            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2061                ProcessRecord app = (ProcessRecord)msg.obj;
2062                synchronized (ActivityManagerService.this) {
2063                    processContentProviderPublishTimedOutLocked(app);
2064                }
2065            } break;
2066            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2067                synchronized (ActivityManagerService.this) {
2068                    mActivityStarter.doPendingActivityLaunchesLocked(true);
2069                }
2070            } break;
2071            case KILL_APPLICATION_MSG: {
2072                synchronized (ActivityManagerService.this) {
2073                    final int appId = msg.arg1;
2074                    final int userId = msg.arg2;
2075                    Bundle bundle = (Bundle)msg.obj;
2076                    String pkg = bundle.getString("pkg");
2077                    String reason = bundle.getString("reason");
2078                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2079                            false, userId, reason);
2080                }
2081            } break;
2082            case FINALIZE_PENDING_INTENT_MSG: {
2083                ((PendingIntentRecord)msg.obj).completeFinalize();
2084            } break;
2085            case POST_HEAVY_NOTIFICATION_MSG: {
2086                INotificationManager inm = NotificationManager.getService();
2087                if (inm == null) {
2088                    return;
2089                }
2090
2091                ActivityRecord root = (ActivityRecord)msg.obj;
2092                ProcessRecord process = root.app;
2093                if (process == null) {
2094                    return;
2095                }
2096
2097                try {
2098                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2099                    String text = mContext.getString(R.string.heavy_weight_notification,
2100                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2101                    Notification notification =
2102                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2103                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2104                            .setWhen(0)
2105                            .setOngoing(true)
2106                            .setTicker(text)
2107                            .setColor(mContext.getColor(
2108                                    com.android.internal.R.color.system_notification_accent_color))
2109                            .setContentTitle(text)
2110                            .setContentText(
2111                                    mContext.getText(R.string.heavy_weight_notification_detail))
2112                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2113                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2114                                    new UserHandle(root.userId)))
2115                            .build();
2116                    try {
2117                        int[] outId = new int[1];
2118                        inm.enqueueNotificationWithTag("android", "android", null,
2119                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2120                                notification, outId, root.userId);
2121                    } catch (RuntimeException e) {
2122                        Slog.w(ActivityManagerService.TAG,
2123                                "Error showing notification for heavy-weight app", e);
2124                    } catch (RemoteException e) {
2125                    }
2126                } catch (NameNotFoundException e) {
2127                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2128                }
2129            } break;
2130            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2131                INotificationManager inm = NotificationManager.getService();
2132                if (inm == null) {
2133                    return;
2134                }
2135                try {
2136                    inm.cancelNotificationWithTag("android", null,
2137                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2138                } catch (RuntimeException e) {
2139                    Slog.w(ActivityManagerService.TAG,
2140                            "Error canceling notification for service", e);
2141                } catch (RemoteException e) {
2142                }
2143            } break;
2144            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2145                synchronized (ActivityManagerService.this) {
2146                    checkExcessivePowerUsageLocked(true);
2147                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2148                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2149                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
2150                }
2151            } break;
2152            case REPORT_MEM_USAGE_MSG: {
2153                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2154                Thread thread = new Thread() {
2155                    @Override public void run() {
2156                        reportMemUsage(memInfos);
2157                    }
2158                };
2159                thread.start();
2160                break;
2161            }
2162            case START_USER_SWITCH_FG_MSG: {
2163                mUserController.startUserInForeground(msg.arg1);
2164                break;
2165            }
2166            case REPORT_USER_SWITCH_MSG: {
2167                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2168                break;
2169            }
2170            case CONTINUE_USER_SWITCH_MSG: {
2171                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2172                break;
2173            }
2174            case USER_SWITCH_TIMEOUT_MSG: {
2175                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2176                break;
2177            }
2178            case IMMERSIVE_MODE_LOCK_MSG: {
2179                final boolean nextState = (msg.arg1 != 0);
2180                if (mUpdateLock.isHeld() != nextState) {
2181                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2182                            "Applying new update lock state '" + nextState
2183                            + "' for " + (ActivityRecord)msg.obj);
2184                    if (nextState) {
2185                        mUpdateLock.acquire();
2186                    } else {
2187                        mUpdateLock.release();
2188                    }
2189                }
2190                break;
2191            }
2192            case PERSIST_URI_GRANTS_MSG: {
2193                writeGrantedUriPermissions();
2194                break;
2195            }
2196            case REQUEST_ALL_PSS_MSG: {
2197                synchronized (ActivityManagerService.this) {
2198                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2199                }
2200                break;
2201            }
2202            case START_PROFILES_MSG: {
2203                synchronized (ActivityManagerService.this) {
2204                    mUserController.startProfilesLocked();
2205                }
2206                break;
2207            }
2208            case UPDATE_TIME_PREFERENCE_MSG: {
2209                // The user's time format preference might have changed.
2210                // For convenience we re-use the Intent extra values.
2211                synchronized (ActivityManagerService.this) {
2212                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2213                        ProcessRecord r = mLruProcesses.get(i);
2214                        if (r.thread != null) {
2215                            try {
2216                                r.thread.updateTimePrefs(msg.arg1);
2217                            } catch (RemoteException ex) {
2218                                Slog.w(TAG, "Failed to update preferences for: "
2219                                        + r.info.processName);
2220                            }
2221                        }
2222                    }
2223                }
2224                break;
2225            }
2226            case SYSTEM_USER_START_MSG: {
2227                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2228                        Integer.toString(msg.arg1), msg.arg1);
2229                mSystemServiceManager.startUser(msg.arg1);
2230                break;
2231            }
2232            case SYSTEM_USER_UNLOCK_MSG: {
2233                final int userId = msg.arg1;
2234                mSystemServiceManager.unlockUser(userId);
2235                synchronized (ActivityManagerService.this) {
2236                    mRecentTasks.loadUserRecentsLocked(userId);
2237                }
2238                if (userId == UserHandle.USER_SYSTEM) {
2239                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2240                }
2241                installEncryptionUnawareProviders(userId);
2242                mUserController.finishUserUnlocked((UserState) msg.obj);
2243                break;
2244            }
2245            case SYSTEM_USER_CURRENT_MSG: {
2246                mBatteryStatsService.noteEvent(
2247                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2248                        Integer.toString(msg.arg2), msg.arg2);
2249                mBatteryStatsService.noteEvent(
2250                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2251                        Integer.toString(msg.arg1), msg.arg1);
2252                mSystemServiceManager.switchUser(msg.arg1);
2253                break;
2254            }
2255            case ENTER_ANIMATION_COMPLETE_MSG: {
2256                synchronized (ActivityManagerService.this) {
2257                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2258                    if (r != null && r.app != null && r.app.thread != null) {
2259                        try {
2260                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2261                        } catch (RemoteException e) {
2262                        }
2263                    }
2264                }
2265                break;
2266            }
2267            case FINISH_BOOTING_MSG: {
2268                if (msg.arg1 != 0) {
2269                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2270                    finishBooting();
2271                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2272                }
2273                if (msg.arg2 != 0) {
2274                    enableScreenAfterBoot();
2275                }
2276                break;
2277            }
2278            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2279                try {
2280                    Locale l = (Locale) msg.obj;
2281                    IBinder service = ServiceManager.getService("mount");
2282                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2283                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2284                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2285                } catch (RemoteException e) {
2286                    Log.e(TAG, "Error storing locale for decryption UI", e);
2287                }
2288                break;
2289            }
2290            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2291                final int uid = msg.arg1;
2292                final byte[] firstPacket = (byte[]) msg.obj;
2293
2294                synchronized (mPidsSelfLocked) {
2295                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2296                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2297                        if (p.uid == uid) {
2298                            try {
2299                                p.thread.notifyCleartextNetwork(firstPacket);
2300                            } catch (RemoteException ignored) {
2301                            }
2302                        }
2303                    }
2304                }
2305                break;
2306            }
2307            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2308                final String procName;
2309                final int uid;
2310                final long memLimit;
2311                final String reportPackage;
2312                synchronized (ActivityManagerService.this) {
2313                    procName = mMemWatchDumpProcName;
2314                    uid = mMemWatchDumpUid;
2315                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2316                    if (val == null) {
2317                        val = mMemWatchProcesses.get(procName, 0);
2318                    }
2319                    if (val != null) {
2320                        memLimit = val.first;
2321                        reportPackage = val.second;
2322                    } else {
2323                        memLimit = 0;
2324                        reportPackage = null;
2325                    }
2326                }
2327                if (procName == null) {
2328                    return;
2329                }
2330
2331                if (DEBUG_PSS) Slog.d(TAG_PSS,
2332                        "Showing dump heap notification from " + procName + "/" + uid);
2333
2334                INotificationManager inm = NotificationManager.getService();
2335                if (inm == null) {
2336                    return;
2337                }
2338
2339                String text = mContext.getString(R.string.dump_heap_notification, procName);
2340
2341
2342                Intent deleteIntent = new Intent();
2343                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2344                Intent intent = new Intent();
2345                intent.setClassName("android", DumpHeapActivity.class.getName());
2346                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2347                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2348                if (reportPackage != null) {
2349                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2350                }
2351                int userId = UserHandle.getUserId(uid);
2352                Notification notification =
2353                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2354                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2355                        .setWhen(0)
2356                        .setOngoing(true)
2357                        .setAutoCancel(true)
2358                        .setTicker(text)
2359                        .setColor(mContext.getColor(
2360                                com.android.internal.R.color.system_notification_accent_color))
2361                        .setContentTitle(text)
2362                        .setContentText(
2363                                mContext.getText(R.string.dump_heap_notification_detail))
2364                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2365                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2366                                new UserHandle(userId)))
2367                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2368                                deleteIntent, 0, UserHandle.SYSTEM))
2369                        .build();
2370
2371                try {
2372                    int[] outId = new int[1];
2373                    inm.enqueueNotificationWithTag("android", "android", null,
2374                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2375                            notification, outId, userId);
2376                } catch (RuntimeException e) {
2377                    Slog.w(ActivityManagerService.TAG,
2378                            "Error showing notification for dump heap", e);
2379                } catch (RemoteException e) {
2380                }
2381            } break;
2382            case DELETE_DUMPHEAP_MSG: {
2383                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2384                        null, DumpHeapActivity.JAVA_URI,
2385                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2386                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2387                        UserHandle.myUserId());
2388                synchronized (ActivityManagerService.this) {
2389                    mMemWatchDumpFile = null;
2390                    mMemWatchDumpProcName = null;
2391                    mMemWatchDumpPid = -1;
2392                    mMemWatchDumpUid = -1;
2393                }
2394            } break;
2395            case FOREGROUND_PROFILE_CHANGED_MSG: {
2396                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2397            } break;
2398            case REPORT_TIME_TRACKER_MSG: {
2399                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2400                tracker.deliverResult(mContext);
2401            } break;
2402            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2403                mUserController.dispatchUserSwitchComplete(msg.arg1);
2404            } break;
2405            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2406                mUserController.dispatchLockedBootComplete(msg.arg1);
2407            } break;
2408            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2409                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2410                try {
2411                    connection.shutdown();
2412                } catch (RemoteException e) {
2413                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2414                }
2415                // Only a UiAutomation can set this flag and now that
2416                // it is finished we make sure it is reset to its default.
2417                mUserIsMonkey = false;
2418            } break;
2419            case IDLE_UIDS_MSG: {
2420                idleUids();
2421            } break;
2422            case VR_MODE_CHANGE_MSG: {
2423                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2424                    return;
2425                }
2426                synchronized (ActivityManagerService.this) {
2427                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2428                    mWindowManager.disableNonVrUi(disableNonVrUi);
2429                    if (disableNonVrUi) {
2430                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2431                        // then remove the pinned stack.
2432                        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2433                                PINNED_STACK_ID);
2434                        if (pinnedStack != null) {
2435                            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2436                        }
2437                    }
2438                }
2439            } break;
2440            case NOTIFY_VR_SLEEPING_MSG: {
2441                notifyVrManagerOfSleepState(msg.arg1 != 0);
2442            } break;
2443            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2444                synchronized (ActivityManagerService.this) {
2445                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2446                        ProcessRecord r = mLruProcesses.get(i);
2447                        if (r.thread != null) {
2448                            try {
2449                                r.thread.handleTrustStorageUpdate();
2450                            } catch (RemoteException ex) {
2451                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2452                                        r.info.processName);
2453                            }
2454                        }
2455                    }
2456                }
2457            } break;
2458            }
2459        }
2460    };
2461
2462    static final int COLLECT_PSS_BG_MSG = 1;
2463
2464    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2465        @Override
2466        public void handleMessage(Message msg) {
2467            switch (msg.what) {
2468            case COLLECT_PSS_BG_MSG: {
2469                long start = SystemClock.uptimeMillis();
2470                MemInfoReader memInfo = null;
2471                synchronized (ActivityManagerService.this) {
2472                    if (mFullPssPending) {
2473                        mFullPssPending = false;
2474                        memInfo = new MemInfoReader();
2475                    }
2476                }
2477                if (memInfo != null) {
2478                    updateCpuStatsNow();
2479                    long nativeTotalPss = 0;
2480                    final List<ProcessCpuTracker.Stats> stats;
2481                    synchronized (mProcessCpuTracker) {
2482                        stats = mProcessCpuTracker.getStats( (st)-> {
2483                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2484                        });
2485                    }
2486                    final int N = stats.size();
2487                    for (int j = 0; j < N; j++) {
2488                        synchronized (mPidsSelfLocked) {
2489                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2490                                // This is one of our own processes; skip it.
2491                                continue;
2492                            }
2493                        }
2494                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2495                    }
2496                    memInfo.readMemInfo();
2497                    synchronized (ActivityManagerService.this) {
2498                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2499                                + (SystemClock.uptimeMillis()-start) + "ms");
2500                        final long cachedKb = memInfo.getCachedSizeKb();
2501                        final long freeKb = memInfo.getFreeSizeKb();
2502                        final long zramKb = memInfo.getZramTotalSizeKb();
2503                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2504                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2505                                kernelKb*1024, nativeTotalPss*1024);
2506                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2507                                nativeTotalPss);
2508                    }
2509                }
2510
2511                int num = 0;
2512                long[] tmp = new long[2];
2513                do {
2514                    ProcessRecord proc;
2515                    int procState;
2516                    int pid;
2517                    long lastPssTime;
2518                    synchronized (ActivityManagerService.this) {
2519                        if (mPendingPssProcesses.size() <= 0) {
2520                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2521                                    "Collected PSS of " + num + " processes in "
2522                                    + (SystemClock.uptimeMillis() - start) + "ms");
2523                            mPendingPssProcesses.clear();
2524                            return;
2525                        }
2526                        proc = mPendingPssProcesses.remove(0);
2527                        procState = proc.pssProcState;
2528                        lastPssTime = proc.lastPssTime;
2529                        if (proc.thread != null && procState == proc.setProcState
2530                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2531                                        < SystemClock.uptimeMillis()) {
2532                            pid = proc.pid;
2533                        } else {
2534                            proc = null;
2535                            pid = 0;
2536                        }
2537                    }
2538                    if (proc != null) {
2539                        long pss = Debug.getPss(pid, tmp, null);
2540                        synchronized (ActivityManagerService.this) {
2541                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2542                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2543                                num++;
2544                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2545                                        SystemClock.uptimeMillis());
2546                            }
2547                        }
2548                    }
2549                } while (true);
2550            }
2551            }
2552        }
2553    };
2554
2555    public void setSystemProcess() {
2556        try {
2557            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2558            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2559            ServiceManager.addService("meminfo", new MemBinder(this));
2560            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2561            ServiceManager.addService("dbinfo", new DbBinder(this));
2562            if (MONITOR_CPU_USAGE) {
2563                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2564            }
2565            ServiceManager.addService("permission", new PermissionController(this));
2566            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2567
2568            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2569                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2570            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2571
2572            synchronized (this) {
2573                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2574                app.persistent = true;
2575                app.pid = MY_PID;
2576                app.maxAdj = ProcessList.SYSTEM_ADJ;
2577                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2578                synchronized (mPidsSelfLocked) {
2579                    mPidsSelfLocked.put(app.pid, app);
2580                }
2581                updateLruProcessLocked(app, false, null);
2582                updateOomAdjLocked();
2583            }
2584        } catch (PackageManager.NameNotFoundException e) {
2585            throw new RuntimeException(
2586                    "Unable to find android system package", e);
2587        }
2588    }
2589
2590    public void setWindowManager(WindowManagerService wm) {
2591        mWindowManager = wm;
2592        mStackSupervisor.setWindowManager(wm);
2593        mActivityStarter.setWindowManager(wm);
2594    }
2595
2596    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2597        mUsageStatsService = usageStatsManager;
2598    }
2599
2600    public void startObservingNativeCrashes() {
2601        final NativeCrashListener ncl = new NativeCrashListener(this);
2602        ncl.start();
2603    }
2604
2605    public IAppOpsService getAppOpsService() {
2606        return mAppOpsService;
2607    }
2608
2609    static class MemBinder extends Binder {
2610        ActivityManagerService mActivityManagerService;
2611        MemBinder(ActivityManagerService activityManagerService) {
2612            mActivityManagerService = activityManagerService;
2613        }
2614
2615        @Override
2616        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2617            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2618                    "meminfo", pw)) return;
2619            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2620        }
2621    }
2622
2623    static class GraphicsBinder extends Binder {
2624        ActivityManagerService mActivityManagerService;
2625        GraphicsBinder(ActivityManagerService activityManagerService) {
2626            mActivityManagerService = activityManagerService;
2627        }
2628
2629        @Override
2630        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2631            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2632                    "gfxinfo", pw)) return;
2633            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2634        }
2635    }
2636
2637    static class DbBinder extends Binder {
2638        ActivityManagerService mActivityManagerService;
2639        DbBinder(ActivityManagerService activityManagerService) {
2640            mActivityManagerService = activityManagerService;
2641        }
2642
2643        @Override
2644        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2645            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2646                    "dbinfo", pw)) return;
2647            mActivityManagerService.dumpDbInfo(fd, pw, args);
2648        }
2649    }
2650
2651    static class CpuBinder extends Binder {
2652        ActivityManagerService mActivityManagerService;
2653        CpuBinder(ActivityManagerService activityManagerService) {
2654            mActivityManagerService = activityManagerService;
2655        }
2656
2657        @Override
2658        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2659            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2660                    "cpuinfo", pw)) return;
2661            synchronized (mActivityManagerService.mProcessCpuTracker) {
2662                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2663                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2664                        SystemClock.uptimeMillis()));
2665            }
2666        }
2667    }
2668
2669    public static final class Lifecycle extends SystemService {
2670        private final ActivityManagerService mService;
2671
2672        public Lifecycle(Context context) {
2673            super(context);
2674            mService = new ActivityManagerService(context);
2675        }
2676
2677        @Override
2678        public void onStart() {
2679            mService.start();
2680        }
2681
2682        public ActivityManagerService getService() {
2683            return mService;
2684        }
2685    }
2686
2687    @VisibleForTesting
2688    public ActivityManagerService(Injector injector) {
2689        mInjector = injector;
2690        mContext = mInjector.getContext();
2691        mUiContext = null;
2692        GL_ES_VERSION = 0;
2693        mActivityStarter = null;
2694        mAppErrors = null;
2695        mAppOpsService = mInjector.getAppOpsService(null, null);
2696        mBatteryStatsService = null;
2697        mCompatModePackages = null;
2698        mConstants = null;
2699        mGrantFile = null;
2700        mHandler = null;
2701        mHandlerThread = null;
2702        mIntentFirewall = null;
2703        mKeyguardController = null;
2704        mPermissionReviewRequired = false;
2705        mProcessCpuThread = null;
2706        mProcessStats = null;
2707        mProviderMap = null;
2708        mRecentTasks = null;
2709        mServices = null;
2710        mStackSupervisor = null;
2711        mSystemThread = null;
2712        mTaskChangeNotificationController = null;
2713        mUiHandler = injector.getUiHandler(null);
2714        mUserController = null;
2715        mVrController = null;
2716    }
2717
2718    // Note: This method is invoked on the main thread but may need to attach various
2719    // handlers to other threads.  So take care to be explicit about the looper.
2720    public ActivityManagerService(Context systemContext) {
2721        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2722        mInjector = new Injector();
2723        mContext = systemContext;
2724
2725        mFactoryTest = FactoryTest.getMode();
2726        mSystemThread = ActivityThread.currentActivityThread();
2727        mUiContext = mSystemThread.getSystemUiContext();
2728
2729        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2730
2731        mPermissionReviewRequired = mContext.getResources().getBoolean(
2732                com.android.internal.R.bool.config_permissionReviewRequired);
2733
2734        mHandlerThread = new ServiceThread(TAG,
2735                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2736        mHandlerThread.start();
2737        mHandler = new MainHandler(mHandlerThread.getLooper());
2738        mUiHandler = mInjector.getUiHandler(this);
2739
2740        mConstants = new ActivityManagerConstants(this, mHandler);
2741
2742        /* static; one-time init here */
2743        if (sKillHandler == null) {
2744            sKillThread = new ServiceThread(TAG + ":kill",
2745                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2746            sKillThread.start();
2747            sKillHandler = new KillHandler(sKillThread.getLooper());
2748        }
2749
2750        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2751                "foreground", BROADCAST_FG_TIMEOUT, false);
2752        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2753                "background", BROADCAST_BG_TIMEOUT, true);
2754        mBroadcastQueues[0] = mFgBroadcastQueue;
2755        mBroadcastQueues[1] = mBgBroadcastQueue;
2756
2757        mServices = new ActiveServices(this);
2758        mProviderMap = new ProviderMap(this);
2759        mAppErrors = new AppErrors(mUiContext, this);
2760
2761        // TODO: Move creation of battery stats service outside of activity manager service.
2762        File dataDir = Environment.getDataDirectory();
2763        File systemDir = new File(dataDir, "system");
2764        systemDir.mkdirs();
2765        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2766        mBatteryStatsService.getActiveStatistics().readLocked();
2767        mBatteryStatsService.scheduleWriteToDisk();
2768        mOnBattery = DEBUG_POWER ? true
2769                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2770        mBatteryStatsService.getActiveStatistics().setCallback(this);
2771
2772        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2773
2774        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2775        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2776                new IAppOpsCallback.Stub() {
2777                    @Override public void opChanged(int op, int uid, String packageName) {
2778                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2779                            if (mAppOpsService.checkOperation(op, uid, packageName)
2780                                    != AppOpsManager.MODE_ALLOWED) {
2781                                runInBackgroundDisabled(uid);
2782                            }
2783                        }
2784                    }
2785                });
2786
2787        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2788
2789        mUserController = new UserController(this);
2790
2791        mVrController = new VrController(this);
2792
2793        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2794            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2795
2796        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2797            mUseFifoUiScheduling = true;
2798        }
2799
2800        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2801        mTempConfig.setToDefaults();
2802        mTempConfig.setLocales(LocaleList.getDefault());
2803        mConfigurationSeq = mTempConfig.seq = 1;
2804        mStackSupervisor = createStackSupervisor();
2805        mStackSupervisor.onConfigurationChanged(mTempConfig);
2806        mKeyguardController = mStackSupervisor.mKeyguardController;
2807        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2808        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2809        mTaskChangeNotificationController =
2810                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2811        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2812        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2813
2814        mProcessCpuThread = new Thread("CpuTracker") {
2815            @Override
2816            public void run() {
2817                synchronized (mProcessCpuTracker) {
2818                    mProcessCpuInitLatch.countDown();
2819                    mProcessCpuTracker.init();
2820                }
2821                while (true) {
2822                    try {
2823                        try {
2824                            synchronized(this) {
2825                                final long now = SystemClock.uptimeMillis();
2826                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2827                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2828                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2829                                //        + ", write delay=" + nextWriteDelay);
2830                                if (nextWriteDelay < nextCpuDelay) {
2831                                    nextCpuDelay = nextWriteDelay;
2832                                }
2833                                if (nextCpuDelay > 0) {
2834                                    mProcessCpuMutexFree.set(true);
2835                                    this.wait(nextCpuDelay);
2836                                }
2837                            }
2838                        } catch (InterruptedException e) {
2839                        }
2840                        updateCpuStatsNow();
2841                    } catch (Exception e) {
2842                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2843                    }
2844                }
2845            }
2846        };
2847
2848        Watchdog.getInstance().addMonitor(this);
2849        Watchdog.getInstance().addThread(mHandler);
2850    }
2851
2852    protected ActivityStackSupervisor createStackSupervisor() {
2853        return new ActivityStackSupervisor(this, mHandler.getLooper());
2854    }
2855
2856    public void setSystemServiceManager(SystemServiceManager mgr) {
2857        mSystemServiceManager = mgr;
2858    }
2859
2860    public void setInstaller(Installer installer) {
2861        mInstaller = installer;
2862    }
2863
2864    private void start() {
2865        removeAllProcessGroups();
2866        mProcessCpuThread.start();
2867
2868        mBatteryStatsService.publish(mContext);
2869        mAppOpsService.publish(mContext);
2870        Slog.d("AppOps", "AppOpsService published");
2871        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2872        // Wait for the synchronized block started in mProcessCpuThread,
2873        // so that any other acccess to mProcessCpuTracker from main thread
2874        // will be blocked during mProcessCpuTracker initialization.
2875        try {
2876            mProcessCpuInitLatch.await();
2877        } catch (InterruptedException e) {
2878            Slog.wtf(TAG, "Interrupted wait during start", e);
2879            Thread.currentThread().interrupt();
2880            throw new IllegalStateException("Interrupted wait during start");
2881        }
2882    }
2883
2884    void onUserStoppedLocked(int userId) {
2885        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2886    }
2887
2888    public void initPowerManagement() {
2889        mStackSupervisor.initPowerManagement();
2890        mBatteryStatsService.initPowerManagement();
2891        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2892        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2893        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2894        mVoiceWakeLock.setReferenceCounted(false);
2895    }
2896
2897    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2898        if (mBackgroundLaunchBroadcasts == null) {
2899            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2900        }
2901        return mBackgroundLaunchBroadcasts;
2902    }
2903
2904    @Override
2905    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2906            throws RemoteException {
2907        if (code == SYSPROPS_TRANSACTION) {
2908            // We need to tell all apps about the system property change.
2909            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2910            synchronized(this) {
2911                final int NP = mProcessNames.getMap().size();
2912                for (int ip=0; ip<NP; ip++) {
2913                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2914                    final int NA = apps.size();
2915                    for (int ia=0; ia<NA; ia++) {
2916                        ProcessRecord app = apps.valueAt(ia);
2917                        if (app.thread != null) {
2918                            procs.add(app.thread.asBinder());
2919                        }
2920                    }
2921                }
2922            }
2923
2924            int N = procs.size();
2925            for (int i=0; i<N; i++) {
2926                Parcel data2 = Parcel.obtain();
2927                try {
2928                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2929                            Binder.FLAG_ONEWAY);
2930                } catch (RemoteException e) {
2931                }
2932                data2.recycle();
2933            }
2934        }
2935        try {
2936            return super.onTransact(code, data, reply, flags);
2937        } catch (RuntimeException e) {
2938            // The activity manager only throws security exceptions, so let's
2939            // log all others.
2940            if (!(e instanceof SecurityException)) {
2941                Slog.wtf(TAG, "Activity Manager Crash", e);
2942            }
2943            throw e;
2944        }
2945    }
2946
2947    void updateCpuStats() {
2948        final long now = SystemClock.uptimeMillis();
2949        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2950            return;
2951        }
2952        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2953            synchronized (mProcessCpuThread) {
2954                mProcessCpuThread.notify();
2955            }
2956        }
2957    }
2958
2959    void updateCpuStatsNow() {
2960        synchronized (mProcessCpuTracker) {
2961            mProcessCpuMutexFree.set(false);
2962            final long now = SystemClock.uptimeMillis();
2963            boolean haveNewCpuStats = false;
2964
2965            if (MONITOR_CPU_USAGE &&
2966                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2967                mLastCpuTime.set(now);
2968                mProcessCpuTracker.update();
2969                if (mProcessCpuTracker.hasGoodLastStats()) {
2970                    haveNewCpuStats = true;
2971                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2972                    //Slog.i(TAG, "Total CPU usage: "
2973                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2974
2975                    // Slog the cpu usage if the property is set.
2976                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2977                        int user = mProcessCpuTracker.getLastUserTime();
2978                        int system = mProcessCpuTracker.getLastSystemTime();
2979                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2980                        int irq = mProcessCpuTracker.getLastIrqTime();
2981                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2982                        int idle = mProcessCpuTracker.getLastIdleTime();
2983
2984                        int total = user + system + iowait + irq + softIrq + idle;
2985                        if (total == 0) total = 1;
2986
2987                        EventLog.writeEvent(EventLogTags.CPU,
2988                                ((user+system+iowait+irq+softIrq) * 100) / total,
2989                                (user * 100) / total,
2990                                (system * 100) / total,
2991                                (iowait * 100) / total,
2992                                (irq * 100) / total,
2993                                (softIrq * 100) / total);
2994                    }
2995                }
2996            }
2997
2998            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2999            synchronized(bstats) {
3000                synchronized(mPidsSelfLocked) {
3001                    if (haveNewCpuStats) {
3002                        if (bstats.startAddingCpuLocked()) {
3003                            int totalUTime = 0;
3004                            int totalSTime = 0;
3005                            final int N = mProcessCpuTracker.countStats();
3006                            for (int i=0; i<N; i++) {
3007                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3008                                if (!st.working) {
3009                                    continue;
3010                                }
3011                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3012                                totalUTime += st.rel_utime;
3013                                totalSTime += st.rel_stime;
3014                                if (pr != null) {
3015                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3016                                    if (ps == null || !ps.isActive()) {
3017                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3018                                                pr.info.uid, pr.processName);
3019                                    }
3020                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3021                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3022                                } else {
3023                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3024                                    if (ps == null || !ps.isActive()) {
3025                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3026                                                bstats.mapUid(st.uid), st.name);
3027                                    }
3028                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3029                                }
3030                            }
3031                            final int userTime = mProcessCpuTracker.getLastUserTime();
3032                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3033                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3034                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3035                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3036                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3037                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3038                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3039                        }
3040                    }
3041                }
3042
3043                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3044                    mLastWriteTime = now;
3045                    mBatteryStatsService.scheduleWriteToDisk();
3046                }
3047            }
3048        }
3049    }
3050
3051    @Override
3052    public void batteryNeedsCpuUpdate() {
3053        updateCpuStatsNow();
3054    }
3055
3056    @Override
3057    public void batteryPowerChanged(boolean onBattery) {
3058        // When plugging in, update the CPU stats first before changing
3059        // the plug state.
3060        updateCpuStatsNow();
3061        synchronized (this) {
3062            synchronized(mPidsSelfLocked) {
3063                mOnBattery = DEBUG_POWER ? true : onBattery;
3064            }
3065        }
3066    }
3067
3068    @Override
3069    public void batterySendBroadcast(Intent intent) {
3070        synchronized (this) {
3071            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3072                    AppOpsManager.OP_NONE, null, false, false,
3073                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3074        }
3075    }
3076
3077    /**
3078     * Initialize the application bind args. These are passed to each
3079     * process when the bindApplication() IPC is sent to the process. They're
3080     * lazily setup to make sure the services are running when they're asked for.
3081     */
3082    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3083        // Isolated processes won't get this optimization, so that we don't
3084        // violate the rules about which services they have access to.
3085        if (isolated) {
3086            if (mIsolatedAppBindArgs == null) {
3087                mIsolatedAppBindArgs = new HashMap<>();
3088                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3089            }
3090            return mIsolatedAppBindArgs;
3091        }
3092
3093        if (mAppBindArgs == null) {
3094            mAppBindArgs = new HashMap<>();
3095
3096            // Setup the application init args
3097            mAppBindArgs.put("package", ServiceManager.getService("package"));
3098            mAppBindArgs.put("window", ServiceManager.getService("window"));
3099            mAppBindArgs.put(Context.ALARM_SERVICE,
3100                    ServiceManager.getService(Context.ALARM_SERVICE));
3101        }
3102        return mAppBindArgs;
3103    }
3104
3105    /**
3106     * Update AMS states when an activity is resumed. This should only be called by
3107     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3108     */
3109    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3110        final TaskRecord task = r.getTask();
3111        if (task.isApplicationTask()) {
3112            if (mCurAppTimeTracker != r.appTimeTracker) {
3113                // We are switching app tracking.  Complete the current one.
3114                if (mCurAppTimeTracker != null) {
3115                    mCurAppTimeTracker.stop();
3116                    mHandler.obtainMessage(
3117                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3118                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3119                    mCurAppTimeTracker = null;
3120                }
3121                if (r.appTimeTracker != null) {
3122                    mCurAppTimeTracker = r.appTimeTracker;
3123                    startTimeTrackingFocusedActivityLocked();
3124                }
3125            } else {
3126                startTimeTrackingFocusedActivityLocked();
3127            }
3128        } else {
3129            r.appTimeTracker = null;
3130        }
3131        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3132        // TODO: Probably not, because we don't want to resume voice on switching
3133        // back to this activity
3134        if (task.voiceInteractor != null) {
3135            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3136        } else {
3137            finishRunningVoiceLocked();
3138
3139            if (mLastResumedActivity != null) {
3140                final IVoiceInteractionSession session;
3141
3142                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3143                if (lastResumedActivityTask != null
3144                        && lastResumedActivityTask.voiceSession != null) {
3145                    session = lastResumedActivityTask.voiceSession;
3146                } else {
3147                    session = mLastResumedActivity.voiceSession;
3148                }
3149
3150                if (session != null) {
3151                    // We had been in a voice interaction session, but now focused has
3152                    // move to something different.  Just finish the session, we can't
3153                    // return to it and retain the proper state and synchronization with
3154                    // the voice interaction service.
3155                    finishVoiceTask(session);
3156                }
3157            }
3158        }
3159
3160        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3161            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3162            mHandler.obtainMessage(
3163                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3164        }
3165        mLastResumedActivity = r;
3166
3167        mWindowManager.setFocusedApp(r.appToken, true);
3168
3169        applyUpdateLockStateLocked(r);
3170        applyUpdateVrModeLocked(r);
3171
3172        EventLogTags.writeAmSetResumedActivity(
3173                r == null ? -1 : r.userId,
3174                r == null ? "NULL" : r.shortComponentName,
3175                reason);
3176    }
3177
3178    @Override
3179    public void setFocusedStack(int stackId) {
3180        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3181        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3182        final long callingId = Binder.clearCallingIdentity();
3183        try {
3184            synchronized (this) {
3185                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3186                if (stack == null) {
3187                    return;
3188                }
3189                final ActivityRecord r = stack.topRunningActivityLocked();
3190                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3191                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3192                }
3193            }
3194        } finally {
3195            Binder.restoreCallingIdentity(callingId);
3196        }
3197    }
3198
3199    @Override
3200    public void setFocusedTask(int taskId) {
3201        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3202        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3203        final long callingId = Binder.clearCallingIdentity();
3204        try {
3205            synchronized (this) {
3206                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3207                if (task == null) {
3208                    return;
3209                }
3210                final ActivityRecord r = task.topRunningActivityLocked();
3211                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3212                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3213                }
3214            }
3215        } finally {
3216            Binder.restoreCallingIdentity(callingId);
3217        }
3218    }
3219
3220    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3221    @Override
3222    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3223        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3224        mTaskChangeNotificationController.registerTaskStackListener(listener);
3225    }
3226
3227    /**
3228     * Unregister a task stack listener so that it stops receiving callbacks.
3229     */
3230    @Override
3231    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3232         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3233         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3234     }
3235
3236    @Override
3237    public void notifyActivityDrawn(IBinder token) {
3238        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3239        synchronized (this) {
3240            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3241            if (r != null) {
3242                r.getStack().notifyActivityDrawnLocked(r);
3243            }
3244        }
3245    }
3246
3247    final void applyUpdateLockStateLocked(ActivityRecord r) {
3248        // Modifications to the UpdateLock state are done on our handler, outside
3249        // the activity manager's locks.  The new state is determined based on the
3250        // state *now* of the relevant activity record.  The object is passed to
3251        // the handler solely for logging detail, not to be consulted/modified.
3252        final boolean nextState = r != null && r.immersive;
3253        mHandler.sendMessage(
3254                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3255    }
3256
3257    final void applyUpdateVrModeLocked(ActivityRecord r) {
3258        mHandler.sendMessage(
3259                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3260    }
3261
3262    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3263        mHandler.sendMessage(
3264                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3265    }
3266
3267    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3268        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3269        if (vrService == null) {
3270            return;
3271        }
3272        vrService.onSleepStateChanged(isSleeping);
3273    }
3274
3275    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3276        Message msg = Message.obtain();
3277        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3278        msg.obj = r.getTask().askedCompatMode ? null : r;
3279        mUiHandler.sendMessage(msg);
3280    }
3281
3282    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3283        final Configuration globalConfig = getGlobalConfiguration();
3284        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3285                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3286            final Message msg = Message.obtain();
3287            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3288            msg.obj = r;
3289            mUiHandler.sendMessage(msg);
3290        }
3291    }
3292
3293    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3294            String what, Object obj, ProcessRecord srcApp) {
3295        app.lastActivityTime = now;
3296
3297        if (app.activities.size() > 0) {
3298            // Don't want to touch dependent processes that are hosting activities.
3299            return index;
3300        }
3301
3302        int lrui = mLruProcesses.lastIndexOf(app);
3303        if (lrui < 0) {
3304            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3305                    + what + " " + obj + " from " + srcApp);
3306            return index;
3307        }
3308
3309        if (lrui >= index) {
3310            // Don't want to cause this to move dependent processes *back* in the
3311            // list as if they were less frequently used.
3312            return index;
3313        }
3314
3315        if (lrui >= mLruProcessActivityStart) {
3316            // Don't want to touch dependent processes that are hosting activities.
3317            return index;
3318        }
3319
3320        mLruProcesses.remove(lrui);
3321        if (index > 0) {
3322            index--;
3323        }
3324        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3325                + " in LRU list: " + app);
3326        mLruProcesses.add(index, app);
3327        return index;
3328    }
3329
3330    static void killProcessGroup(int uid, int pid) {
3331        if (sKillHandler != null) {
3332            sKillHandler.sendMessage(
3333                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3334        } else {
3335            Slog.w(TAG, "Asked to kill process group before system bringup!");
3336            Process.killProcessGroup(uid, pid);
3337        }
3338    }
3339
3340    final void removeLruProcessLocked(ProcessRecord app) {
3341        int lrui = mLruProcesses.lastIndexOf(app);
3342        if (lrui >= 0) {
3343            if (!app.killed) {
3344                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3345                killProcessQuiet(app.pid);
3346                killProcessGroup(app.uid, app.pid);
3347            }
3348            if (lrui <= mLruProcessActivityStart) {
3349                mLruProcessActivityStart--;
3350            }
3351            if (lrui <= mLruProcessServiceStart) {
3352                mLruProcessServiceStart--;
3353            }
3354            mLruProcesses.remove(lrui);
3355        }
3356    }
3357
3358    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3359            ProcessRecord client) {
3360        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3361                || app.treatLikeActivity;
3362        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3363        if (!activityChange && hasActivity) {
3364            // The process has activities, so we are only allowing activity-based adjustments
3365            // to move it.  It should be kept in the front of the list with other
3366            // processes that have activities, and we don't want those to change their
3367            // order except due to activity operations.
3368            return;
3369        }
3370
3371        mLruSeq++;
3372        final long now = SystemClock.uptimeMillis();
3373        app.lastActivityTime = now;
3374
3375        // First a quick reject: if the app is already at the position we will
3376        // put it, then there is nothing to do.
3377        if (hasActivity) {
3378            final int N = mLruProcesses.size();
3379            if (N > 0 && mLruProcesses.get(N-1) == app) {
3380                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3381                return;
3382            }
3383        } else {
3384            if (mLruProcessServiceStart > 0
3385                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3386                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3387                return;
3388            }
3389        }
3390
3391        int lrui = mLruProcesses.lastIndexOf(app);
3392
3393        if (app.persistent && lrui >= 0) {
3394            // We don't care about the position of persistent processes, as long as
3395            // they are in the list.
3396            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3397            return;
3398        }
3399
3400        /* In progress: compute new position first, so we can avoid doing work
3401           if the process is not actually going to move.  Not yet working.
3402        int addIndex;
3403        int nextIndex;
3404        boolean inActivity = false, inService = false;
3405        if (hasActivity) {
3406            // Process has activities, put it at the very tipsy-top.
3407            addIndex = mLruProcesses.size();
3408            nextIndex = mLruProcessServiceStart;
3409            inActivity = true;
3410        } else if (hasService) {
3411            // Process has services, put it at the top of the service list.
3412            addIndex = mLruProcessActivityStart;
3413            nextIndex = mLruProcessServiceStart;
3414            inActivity = true;
3415            inService = true;
3416        } else  {
3417            // Process not otherwise of interest, it goes to the top of the non-service area.
3418            addIndex = mLruProcessServiceStart;
3419            if (client != null) {
3420                int clientIndex = mLruProcesses.lastIndexOf(client);
3421                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3422                        + app);
3423                if (clientIndex >= 0 && addIndex > clientIndex) {
3424                    addIndex = clientIndex;
3425                }
3426            }
3427            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3428        }
3429
3430        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3431                + mLruProcessActivityStart + "): " + app);
3432        */
3433
3434        if (lrui >= 0) {
3435            if (lrui < mLruProcessActivityStart) {
3436                mLruProcessActivityStart--;
3437            }
3438            if (lrui < mLruProcessServiceStart) {
3439                mLruProcessServiceStart--;
3440            }
3441            /*
3442            if (addIndex > lrui) {
3443                addIndex--;
3444            }
3445            if (nextIndex > lrui) {
3446                nextIndex--;
3447            }
3448            */
3449            mLruProcesses.remove(lrui);
3450        }
3451
3452        /*
3453        mLruProcesses.add(addIndex, app);
3454        if (inActivity) {
3455            mLruProcessActivityStart++;
3456        }
3457        if (inService) {
3458            mLruProcessActivityStart++;
3459        }
3460        */
3461
3462        int nextIndex;
3463        if (hasActivity) {
3464            final int N = mLruProcesses.size();
3465            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3466                // Process doesn't have activities, but has clients with
3467                // activities...  move it up, but one below the top (the top
3468                // should always have a real activity).
3469                if (DEBUG_LRU) Slog.d(TAG_LRU,
3470                        "Adding to second-top of LRU activity list: " + app);
3471                mLruProcesses.add(N - 1, app);
3472                // To keep it from spamming the LRU list (by making a bunch of clients),
3473                // we will push down any other entries owned by the app.
3474                final int uid = app.info.uid;
3475                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3476                    ProcessRecord subProc = mLruProcesses.get(i);
3477                    if (subProc.info.uid == uid) {
3478                        // We want to push this one down the list.  If the process after
3479                        // it is for the same uid, however, don't do so, because we don't
3480                        // want them internally to be re-ordered.
3481                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3482                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3483                                    "Pushing uid " + uid + " swapping at " + i + ": "
3484                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3485                            ProcessRecord tmp = mLruProcesses.get(i);
3486                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3487                            mLruProcesses.set(i - 1, tmp);
3488                            i--;
3489                        }
3490                    } else {
3491                        // A gap, we can stop here.
3492                        break;
3493                    }
3494                }
3495            } else {
3496                // Process has activities, put it at the very tipsy-top.
3497                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3498                mLruProcesses.add(app);
3499            }
3500            nextIndex = mLruProcessServiceStart;
3501        } else if (hasService) {
3502            // Process has services, put it at the top of the service list.
3503            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3504            mLruProcesses.add(mLruProcessActivityStart, app);
3505            nextIndex = mLruProcessServiceStart;
3506            mLruProcessActivityStart++;
3507        } else  {
3508            // Process not otherwise of interest, it goes to the top of the non-service area.
3509            int index = mLruProcessServiceStart;
3510            if (client != null) {
3511                // If there is a client, don't allow the process to be moved up higher
3512                // in the list than that client.
3513                int clientIndex = mLruProcesses.lastIndexOf(client);
3514                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3515                        + " when updating " + app);
3516                if (clientIndex <= lrui) {
3517                    // Don't allow the client index restriction to push it down farther in the
3518                    // list than it already is.
3519                    clientIndex = lrui;
3520                }
3521                if (clientIndex >= 0 && index > clientIndex) {
3522                    index = clientIndex;
3523                }
3524            }
3525            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3526            mLruProcesses.add(index, app);
3527            nextIndex = index-1;
3528            mLruProcessActivityStart++;
3529            mLruProcessServiceStart++;
3530        }
3531
3532        // If the app is currently using a content provider or service,
3533        // bump those processes as well.
3534        for (int j=app.connections.size()-1; j>=0; j--) {
3535            ConnectionRecord cr = app.connections.valueAt(j);
3536            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3537                    && cr.binding.service.app != null
3538                    && cr.binding.service.app.lruSeq != mLruSeq
3539                    && !cr.binding.service.app.persistent) {
3540                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3541                        "service connection", cr, app);
3542            }
3543        }
3544        for (int j=app.conProviders.size()-1; j>=0; j--) {
3545            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3546            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3547                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3548                        "provider reference", cpr, app);
3549            }
3550        }
3551    }
3552
3553    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3554        if (uid == SYSTEM_UID) {
3555            // The system gets to run in any process.  If there are multiple
3556            // processes with the same uid, just pick the first (this
3557            // should never happen).
3558            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3559            if (procs == null) return null;
3560            final int procCount = procs.size();
3561            for (int i = 0; i < procCount; i++) {
3562                final int procUid = procs.keyAt(i);
3563                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3564                    // Don't use an app process or different user process for system component.
3565                    continue;
3566                }
3567                return procs.valueAt(i);
3568            }
3569        }
3570        ProcessRecord proc = mProcessNames.get(processName, uid);
3571        if (false && proc != null && !keepIfLarge
3572                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3573                && proc.lastCachedPss >= 4000) {
3574            // Turn this condition on to cause killing to happen regularly, for testing.
3575            if (proc.baseProcessTracker != null) {
3576                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3577            }
3578            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3579        } else if (proc != null && !keepIfLarge
3580                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3581                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3582            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3583            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3584                if (proc.baseProcessTracker != null) {
3585                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3586                }
3587                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3588            }
3589        }
3590        return proc;
3591    }
3592
3593    void notifyPackageUse(String packageName, int reason) {
3594        IPackageManager pm = AppGlobals.getPackageManager();
3595        try {
3596            pm.notifyPackageUse(packageName, reason);
3597        } catch (RemoteException e) {
3598        }
3599    }
3600
3601    boolean isNextTransitionForward() {
3602        int transit = mWindowManager.getPendingAppTransition();
3603        return transit == TRANSIT_ACTIVITY_OPEN
3604                || transit == TRANSIT_TASK_OPEN
3605                || transit == TRANSIT_TASK_TO_FRONT;
3606    }
3607
3608    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3609            String processName, String abiOverride, int uid, Runnable crashHandler) {
3610        synchronized(this) {
3611            ApplicationInfo info = new ApplicationInfo();
3612            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3613            // For isolated processes, the former contains the parent's uid and the latter the
3614            // actual uid of the isolated process.
3615            // In the special case introduced by this method (which is, starting an isolated
3616            // process directly from the SystemServer without an actual parent app process) the
3617            // closest thing to a parent's uid is SYSTEM_UID.
3618            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3619            // the |isolated| logic in the ProcessRecord constructor.
3620            info.uid = SYSTEM_UID;
3621            info.processName = processName;
3622            info.className = entryPoint;
3623            info.packageName = "android";
3624            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3625            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3626                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3627                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3628                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3629                    crashHandler);
3630            return proc != null ? proc.pid : 0;
3631        }
3632    }
3633
3634    final ProcessRecord startProcessLocked(String processName,
3635            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3636            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3637            boolean isolated, boolean keepIfLarge) {
3638        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3639                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3640                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3641                null /* crashHandler */);
3642    }
3643
3644    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3645            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3646            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3647            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3648        long startTime = SystemClock.elapsedRealtime();
3649        ProcessRecord app;
3650        if (!isolated) {
3651            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3652            checkTime(startTime, "startProcess: after getProcessRecord");
3653
3654            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3655                // If we are in the background, then check to see if this process
3656                // is bad.  If so, we will just silently fail.
3657                if (mAppErrors.isBadProcessLocked(info)) {
3658                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3659                            + "/" + info.processName);
3660                    return null;
3661                }
3662            } else {
3663                // When the user is explicitly starting a process, then clear its
3664                // crash count so that we won't make it bad until they see at
3665                // least one crash dialog again, and make the process good again
3666                // if it had been bad.
3667                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3668                        + "/" + info.processName);
3669                mAppErrors.resetProcessCrashTimeLocked(info);
3670                if (mAppErrors.isBadProcessLocked(info)) {
3671                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3672                            UserHandle.getUserId(info.uid), info.uid,
3673                            info.processName);
3674                    mAppErrors.clearBadProcessLocked(info);
3675                    if (app != null) {
3676                        app.bad = false;
3677                    }
3678                }
3679            }
3680        } else {
3681            // If this is an isolated process, it can't re-use an existing process.
3682            app = null;
3683        }
3684
3685        // We don't have to do anything more if:
3686        // (1) There is an existing application record; and
3687        // (2) The caller doesn't think it is dead, OR there is no thread
3688        //     object attached to it so we know it couldn't have crashed; and
3689        // (3) There is a pid assigned to it, so it is either starting or
3690        //     already running.
3691        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3692                + " app=" + app + " knownToBeDead=" + knownToBeDead
3693                + " thread=" + (app != null ? app.thread : null)
3694                + " pid=" + (app != null ? app.pid : -1));
3695        if (app != null && app.pid > 0) {
3696            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3697                // We already have the app running, or are waiting for it to
3698                // come up (we have a pid but not yet its thread), so keep it.
3699                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3700                // If this is a new package in the process, add the package to the list
3701                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3702                checkTime(startTime, "startProcess: done, added package to proc");
3703                return app;
3704            }
3705
3706            // An application record is attached to a previous process,
3707            // clean it up now.
3708            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3709            checkTime(startTime, "startProcess: bad proc running, killing");
3710            killProcessGroup(app.uid, app.pid);
3711            handleAppDiedLocked(app, true, true);
3712            checkTime(startTime, "startProcess: done killing old proc");
3713        }
3714
3715        String hostingNameStr = hostingName != null
3716                ? hostingName.flattenToShortString() : null;
3717
3718        if (app == null) {
3719            checkTime(startTime, "startProcess: creating new process record");
3720            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3721            if (app == null) {
3722                Slog.w(TAG, "Failed making new process record for "
3723                        + processName + "/" + info.uid + " isolated=" + isolated);
3724                return null;
3725            }
3726            app.crashHandler = crashHandler;
3727            checkTime(startTime, "startProcess: done creating new process record");
3728        } else {
3729            // If this is a new package in the process, add the package to the list
3730            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3731            checkTime(startTime, "startProcess: added package to existing proc");
3732        }
3733
3734        // If the system is not ready yet, then hold off on starting this
3735        // process until it is.
3736        if (!mProcessesReady
3737                && !isAllowedWhileBooting(info)
3738                && !allowWhileBooting) {
3739            if (!mProcessesOnHold.contains(app)) {
3740                mProcessesOnHold.add(app);
3741            }
3742            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3743                    "System not ready, putting on hold: " + app);
3744            checkTime(startTime, "startProcess: returning with proc on hold");
3745            return app;
3746        }
3747
3748        checkTime(startTime, "startProcess: stepping in to startProcess");
3749        startProcessLocked(
3750                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3751        checkTime(startTime, "startProcess: done starting proc!");
3752        return (app.pid != 0) ? app : null;
3753    }
3754
3755    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3756        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3757    }
3758
3759    private final void startProcessLocked(ProcessRecord app,
3760            String hostingType, String hostingNameStr) {
3761        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3762                null /* entryPoint */, null /* entryPointArgs */);
3763    }
3764
3765    private final void startProcessLocked(ProcessRecord app, String hostingType,
3766            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3767        long startTime = SystemClock.elapsedRealtime();
3768        if (app.pid > 0 && app.pid != MY_PID) {
3769            checkTime(startTime, "startProcess: removing from pids map");
3770            synchronized (mPidsSelfLocked) {
3771                mPidsSelfLocked.remove(app.pid);
3772                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3773            }
3774            checkTime(startTime, "startProcess: done removing from pids map");
3775            app.setPid(0);
3776        }
3777
3778        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3779                "startProcessLocked removing on hold: " + app);
3780        mProcessesOnHold.remove(app);
3781
3782        checkTime(startTime, "startProcess: starting to update cpu stats");
3783        updateCpuStats();
3784        checkTime(startTime, "startProcess: done updating cpu stats");
3785
3786        try {
3787            try {
3788                final int userId = UserHandle.getUserId(app.uid);
3789                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3790            } catch (RemoteException e) {
3791                throw e.rethrowAsRuntimeException();
3792            }
3793
3794            int uid = app.uid;
3795            int[] gids = null;
3796            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3797            if (!app.isolated) {
3798                int[] permGids = null;
3799                try {
3800                    checkTime(startTime, "startProcess: getting gids from package manager");
3801                    final IPackageManager pm = AppGlobals.getPackageManager();
3802                    permGids = pm.getPackageGids(app.info.packageName,
3803                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3804                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3805                            StorageManagerInternal.class);
3806                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3807                            app.info.packageName);
3808                } catch (RemoteException e) {
3809                    throw e.rethrowAsRuntimeException();
3810                }
3811
3812                /*
3813                 * Add shared application and profile GIDs so applications can share some
3814                 * resources like shared libraries and access user-wide resources
3815                 */
3816                if (ArrayUtils.isEmpty(permGids)) {
3817                    gids = new int[3];
3818                } else {
3819                    gids = new int[permGids.length + 3];
3820                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3821                }
3822                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3823                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3824                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3825            }
3826            checkTime(startTime, "startProcess: building args");
3827            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3828                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3829                        && mTopComponent != null
3830                        && app.processName.equals(mTopComponent.getPackageName())) {
3831                    uid = 0;
3832                }
3833                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3834                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3835                    uid = 0;
3836                }
3837            }
3838            int debugFlags = 0;
3839            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3840                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3841                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3842                // Also turn on CheckJNI for debuggable apps. It's quite
3843                // awkward to turn on otherwise.
3844                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3845            }
3846            // Run the app in safe mode if its manifest requests so or the
3847            // system is booted in safe mode.
3848            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3849                mSafeMode == true) {
3850                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3851            }
3852            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3853                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3854            }
3855            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3856            if ("true".equals(genDebugInfoProperty)) {
3857                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3858            }
3859            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3860                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3861            }
3862            if ("1".equals(SystemProperties.get("debug.assert"))) {
3863                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3864            }
3865            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3866                // Enable all debug flags required by the native debugger.
3867                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3868                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3869                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3870                mNativeDebuggingApp = null;
3871            }
3872
3873            String invokeWith = null;
3874            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3875                // Debuggable apps may include a wrapper script with their library directory.
3876                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3877                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3878                try {
3879                    if (new File(wrapperFileName).exists()) {
3880                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3881                    }
3882                } finally {
3883                    StrictMode.setThreadPolicy(oldPolicy);
3884                }
3885            }
3886
3887            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3888            if (requiredAbi == null) {
3889                requiredAbi = Build.SUPPORTED_ABIS[0];
3890            }
3891
3892            String instructionSet = null;
3893            if (app.info.primaryCpuAbi != null) {
3894                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3895            }
3896
3897            app.gids = gids;
3898            app.requiredAbi = requiredAbi;
3899            app.instructionSet = instructionSet;
3900
3901            // the per-user SELinux context must be set
3902            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3903                Slog.wtf(TAG, "SELinux tag not defined",
3904                        new IllegalStateException("SELinux tag not defined for "
3905                        + app.info.packageName + " (uid " + app.uid + ")"));
3906            }
3907            final String seInfo = app.info.seInfo
3908                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3909            // Start the process.  It will either succeed and return a result containing
3910            // the PID of the new process, or else throw a RuntimeException.
3911            boolean isActivityProcess = (entryPoint == null);
3912            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3913            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3914                    app.processName);
3915            checkTime(startTime, "startProcess: asking zygote to start proc");
3916            ProcessStartResult startResult;
3917            if (hostingType.equals("webview_service")) {
3918                startResult = startWebView(entryPoint,
3919                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3920                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3921                        app.info.dataDir, null, entryPointArgs);
3922            } else {
3923                startResult = Process.start(entryPoint,
3924                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3925                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3926                        app.info.dataDir, invokeWith, entryPointArgs);
3927            }
3928            checkTime(startTime, "startProcess: returned from zygote!");
3929            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3930
3931            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3932            checkTime(startTime, "startProcess: done updating battery stats");
3933
3934            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3935                    UserHandle.getUserId(uid), startResult.pid, uid,
3936                    app.processName, hostingType,
3937                    hostingNameStr != null ? hostingNameStr : "");
3938
3939            try {
3940                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3941                        seInfo, app.info.sourceDir, startResult.pid);
3942            } catch (RemoteException ex) {
3943                // Ignore
3944            }
3945
3946            if (app.persistent) {
3947                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3948            }
3949
3950            checkTime(startTime, "startProcess: building log message");
3951            StringBuilder buf = mStringBuilder;
3952            buf.setLength(0);
3953            buf.append("Start proc ");
3954            buf.append(startResult.pid);
3955            buf.append(':');
3956            buf.append(app.processName);
3957            buf.append('/');
3958            UserHandle.formatUid(buf, uid);
3959            if (!isActivityProcess) {
3960                buf.append(" [");
3961                buf.append(entryPoint);
3962                buf.append("]");
3963            }
3964            buf.append(" for ");
3965            buf.append(hostingType);
3966            if (hostingNameStr != null) {
3967                buf.append(" ");
3968                buf.append(hostingNameStr);
3969            }
3970            Slog.i(TAG, buf.toString());
3971            app.setPid(startResult.pid);
3972            app.usingWrapper = startResult.usingWrapper;
3973            app.removed = false;
3974            app.killed = false;
3975            app.killedByAm = false;
3976            checkTime(startTime, "startProcess: starting to update pids map");
3977            ProcessRecord oldApp;
3978            synchronized (mPidsSelfLocked) {
3979                oldApp = mPidsSelfLocked.get(startResult.pid);
3980            }
3981            // If there is already an app occupying that pid that hasn't been cleaned up
3982            if (oldApp != null && !app.isolated) {
3983                // Clean up anything relating to this pid first
3984                Slog.w(TAG, "Reusing pid " + startResult.pid
3985                        + " while app is still mapped to it");
3986                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3987                        true /*replacingPid*/);
3988            }
3989            synchronized (mPidsSelfLocked) {
3990                this.mPidsSelfLocked.put(startResult.pid, app);
3991                if (isActivityProcess) {
3992                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3993                    msg.obj = app;
3994                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3995                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3996                }
3997            }
3998            checkTime(startTime, "startProcess: done updating pids map");
3999        } catch (RuntimeException e) {
4000            Slog.e(TAG, "Failure starting process " + app.processName, e);
4001
4002            // Something went very wrong while trying to start this process; one
4003            // common case is when the package is frozen due to an active
4004            // upgrade. To recover, clean up any active bookkeeping related to
4005            // starting this process. (We already invoked this method once when
4006            // the package was initially frozen through KILL_APPLICATION_MSG, so
4007            // it doesn't hurt to use it again.)
4008            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4009                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4010        }
4011    }
4012
4013    void updateUsageStats(ActivityRecord component, boolean resumed) {
4014        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4015                "updateUsageStats: comp=" + component + "res=" + resumed);
4016        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4017        if (resumed) {
4018            if (mUsageStatsService != null) {
4019                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4020                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4021            }
4022            synchronized (stats) {
4023                stats.noteActivityResumedLocked(component.app.uid);
4024            }
4025        } else {
4026            if (mUsageStatsService != null) {
4027                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4028                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4029            }
4030            synchronized (stats) {
4031                stats.noteActivityPausedLocked(component.app.uid);
4032            }
4033        }
4034    }
4035
4036    Intent getHomeIntent() {
4037        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4038        intent.setComponent(mTopComponent);
4039        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4040        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4041            intent.addCategory(Intent.CATEGORY_HOME);
4042        }
4043        return intent;
4044    }
4045
4046    boolean startHomeActivityLocked(int userId, String reason) {
4047        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4048                && mTopAction == null) {
4049            // We are running in factory test mode, but unable to find
4050            // the factory test app, so just sit around displaying the
4051            // error message and don't try to start anything.
4052            return false;
4053        }
4054        Intent intent = getHomeIntent();
4055        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4056        if (aInfo != null) {
4057            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4058            // Don't do this if the home app is currently being
4059            // instrumented.
4060            aInfo = new ActivityInfo(aInfo);
4061            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4062            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4063                    aInfo.applicationInfo.uid, true);
4064            if (app == null || app.instr == null) {
4065                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4066                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
4067            }
4068        } else {
4069            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4070        }
4071
4072        return true;
4073    }
4074
4075    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4076        ActivityInfo ai = null;
4077        ComponentName comp = intent.getComponent();
4078        try {
4079            if (comp != null) {
4080                // Factory test.
4081                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4082            } else {
4083                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4084                        intent,
4085                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4086                        flags, userId);
4087
4088                if (info != null) {
4089                    ai = info.activityInfo;
4090                }
4091            }
4092        } catch (RemoteException e) {
4093            // ignore
4094        }
4095
4096        return ai;
4097    }
4098
4099    /**
4100     * Starts the "new version setup screen" if appropriate.
4101     */
4102    void startSetupActivityLocked() {
4103        // Only do this once per boot.
4104        if (mCheckedForSetup) {
4105            return;
4106        }
4107
4108        // We will show this screen if the current one is a different
4109        // version than the last one shown, and we are not running in
4110        // low-level factory test mode.
4111        final ContentResolver resolver = mContext.getContentResolver();
4112        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4113                Settings.Global.getInt(resolver,
4114                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4115            mCheckedForSetup = true;
4116
4117            // See if we should be showing the platform update setup UI.
4118            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4119            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4120                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4121            if (!ris.isEmpty()) {
4122                final ResolveInfo ri = ris.get(0);
4123                String vers = ri.activityInfo.metaData != null
4124                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4125                        : null;
4126                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4127                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4128                            Intent.METADATA_SETUP_VERSION);
4129                }
4130                String lastVers = Settings.Secure.getString(
4131                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4132                if (vers != null && !vers.equals(lastVers)) {
4133                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4134                    intent.setComponent(new ComponentName(
4135                            ri.activityInfo.packageName, ri.activityInfo.name));
4136                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4137                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4138                            null, 0, 0, 0, null, false, false, null, null, null);
4139                }
4140            }
4141        }
4142    }
4143
4144    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4145        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4146    }
4147
4148    void enforceNotIsolatedCaller(String caller) {
4149        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4150            throw new SecurityException("Isolated process not allowed to call " + caller);
4151        }
4152    }
4153
4154    void enforceShellRestriction(String restriction, int userHandle) {
4155        if (Binder.getCallingUid() == SHELL_UID) {
4156            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4157                throw new SecurityException("Shell does not have permission to access user "
4158                        + userHandle);
4159            }
4160        }
4161    }
4162
4163    @Override
4164    public int getFrontActivityScreenCompatMode() {
4165        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4166        synchronized (this) {
4167            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4168        }
4169    }
4170
4171    @Override
4172    public void setFrontActivityScreenCompatMode(int mode) {
4173        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4174                "setFrontActivityScreenCompatMode");
4175        synchronized (this) {
4176            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4177        }
4178    }
4179
4180    @Override
4181    public int getPackageScreenCompatMode(String packageName) {
4182        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4183        synchronized (this) {
4184            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4185        }
4186    }
4187
4188    @Override
4189    public void setPackageScreenCompatMode(String packageName, int mode) {
4190        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4191                "setPackageScreenCompatMode");
4192        synchronized (this) {
4193            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4194        }
4195    }
4196
4197    @Override
4198    public boolean getPackageAskScreenCompat(String packageName) {
4199        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4200        synchronized (this) {
4201            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4202        }
4203    }
4204
4205    @Override
4206    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4207        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4208                "setPackageAskScreenCompat");
4209        synchronized (this) {
4210            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4211        }
4212    }
4213
4214    private boolean hasUsageStatsPermission(String callingPackage) {
4215        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4216                Binder.getCallingUid(), callingPackage);
4217        if (mode == AppOpsManager.MODE_DEFAULT) {
4218            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4219                    == PackageManager.PERMISSION_GRANTED;
4220        }
4221        return mode == AppOpsManager.MODE_ALLOWED;
4222    }
4223
4224    @Override
4225    public int getPackageProcessState(String packageName, String callingPackage) {
4226        if (!hasUsageStatsPermission(callingPackage)) {
4227            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4228                    "getPackageProcessState");
4229        }
4230
4231        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4232        synchronized (this) {
4233            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4234                final ProcessRecord proc = mLruProcesses.get(i);
4235                if (procState > proc.setProcState) {
4236                    if (proc.pkgList.containsKey(packageName) ||
4237                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4238                        procState = proc.setProcState;
4239                    }
4240                }
4241            }
4242        }
4243        return procState;
4244    }
4245
4246    @Override
4247    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4248            throws RemoteException {
4249        synchronized (this) {
4250            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4251            if (app == null) {
4252                throw new IllegalArgumentException("Unknown process: " + process);
4253            }
4254            if (app.thread == null) {
4255                throw new IllegalArgumentException("Process has no app thread");
4256            }
4257            if (app.trimMemoryLevel >= level) {
4258                throw new IllegalArgumentException(
4259                        "Unable to set a higher trim level than current level");
4260            }
4261            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4262                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4263                throw new IllegalArgumentException("Unable to set a background trim level "
4264                    + "on a foreground process");
4265            }
4266            app.thread.scheduleTrimMemory(level);
4267            app.trimMemoryLevel = level;
4268            return true;
4269        }
4270    }
4271
4272    private void dispatchProcessesChanged() {
4273        int N;
4274        synchronized (this) {
4275            N = mPendingProcessChanges.size();
4276            if (mActiveProcessChanges.length < N) {
4277                mActiveProcessChanges = new ProcessChangeItem[N];
4278            }
4279            mPendingProcessChanges.toArray(mActiveProcessChanges);
4280            mPendingProcessChanges.clear();
4281            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4282                    "*** Delivering " + N + " process changes");
4283        }
4284
4285        int i = mProcessObservers.beginBroadcast();
4286        while (i > 0) {
4287            i--;
4288            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4289            if (observer != null) {
4290                try {
4291                    for (int j=0; j<N; j++) {
4292                        ProcessChangeItem item = mActiveProcessChanges[j];
4293                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4294                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4295                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4296                                    + item.uid + ": " + item.foregroundActivities);
4297                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4298                                    item.foregroundActivities);
4299                        }
4300                    }
4301                } catch (RemoteException e) {
4302                }
4303            }
4304        }
4305        mProcessObservers.finishBroadcast();
4306
4307        synchronized (this) {
4308            for (int j=0; j<N; j++) {
4309                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4310            }
4311        }
4312    }
4313
4314    private void dispatchProcessDied(int pid, int uid) {
4315        int i = mProcessObservers.beginBroadcast();
4316        while (i > 0) {
4317            i--;
4318            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4319            if (observer != null) {
4320                try {
4321                    observer.onProcessDied(pid, uid);
4322                } catch (RemoteException e) {
4323                }
4324            }
4325        }
4326        mProcessObservers.finishBroadcast();
4327    }
4328
4329    @VisibleForTesting
4330    void dispatchUidsChanged() {
4331        int N;
4332        synchronized (this) {
4333            N = mPendingUidChanges.size();
4334            if (mActiveUidChanges.length < N) {
4335                mActiveUidChanges = new UidRecord.ChangeItem[N];
4336            }
4337            for (int i=0; i<N; i++) {
4338                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4339                mActiveUidChanges[i] = change;
4340                if (change.uidRecord != null) {
4341                    change.uidRecord.pendingChange = null;
4342                    change.uidRecord = null;
4343                }
4344            }
4345            mPendingUidChanges.clear();
4346            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4347                    "*** Delivering " + N + " uid changes");
4348        }
4349
4350        int i = mUidObservers.beginBroadcast();
4351        while (i > 0) {
4352            i--;
4353            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4354                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4355        }
4356        mUidObservers.finishBroadcast();
4357
4358        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4359            for (int j = 0; j < N; ++j) {
4360                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4361                if (item.change == UidRecord.CHANGE_GONE
4362                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4363                    mValidateUids.remove(item.uid);
4364                } else {
4365                    UidRecord validateUid = mValidateUids.get(item.uid);
4366                    if (validateUid == null) {
4367                        validateUid = new UidRecord(item.uid);
4368                        mValidateUids.put(item.uid, validateUid);
4369                    }
4370                    if (item.change == UidRecord.CHANGE_IDLE) {
4371                        validateUid.idle = true;
4372                    } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4373                        validateUid.idle = false;
4374                    }
4375                    validateUid.curProcState = validateUid.setProcState = item.processState;
4376                }
4377            }
4378        }
4379
4380        synchronized (this) {
4381            for (int j = 0; j < N; j++) {
4382                mAvailUidChanges.add(mActiveUidChanges[j]);
4383            }
4384        }
4385    }
4386
4387    private void dispatchUidsChangedForObserver(IUidObserver observer,
4388            UidObserverRegistration reg, int changesSize) {
4389        if (observer == null) {
4390            return;
4391        }
4392        try {
4393            for (int j = 0; j < changesSize; j++) {
4394                UidRecord.ChangeItem item = mActiveUidChanges[j];
4395                final int change = item.change;
4396                if (change == UidRecord.CHANGE_IDLE
4397                        || change == UidRecord.CHANGE_GONE_IDLE) {
4398                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4399                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4400                                "UID idle uid=" + item.uid);
4401                        observer.onUidIdle(item.uid, item.ephemeral);
4402                    }
4403                } else if (change == UidRecord.CHANGE_ACTIVE) {
4404                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4405                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4406                                "UID active uid=" + item.uid);
4407                        observer.onUidActive(item.uid);
4408                    }
4409                }
4410                if (change == UidRecord.CHANGE_GONE
4411                        || change == UidRecord.CHANGE_GONE_IDLE) {
4412                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4413                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4414                                "UID gone uid=" + item.uid);
4415                        observer.onUidGone(item.uid, item.ephemeral);
4416                    }
4417                    if (reg.lastProcStates != null) {
4418                        reg.lastProcStates.delete(item.uid);
4419                    }
4420                } else {
4421                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4422                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4423                                "UID CHANGED uid=" + item.uid
4424                                        + ": " + item.processState);
4425                        boolean doReport = true;
4426                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4427                            final int lastState = reg.lastProcStates.get(item.uid,
4428                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4429                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4430                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4431                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4432                                doReport = lastAboveCut != newAboveCut;
4433                            } else {
4434                                doReport = item.processState
4435                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4436                            }
4437                        }
4438                        if (doReport) {
4439                            if (reg.lastProcStates != null) {
4440                                reg.lastProcStates.put(item.uid, item.processState);
4441                            }
4442                            observer.onUidStateChanged(item.uid, item.processState,
4443                                    item.procStateSeq);
4444                        }
4445                    }
4446                }
4447            }
4448        } catch (RemoteException e) {
4449        }
4450    }
4451
4452    @Override
4453    public final int startActivity(IApplicationThread caller, String callingPackage,
4454            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4455            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4456        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4457                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4458                UserHandle.getCallingUserId());
4459    }
4460
4461    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4462        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4463        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4464                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4465                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4466
4467        // TODO: Switch to user app stacks here.
4468        String mimeType = intent.getType();
4469        final Uri data = intent.getData();
4470        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4471            mimeType = getProviderMimeType(data, userId);
4472        }
4473        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4474
4475        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4476        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4477                null, 0, 0, null, null, null, null, false, userId, container, null);
4478    }
4479
4480    @Override
4481    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4482            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4483            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4484        enforceNotIsolatedCaller("startActivity");
4485        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4486                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4487        // TODO: Switch to user app stacks here.
4488        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4489                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4490                profilerInfo, null, null, bOptions, false, userId, null, null);
4491    }
4492
4493    @Override
4494    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4495            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4496            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4497            int userId) {
4498
4499        // This is very dangerous -- it allows you to perform a start activity (including
4500        // permission grants) as any app that may launch one of your own activities.  So
4501        // we will only allow this to be done from activities that are part of the core framework,
4502        // and then only when they are running as the system.
4503        final ActivityRecord sourceRecord;
4504        final int targetUid;
4505        final String targetPackage;
4506        synchronized (this) {
4507            if (resultTo == null) {
4508                throw new SecurityException("Must be called from an activity");
4509            }
4510            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4511            if (sourceRecord == null) {
4512                throw new SecurityException("Called with bad activity token: " + resultTo);
4513            }
4514            if (!sourceRecord.info.packageName.equals("android")) {
4515                throw new SecurityException(
4516                        "Must be called from an activity that is declared in the android package");
4517            }
4518            if (sourceRecord.app == null) {
4519                throw new SecurityException("Called without a process attached to activity");
4520            }
4521            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4522                // This is still okay, as long as this activity is running under the
4523                // uid of the original calling activity.
4524                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4525                    throw new SecurityException(
4526                            "Calling activity in uid " + sourceRecord.app.uid
4527                                    + " must be system uid or original calling uid "
4528                                    + sourceRecord.launchedFromUid);
4529                }
4530            }
4531            if (ignoreTargetSecurity) {
4532                if (intent.getComponent() == null) {
4533                    throw new SecurityException(
4534                            "Component must be specified with ignoreTargetSecurity");
4535                }
4536                if (intent.getSelector() != null) {
4537                    throw new SecurityException(
4538                            "Selector not allowed with ignoreTargetSecurity");
4539                }
4540            }
4541            targetUid = sourceRecord.launchedFromUid;
4542            targetPackage = sourceRecord.launchedFromPackage;
4543        }
4544
4545        if (userId == UserHandle.USER_NULL) {
4546            userId = UserHandle.getUserId(sourceRecord.app.uid);
4547        }
4548
4549        // TODO: Switch to user app stacks here.
4550        try {
4551            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4552                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4553                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4554            return ret;
4555        } catch (SecurityException e) {
4556            // XXX need to figure out how to propagate to original app.
4557            // A SecurityException here is generally actually a fault of the original
4558            // calling activity (such as a fairly granting permissions), so propagate it
4559            // back to them.
4560            /*
4561            StringBuilder msg = new StringBuilder();
4562            msg.append("While launching");
4563            msg.append(intent.toString());
4564            msg.append(": ");
4565            msg.append(e.getMessage());
4566            */
4567            throw e;
4568        }
4569    }
4570
4571    @Override
4572    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4573            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4574            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4575        enforceNotIsolatedCaller("startActivityAndWait");
4576        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4577                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4578        WaitResult res = new WaitResult();
4579        // TODO: Switch to user app stacks here.
4580        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4581                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4582                bOptions, false, userId, null, null);
4583        return res;
4584    }
4585
4586    @Override
4587    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4588            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4589            int startFlags, Configuration config, Bundle bOptions, int userId) {
4590        enforceNotIsolatedCaller("startActivityWithConfig");
4591        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4592                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4593        // TODO: Switch to user app stacks here.
4594        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4595                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4596                null, null, config, bOptions, false, userId, null, null);
4597        return ret;
4598    }
4599
4600    @Override
4601    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4602            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4603            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4604            throws TransactionTooLargeException {
4605        enforceNotIsolatedCaller("startActivityIntentSender");
4606        // Refuse possible leaked file descriptors
4607        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4608            throw new IllegalArgumentException("File descriptors passed in Intent");
4609        }
4610
4611        IIntentSender sender = intent.getTarget();
4612        if (!(sender instanceof PendingIntentRecord)) {
4613            throw new IllegalArgumentException("Bad PendingIntent object");
4614        }
4615
4616        PendingIntentRecord pir = (PendingIntentRecord)sender;
4617
4618        synchronized (this) {
4619            // If this is coming from the currently resumed activity, it is
4620            // effectively saying that app switches are allowed at this point.
4621            final ActivityStack stack = getFocusedStack();
4622            if (stack.mResumedActivity != null &&
4623                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4624                mAppSwitchesAllowedTime = 0;
4625            }
4626        }
4627        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4628                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4629        return ret;
4630    }
4631
4632    @Override
4633    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4634            Intent intent, String resolvedType, IVoiceInteractionSession session,
4635            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4636            Bundle bOptions, int userId) {
4637        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4638                != PackageManager.PERMISSION_GRANTED) {
4639            String msg = "Permission Denial: startVoiceActivity() from pid="
4640                    + Binder.getCallingPid()
4641                    + ", uid=" + Binder.getCallingUid()
4642                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4643            Slog.w(TAG, msg);
4644            throw new SecurityException(msg);
4645        }
4646        if (session == null || interactor == null) {
4647            throw new NullPointerException("null session or interactor");
4648        }
4649        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4650                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4651        // TODO: Switch to user app stacks here.
4652        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4653                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4654                null, bOptions, false, userId, null, null);
4655    }
4656
4657    @Override
4658    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4659            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4660        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4661                != PackageManager.PERMISSION_GRANTED) {
4662            final String msg = "Permission Denial: startAssistantActivity() from pid="
4663                    + Binder.getCallingPid()
4664                    + ", uid=" + Binder.getCallingUid()
4665                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4666            Slog.w(TAG, msg);
4667            throw new SecurityException(msg);
4668        }
4669        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4670                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4671        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4672                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4673                userId, null, null);
4674    }
4675
4676    @Override
4677    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4678            throws RemoteException {
4679        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4680        synchronized (this) {
4681            ActivityRecord activity = getFocusedStack().topActivity();
4682            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4683                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4684            }
4685            if (mRunningVoice != null || activity.getTask().voiceSession != null
4686                    || activity.voiceSession != null) {
4687                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4688                return;
4689            }
4690            if (activity.pendingVoiceInteractionStart) {
4691                Slog.w(TAG, "Pending start of voice interaction already.");
4692                return;
4693            }
4694            activity.pendingVoiceInteractionStart = true;
4695        }
4696        LocalServices.getService(VoiceInteractionManagerInternal.class)
4697                .startLocalVoiceInteraction(callingActivity, options);
4698    }
4699
4700    @Override
4701    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4702        LocalServices.getService(VoiceInteractionManagerInternal.class)
4703                .stopLocalVoiceInteraction(callingActivity);
4704    }
4705
4706    @Override
4707    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4708        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4709                .supportsLocalVoiceInteraction();
4710    }
4711
4712    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4713            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4714        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4715        if (activityToCallback == null) return;
4716        activityToCallback.setVoiceSessionLocked(voiceSession);
4717
4718        // Inform the activity
4719        try {
4720            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4721                    voiceInteractor);
4722            long token = Binder.clearCallingIdentity();
4723            try {
4724                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4725            } finally {
4726                Binder.restoreCallingIdentity(token);
4727            }
4728            // TODO: VI Should we cache the activity so that it's easier to find later
4729            // rather than scan through all the stacks and activities?
4730        } catch (RemoteException re) {
4731            activityToCallback.clearVoiceSessionLocked();
4732            // TODO: VI Should this terminate the voice session?
4733        }
4734    }
4735
4736    @Override
4737    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4738        synchronized (this) {
4739            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4740                if (keepAwake) {
4741                    mVoiceWakeLock.acquire();
4742                } else {
4743                    mVoiceWakeLock.release();
4744                }
4745            }
4746        }
4747    }
4748
4749    @Override
4750    public boolean startNextMatchingActivity(IBinder callingActivity,
4751            Intent intent, Bundle bOptions) {
4752        // Refuse possible leaked file descriptors
4753        if (intent != null && intent.hasFileDescriptors() == true) {
4754            throw new IllegalArgumentException("File descriptors passed in Intent");
4755        }
4756        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4757
4758        synchronized (this) {
4759            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4760            if (r == null) {
4761                ActivityOptions.abort(options);
4762                return false;
4763            }
4764            if (r.app == null || r.app.thread == null) {
4765                // The caller is not running...  d'oh!
4766                ActivityOptions.abort(options);
4767                return false;
4768            }
4769            intent = new Intent(intent);
4770            // The caller is not allowed to change the data.
4771            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4772            // And we are resetting to find the next component...
4773            intent.setComponent(null);
4774
4775            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4776
4777            ActivityInfo aInfo = null;
4778            try {
4779                List<ResolveInfo> resolves =
4780                    AppGlobals.getPackageManager().queryIntentActivities(
4781                            intent, r.resolvedType,
4782                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4783                            UserHandle.getCallingUserId()).getList();
4784
4785                // Look for the original activity in the list...
4786                final int N = resolves != null ? resolves.size() : 0;
4787                for (int i=0; i<N; i++) {
4788                    ResolveInfo rInfo = resolves.get(i);
4789                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4790                            && rInfo.activityInfo.name.equals(r.info.name)) {
4791                        // We found the current one...  the next matching is
4792                        // after it.
4793                        i++;
4794                        if (i<N) {
4795                            aInfo = resolves.get(i).activityInfo;
4796                        }
4797                        if (debug) {
4798                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4799                                    + "/" + r.info.name);
4800                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4801                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4802                        }
4803                        break;
4804                    }
4805                }
4806            } catch (RemoteException e) {
4807            }
4808
4809            if (aInfo == null) {
4810                // Nobody who is next!
4811                ActivityOptions.abort(options);
4812                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4813                return false;
4814            }
4815
4816            intent.setComponent(new ComponentName(
4817                    aInfo.applicationInfo.packageName, aInfo.name));
4818            intent.setFlags(intent.getFlags()&~(
4819                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4820                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4821                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4822                    Intent.FLAG_ACTIVITY_NEW_TASK));
4823
4824            // Okay now we need to start the new activity, replacing the
4825            // currently running activity.  This is a little tricky because
4826            // we want to start the new one as if the current one is finished,
4827            // but not finish the current one first so that there is no flicker.
4828            // And thus...
4829            final boolean wasFinishing = r.finishing;
4830            r.finishing = true;
4831
4832            // Propagate reply information over to the new activity.
4833            final ActivityRecord resultTo = r.resultTo;
4834            final String resultWho = r.resultWho;
4835            final int requestCode = r.requestCode;
4836            r.resultTo = null;
4837            if (resultTo != null) {
4838                resultTo.removeResultsLocked(r, resultWho, requestCode);
4839            }
4840
4841            final long origId = Binder.clearCallingIdentity();
4842            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4843                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4844                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4845                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4846                    false, false, null, null, null);
4847            Binder.restoreCallingIdentity(origId);
4848
4849            r.finishing = wasFinishing;
4850            if (res != ActivityManager.START_SUCCESS) {
4851                return false;
4852            }
4853            return true;
4854        }
4855    }
4856
4857    @Override
4858    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4859        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4860            String msg = "Permission Denial: startActivityFromRecents called without " +
4861                    START_TASKS_FROM_RECENTS;
4862            Slog.w(TAG, msg);
4863            throw new SecurityException(msg);
4864        }
4865        final long origId = Binder.clearCallingIdentity();
4866        try {
4867            synchronized (this) {
4868                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4869            }
4870        } finally {
4871            Binder.restoreCallingIdentity(origId);
4872        }
4873    }
4874
4875    final int startActivityInPackage(int uid, String callingPackage,
4876            Intent intent, String resolvedType, IBinder resultTo,
4877            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4878            IActivityContainer container, TaskRecord inTask) {
4879
4880        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4881                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4882
4883        // TODO: Switch to user app stacks here.
4884        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4885                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4886                null, null, null, bOptions, false, userId, container, inTask);
4887        return ret;
4888    }
4889
4890    @Override
4891    public final int startActivities(IApplicationThread caller, String callingPackage,
4892            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4893            int userId) {
4894        enforceNotIsolatedCaller("startActivities");
4895        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4896                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4897        // TODO: Switch to user app stacks here.
4898        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4899                resolvedTypes, resultTo, bOptions, userId);
4900        return ret;
4901    }
4902
4903    final int startActivitiesInPackage(int uid, String callingPackage,
4904            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4905            Bundle bOptions, int userId) {
4906
4907        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4908                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4909        // TODO: Switch to user app stacks here.
4910        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4911                resultTo, bOptions, userId);
4912        return ret;
4913    }
4914
4915    @Override
4916    public void reportActivityFullyDrawn(IBinder token) {
4917        synchronized (this) {
4918            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4919            if (r == null) {
4920                return;
4921            }
4922            r.reportFullyDrawnLocked();
4923        }
4924    }
4925
4926    @Override
4927    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4928        synchronized (this) {
4929            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4930            if (r == null) {
4931                return;
4932            }
4933            final long origId = Binder.clearCallingIdentity();
4934            try {
4935                r.setRequestedOrientation(requestedOrientation);
4936            } finally {
4937                Binder.restoreCallingIdentity(origId);
4938            }
4939        }
4940    }
4941
4942    @Override
4943    public int getRequestedOrientation(IBinder token) {
4944        synchronized (this) {
4945            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4946            if (r == null) {
4947                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4948            }
4949            return r.getRequestedOrientation();
4950        }
4951    }
4952
4953    @Override
4954    public final void requestActivityRelaunch(IBinder token) {
4955        synchronized(this) {
4956            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4957            if (r == null) {
4958                return;
4959            }
4960            final long origId = Binder.clearCallingIdentity();
4961            try {
4962                r.forceNewConfig = true;
4963                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4964                        true /* preserveWindow */);
4965            } finally {
4966                Binder.restoreCallingIdentity(origId);
4967            }
4968        }
4969    }
4970
4971    /**
4972     * This is the internal entry point for handling Activity.finish().
4973     *
4974     * @param token The Binder token referencing the Activity we want to finish.
4975     * @param resultCode Result code, if any, from this Activity.
4976     * @param resultData Result data (Intent), if any, from this Activity.
4977     * @param finishTask Whether to finish the task associated with this Activity.
4978     *
4979     * @return Returns true if the activity successfully finished, or false if it is still running.
4980     */
4981    @Override
4982    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4983            int finishTask) {
4984        // Refuse possible leaked file descriptors
4985        if (resultData != null && resultData.hasFileDescriptors() == true) {
4986            throw new IllegalArgumentException("File descriptors passed in Intent");
4987        }
4988
4989        synchronized(this) {
4990            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4991            if (r == null) {
4992                return true;
4993            }
4994            // Keep track of the root activity of the task before we finish it
4995            TaskRecord tr = r.getTask();
4996            ActivityRecord rootR = tr.getRootActivity();
4997            if (rootR == null) {
4998                Slog.w(TAG, "Finishing task with all activities already finished");
4999            }
5000            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5001            // finish.
5002            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5003                    mStackSupervisor.isLastLockedTask(tr)) {
5004                Slog.i(TAG, "Not finishing task in lock task mode");
5005                mStackSupervisor.showLockTaskToast();
5006                return false;
5007            }
5008            if (mController != null) {
5009                // Find the first activity that is not finishing.
5010                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5011                if (next != null) {
5012                    // ask watcher if this is allowed
5013                    boolean resumeOK = true;
5014                    try {
5015                        resumeOK = mController.activityResuming(next.packageName);
5016                    } catch (RemoteException e) {
5017                        mController = null;
5018                        Watchdog.getInstance().setActivityController(null);
5019                    }
5020
5021                    if (!resumeOK) {
5022                        Slog.i(TAG, "Not finishing activity because controller resumed");
5023                        return false;
5024                    }
5025                }
5026            }
5027            final long origId = Binder.clearCallingIdentity();
5028            try {
5029                boolean res;
5030                final boolean finishWithRootActivity =
5031                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5032                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5033                        || (finishWithRootActivity && r == rootR)) {
5034                    // If requested, remove the task that is associated to this activity only if it
5035                    // was the root activity in the task. The result code and data is ignored
5036                    // because we don't support returning them across task boundaries. Also, to
5037                    // keep backwards compatibility we remove the task from recents when finishing
5038                    // task with root activity.
5039                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5040                    if (!res) {
5041                        Slog.i(TAG, "Removing task failed to finish activity");
5042                    }
5043                } else {
5044                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5045                            resultData, "app-request", true);
5046                    if (!res) {
5047                        Slog.i(TAG, "Failed to finish by app-request");
5048                    }
5049                }
5050                return res;
5051            } finally {
5052                Binder.restoreCallingIdentity(origId);
5053            }
5054        }
5055    }
5056
5057    @Override
5058    public final void finishHeavyWeightApp() {
5059        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5060                != PackageManager.PERMISSION_GRANTED) {
5061            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5062                    + Binder.getCallingPid()
5063                    + ", uid=" + Binder.getCallingUid()
5064                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5065            Slog.w(TAG, msg);
5066            throw new SecurityException(msg);
5067        }
5068
5069        synchronized(this) {
5070            if (mHeavyWeightProcess == null) {
5071                return;
5072            }
5073
5074            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5075            for (int i = 0; i < activities.size(); i++) {
5076                ActivityRecord r = activities.get(i);
5077                if (!r.finishing && r.isInStackLocked()) {
5078                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5079                            null, "finish-heavy", true);
5080                }
5081            }
5082
5083            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5084                    mHeavyWeightProcess.userId, 0));
5085            mHeavyWeightProcess = null;
5086        }
5087    }
5088
5089    @Override
5090    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5091            String message) {
5092        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5093                != PackageManager.PERMISSION_GRANTED) {
5094            String msg = "Permission Denial: crashApplication() from pid="
5095                    + Binder.getCallingPid()
5096                    + ", uid=" + Binder.getCallingUid()
5097                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5098            Slog.w(TAG, msg);
5099            throw new SecurityException(msg);
5100        }
5101
5102        synchronized(this) {
5103            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5104        }
5105    }
5106
5107    @Override
5108    public final void finishSubActivity(IBinder token, String resultWho,
5109            int requestCode) {
5110        synchronized(this) {
5111            final long origId = Binder.clearCallingIdentity();
5112            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5113            if (r != null) {
5114                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5115            }
5116            Binder.restoreCallingIdentity(origId);
5117        }
5118    }
5119
5120    @Override
5121    public boolean finishActivityAffinity(IBinder token) {
5122        synchronized(this) {
5123            final long origId = Binder.clearCallingIdentity();
5124            try {
5125                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5126                if (r == null) {
5127                    return false;
5128                }
5129
5130                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5131                // can finish.
5132                final TaskRecord task = r.getTask();
5133                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5134                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5135                    mStackSupervisor.showLockTaskToast();
5136                    return false;
5137                }
5138                return task.getStack().finishActivityAffinityLocked(r);
5139            } finally {
5140                Binder.restoreCallingIdentity(origId);
5141            }
5142        }
5143    }
5144
5145    @Override
5146    public void finishVoiceTask(IVoiceInteractionSession session) {
5147        synchronized (this) {
5148            final long origId = Binder.clearCallingIdentity();
5149            try {
5150                // TODO: VI Consider treating local voice interactions and voice tasks
5151                // differently here
5152                mStackSupervisor.finishVoiceTask(session);
5153            } finally {
5154                Binder.restoreCallingIdentity(origId);
5155            }
5156        }
5157
5158    }
5159
5160    @Override
5161    public boolean releaseActivityInstance(IBinder token) {
5162        synchronized(this) {
5163            final long origId = Binder.clearCallingIdentity();
5164            try {
5165                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5166                if (r == null) {
5167                    return false;
5168                }
5169                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5170            } finally {
5171                Binder.restoreCallingIdentity(origId);
5172            }
5173        }
5174    }
5175
5176    @Override
5177    public void releaseSomeActivities(IApplicationThread appInt) {
5178        synchronized(this) {
5179            final long origId = Binder.clearCallingIdentity();
5180            try {
5181                ProcessRecord app = getRecordForAppLocked(appInt);
5182                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5183            } finally {
5184                Binder.restoreCallingIdentity(origId);
5185            }
5186        }
5187    }
5188
5189    @Override
5190    public boolean willActivityBeVisible(IBinder token) {
5191        synchronized(this) {
5192            ActivityStack stack = ActivityRecord.getStackLocked(token);
5193            if (stack != null) {
5194                return stack.willActivityBeVisibleLocked(token);
5195            }
5196            return false;
5197        }
5198    }
5199
5200    @Override
5201    public void overridePendingTransition(IBinder token, String packageName,
5202            int enterAnim, int exitAnim) {
5203        synchronized(this) {
5204            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5205            if (self == null) {
5206                return;
5207            }
5208
5209            final long origId = Binder.clearCallingIdentity();
5210
5211            if (self.state == ActivityState.RESUMED
5212                    || self.state == ActivityState.PAUSING) {
5213                mWindowManager.overridePendingAppTransition(packageName,
5214                        enterAnim, exitAnim, null);
5215            }
5216
5217            Binder.restoreCallingIdentity(origId);
5218        }
5219    }
5220
5221    /**
5222     * Main function for removing an existing process from the activity manager
5223     * as a result of that process going away.  Clears out all connections
5224     * to the process.
5225     */
5226    private final void handleAppDiedLocked(ProcessRecord app,
5227            boolean restarting, boolean allowRestart) {
5228        int pid = app.pid;
5229        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5230                false /*replacingPid*/);
5231        if (!kept && !restarting) {
5232            removeLruProcessLocked(app);
5233            if (pid > 0) {
5234                ProcessList.remove(pid);
5235            }
5236        }
5237
5238        if (mProfileProc == app) {
5239            clearProfilerLocked();
5240        }
5241
5242        // Remove this application's activities from active lists.
5243        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5244
5245        app.activities.clear();
5246
5247        if (app.instr != null) {
5248            Slog.w(TAG, "Crash of app " + app.processName
5249                  + " running instrumentation " + app.instr.mClass);
5250            Bundle info = new Bundle();
5251            info.putString("shortMsg", "Process crashed.");
5252            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5253        }
5254
5255        mWindowManager.deferSurfaceLayout();
5256        try {
5257            if (!restarting && hasVisibleActivities
5258                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5259                // If there was nothing to resume, and we are not already restarting this process, but
5260                // there is a visible activity that is hosted by the process...  then make sure all
5261                // visible activities are running, taking care of restarting this process.
5262                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5263            }
5264        } finally {
5265            mWindowManager.continueSurfaceLayout();
5266        }
5267    }
5268
5269    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5270        final IBinder threadBinder = thread.asBinder();
5271        // Find the application record.
5272        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5273            final ProcessRecord rec = mLruProcesses.get(i);
5274            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5275                return i;
5276            }
5277        }
5278        return -1;
5279    }
5280
5281    final ProcessRecord getRecordForAppLocked(
5282            IApplicationThread thread) {
5283        if (thread == null) {
5284            return null;
5285        }
5286
5287        int appIndex = getLRURecordIndexForAppLocked(thread);
5288        if (appIndex >= 0) {
5289            return mLruProcesses.get(appIndex);
5290        }
5291
5292        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5293        // double-check that.
5294        final IBinder threadBinder = thread.asBinder();
5295        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5296        for (int i = pmap.size()-1; i >= 0; i--) {
5297            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5298            for (int j = procs.size()-1; j >= 0; j--) {
5299                final ProcessRecord proc = procs.valueAt(j);
5300                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5301                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5302                            + proc);
5303                    return proc;
5304                }
5305            }
5306        }
5307
5308        return null;
5309    }
5310
5311    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5312        // If there are no longer any background processes running,
5313        // and the app that died was not running instrumentation,
5314        // then tell everyone we are now low on memory.
5315        boolean haveBg = false;
5316        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5317            ProcessRecord rec = mLruProcesses.get(i);
5318            if (rec.thread != null
5319                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5320                haveBg = true;
5321                break;
5322            }
5323        }
5324
5325        if (!haveBg) {
5326            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5327            if (doReport) {
5328                long now = SystemClock.uptimeMillis();
5329                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5330                    doReport = false;
5331                } else {
5332                    mLastMemUsageReportTime = now;
5333                }
5334            }
5335            final ArrayList<ProcessMemInfo> memInfos
5336                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5337            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5338            long now = SystemClock.uptimeMillis();
5339            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5340                ProcessRecord rec = mLruProcesses.get(i);
5341                if (rec == dyingProc || rec.thread == null) {
5342                    continue;
5343                }
5344                if (doReport) {
5345                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5346                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5347                }
5348                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5349                    // The low memory report is overriding any current
5350                    // state for a GC request.  Make sure to do
5351                    // heavy/important/visible/foreground processes first.
5352                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5353                        rec.lastRequestedGc = 0;
5354                    } else {
5355                        rec.lastRequestedGc = rec.lastLowMemory;
5356                    }
5357                    rec.reportLowMemory = true;
5358                    rec.lastLowMemory = now;
5359                    mProcessesToGc.remove(rec);
5360                    addProcessToGcListLocked(rec);
5361                }
5362            }
5363            if (doReport) {
5364                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5365                mHandler.sendMessage(msg);
5366            }
5367            scheduleAppGcsLocked();
5368        }
5369    }
5370
5371    final void appDiedLocked(ProcessRecord app) {
5372       appDiedLocked(app, app.pid, app.thread, false);
5373    }
5374
5375    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5376            boolean fromBinderDied) {
5377        // First check if this ProcessRecord is actually active for the pid.
5378        synchronized (mPidsSelfLocked) {
5379            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5380            if (curProc != app) {
5381                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5382                return;
5383            }
5384        }
5385
5386        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5387        synchronized (stats) {
5388            stats.noteProcessDiedLocked(app.info.uid, pid);
5389        }
5390
5391        if (!app.killed) {
5392            if (!fromBinderDied) {
5393                killProcessQuiet(pid);
5394            }
5395            killProcessGroup(app.uid, pid);
5396            app.killed = true;
5397        }
5398
5399        // Clean up already done if the process has been re-started.
5400        if (app.pid == pid && app.thread != null &&
5401                app.thread.asBinder() == thread.asBinder()) {
5402            boolean doLowMem = app.instr == null;
5403            boolean doOomAdj = doLowMem;
5404            if (!app.killedByAm) {
5405                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5406                        + ") has died");
5407                mAllowLowerMemLevel = true;
5408            } else {
5409                // Note that we always want to do oom adj to update our state with the
5410                // new number of procs.
5411                mAllowLowerMemLevel = false;
5412                doLowMem = false;
5413            }
5414            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5415            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5416                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5417            handleAppDiedLocked(app, false, true);
5418
5419            if (doOomAdj) {
5420                updateOomAdjLocked();
5421            }
5422            if (doLowMem) {
5423                doLowMemReportIfNeededLocked(app);
5424            }
5425        } else if (app.pid != pid) {
5426            // A new process has already been started.
5427            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5428                    + ") has died and restarted (pid " + app.pid + ").");
5429            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5430        } else if (DEBUG_PROCESSES) {
5431            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5432                    + thread.asBinder());
5433        }
5434    }
5435
5436    /**
5437     * If a stack trace dump file is configured, dump process stack traces.
5438     * @param clearTraces causes the dump file to be erased prior to the new
5439     *    traces being written, if true; when false, the new traces will be
5440     *    appended to any existing file content.
5441     * @param firstPids of dalvik VM processes to dump stack traces for first
5442     * @param lastPids of dalvik VM processes to dump stack traces for last
5443     * @param nativePids optional list of native pids to dump stack crawls
5444     * @return file containing stack traces, or null if no dump file is configured
5445     */
5446    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5447            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5448            ArrayList<Integer> nativePids) {
5449        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5450        if (tracesPath == null || tracesPath.length() == 0) {
5451            return null;
5452        }
5453
5454        File tracesFile = new File(tracesPath);
5455        try {
5456            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5457            tracesFile.createNewFile();
5458            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5459        } catch (IOException e) {
5460            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5461            return null;
5462        }
5463
5464        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativePids);
5465        return tracesFile;
5466    }
5467
5468    public static class DumpStackFileObserver extends FileObserver {
5469        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5470        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5471        static final int TRACE_DUMP_TIMEOUT_SECONDS = TRACE_DUMP_TIMEOUT_MS / 1000;
5472
5473        private final String mTracesPath;
5474        private boolean mClosed;
5475
5476        public DumpStackFileObserver(String tracesPath) {
5477            super(tracesPath, FileObserver.CLOSE_WRITE);
5478            mTracesPath = tracesPath;
5479        }
5480
5481        @Override
5482        public synchronized void onEvent(int event, String path) {
5483            mClosed = true;
5484            notify();
5485        }
5486
5487        public void dumpWithTimeout(int pid) {
5488            sendSignal(pid, SIGNAL_QUIT);
5489            synchronized (this) {
5490                try {
5491                    wait(TRACE_DUMP_TIMEOUT_MS); // Wait for traces file to be closed.
5492                } catch (InterruptedException e) {
5493                    Slog.wtf(TAG, e);
5494                }
5495            }
5496            if (!mClosed) {
5497                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5498                       ". Attempting native stack collection.");
5499                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath, TRACE_DUMP_TIMEOUT_SECONDS);
5500            }
5501            mClosed = false;
5502        }
5503    }
5504
5505    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5506            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5507            ArrayList<Integer> nativePids) {
5508        // Use a FileObserver to detect when traces finish writing.
5509        // The order of traces is considered important to maintain for legibility.
5510        DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
5511        try {
5512            observer.startWatching();
5513
5514            // First collect all of the stacks of the most important pids.
5515            if (firstPids != null) {
5516                int num = firstPids.size();
5517                for (int i = 0; i < num; i++) {
5518                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5519                            + firstPids.get(i));
5520                    final long sime = SystemClock.elapsedRealtime();
5521                    observer.dumpWithTimeout(firstPids.get(i));
5522                    if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5523                            + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5524                }
5525            }
5526
5527            // Next collect the stacks of the native pids
5528            if (nativePids != null) {
5529                for (int pid : nativePids) {
5530                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5531                    final long sime = SystemClock.elapsedRealtime();
5532
5533                    Debug.dumpNativeBacktraceToFileTimeout(
5534                            pid, tracesPath, DumpStackFileObserver.TRACE_DUMP_TIMEOUT_SECONDS);
5535                    if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5536                            + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5537                }
5538            }
5539
5540            // Lastly, measure CPU usage.
5541            if (processCpuTracker != null) {
5542                processCpuTracker.init();
5543                System.gc();
5544                processCpuTracker.update();
5545                try {
5546                    synchronized (processCpuTracker) {
5547                        processCpuTracker.wait(500); // measure over 1/2 second.
5548                    }
5549                } catch (InterruptedException e) {
5550                }
5551                processCpuTracker.update();
5552
5553                // We'll take the stack crawls of just the top apps using CPU.
5554                final int N = processCpuTracker.countWorkingStats();
5555                int numProcs = 0;
5556                for (int i=0; i<N && numProcs<5; i++) {
5557                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5558                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5559                        numProcs++;
5560                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5561                                + stats.pid);
5562                        final long stime = SystemClock.elapsedRealtime();
5563                        observer.dumpWithTimeout(stats.pid);
5564                        if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5565                                + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5566                    } else if (DEBUG_ANR) {
5567                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5568                                + stats.pid);
5569                    }
5570                }
5571            }
5572        } finally {
5573            observer.stopWatching();
5574        }
5575    }
5576
5577    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5578        if (true || IS_USER_BUILD) {
5579            return;
5580        }
5581        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5582        if (tracesPath == null || tracesPath.length() == 0) {
5583            return;
5584        }
5585
5586        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5587        StrictMode.allowThreadDiskWrites();
5588        try {
5589            final File tracesFile = new File(tracesPath);
5590            final File tracesDir = tracesFile.getParentFile();
5591            final File tracesTmp = new File(tracesDir, "__tmp__");
5592            try {
5593                if (tracesFile.exists()) {
5594                    tracesTmp.delete();
5595                    tracesFile.renameTo(tracesTmp);
5596                }
5597                StringBuilder sb = new StringBuilder();
5598                Time tobj = new Time();
5599                tobj.set(System.currentTimeMillis());
5600                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5601                sb.append(": ");
5602                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5603                sb.append(" since ");
5604                sb.append(msg);
5605                FileOutputStream fos = new FileOutputStream(tracesFile);
5606                fos.write(sb.toString().getBytes());
5607                if (app == null) {
5608                    fos.write("\n*** No application process!".getBytes());
5609                }
5610                fos.close();
5611                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5612            } catch (IOException e) {
5613                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5614                return;
5615            }
5616
5617            if (app != null) {
5618                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5619                firstPids.add(app.pid);
5620                dumpStackTraces(tracesPath, firstPids, null, null, null);
5621            }
5622
5623            File lastTracesFile = null;
5624            File curTracesFile = null;
5625            for (int i=9; i>=0; i--) {
5626                String name = String.format(Locale.US, "slow%02d.txt", i);
5627                curTracesFile = new File(tracesDir, name);
5628                if (curTracesFile.exists()) {
5629                    if (lastTracesFile != null) {
5630                        curTracesFile.renameTo(lastTracesFile);
5631                    } else {
5632                        curTracesFile.delete();
5633                    }
5634                }
5635                lastTracesFile = curTracesFile;
5636            }
5637            tracesFile.renameTo(curTracesFile);
5638            if (tracesTmp.exists()) {
5639                tracesTmp.renameTo(tracesFile);
5640            }
5641        } finally {
5642            StrictMode.setThreadPolicy(oldPolicy);
5643        }
5644    }
5645
5646    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5647        if (!mLaunchWarningShown) {
5648            mLaunchWarningShown = true;
5649            mUiHandler.post(new Runnable() {
5650                @Override
5651                public void run() {
5652                    synchronized (ActivityManagerService.this) {
5653                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5654                        d.show();
5655                        mUiHandler.postDelayed(new Runnable() {
5656                            @Override
5657                            public void run() {
5658                                synchronized (ActivityManagerService.this) {
5659                                    d.dismiss();
5660                                    mLaunchWarningShown = false;
5661                                }
5662                            }
5663                        }, 4000);
5664                    }
5665                }
5666            });
5667        }
5668    }
5669
5670    @Override
5671    public boolean clearApplicationUserData(final String packageName,
5672            final IPackageDataObserver observer, int userId) {
5673        enforceNotIsolatedCaller("clearApplicationUserData");
5674        int uid = Binder.getCallingUid();
5675        int pid = Binder.getCallingPid();
5676        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5677                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5678
5679
5680        long callingId = Binder.clearCallingIdentity();
5681        try {
5682            IPackageManager pm = AppGlobals.getPackageManager();
5683            int pkgUid = -1;
5684            synchronized(this) {
5685                if (getPackageManagerInternalLocked().isPackageDataProtected(
5686                        userId, packageName)) {
5687                    throw new SecurityException(
5688                            "Cannot clear data for a protected package: " + packageName);
5689                }
5690
5691                try {
5692                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5693                } catch (RemoteException e) {
5694                }
5695                if (pkgUid == -1) {
5696                    Slog.w(TAG, "Invalid packageName: " + packageName);
5697                    if (observer != null) {
5698                        try {
5699                            observer.onRemoveCompleted(packageName, false);
5700                        } catch (RemoteException e) {
5701                            Slog.i(TAG, "Observer no longer exists.");
5702                        }
5703                    }
5704                    return false;
5705                }
5706                if (uid == pkgUid || checkComponentPermission(
5707                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5708                        pid, uid, -1, true)
5709                        == PackageManager.PERMISSION_GRANTED) {
5710                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5711                } else {
5712                    throw new SecurityException("PID " + pid + " does not have permission "
5713                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5714                                    + " of package " + packageName);
5715                }
5716
5717                // Remove all tasks match the cleared application package and user
5718                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5719                    final TaskRecord tr = mRecentTasks.get(i);
5720                    final String taskPackageName =
5721                            tr.getBaseIntent().getComponent().getPackageName();
5722                    if (tr.userId != userId) continue;
5723                    if (!taskPackageName.equals(packageName)) continue;
5724                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5725                }
5726            }
5727
5728            final int pkgUidF = pkgUid;
5729            final int userIdF = userId;
5730            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5731                @Override
5732                public void onRemoveCompleted(String packageName, boolean succeeded)
5733                        throws RemoteException {
5734                    synchronized (ActivityManagerService.this) {
5735                        finishForceStopPackageLocked(packageName, pkgUidF);
5736                    }
5737
5738                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5739                            Uri.fromParts("package", packageName, null));
5740                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5741                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5742                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5743                    broadcastIntentInPackage("android", SYSTEM_UID, intent,
5744                            null, null, 0, null, null, null, null, false, false, userIdF);
5745
5746                    if (observer != null) {
5747                        observer.onRemoveCompleted(packageName, succeeded);
5748                    }
5749                }
5750            };
5751
5752            try {
5753                // Clear application user data
5754                pm.clearApplicationUserData(packageName, localObserver, userId);
5755
5756                synchronized(this) {
5757                    // Remove all permissions granted from/to this package
5758                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5759                }
5760
5761                // Reset notification settings.
5762                INotificationManager inm = NotificationManager.getService();
5763                inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5764            } catch (RemoteException e) {
5765            }
5766        } finally {
5767            Binder.restoreCallingIdentity(callingId);
5768        }
5769        return true;
5770    }
5771
5772    @Override
5773    public void killBackgroundProcesses(final String packageName, int userId) {
5774        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5775                != PackageManager.PERMISSION_GRANTED &&
5776                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5777                        != PackageManager.PERMISSION_GRANTED) {
5778            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5779                    + Binder.getCallingPid()
5780                    + ", uid=" + Binder.getCallingUid()
5781                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5782            Slog.w(TAG, msg);
5783            throw new SecurityException(msg);
5784        }
5785
5786        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5787                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5788        long callingId = Binder.clearCallingIdentity();
5789        try {
5790            IPackageManager pm = AppGlobals.getPackageManager();
5791            synchronized(this) {
5792                int appId = -1;
5793                try {
5794                    appId = UserHandle.getAppId(
5795                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5796                } catch (RemoteException e) {
5797                }
5798                if (appId == -1) {
5799                    Slog.w(TAG, "Invalid packageName: " + packageName);
5800                    return;
5801                }
5802                killPackageProcessesLocked(packageName, appId, userId,
5803                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5804            }
5805        } finally {
5806            Binder.restoreCallingIdentity(callingId);
5807        }
5808    }
5809
5810    @Override
5811    public void killAllBackgroundProcesses() {
5812        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5813                != PackageManager.PERMISSION_GRANTED) {
5814            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5815                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5816                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5817            Slog.w(TAG, msg);
5818            throw new SecurityException(msg);
5819        }
5820
5821        final long callingId = Binder.clearCallingIdentity();
5822        try {
5823            synchronized (this) {
5824                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5825                final int NP = mProcessNames.getMap().size();
5826                for (int ip = 0; ip < NP; ip++) {
5827                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5828                    final int NA = apps.size();
5829                    for (int ia = 0; ia < NA; ia++) {
5830                        final ProcessRecord app = apps.valueAt(ia);
5831                        if (app.persistent) {
5832                            // We don't kill persistent processes.
5833                            continue;
5834                        }
5835                        if (app.removed) {
5836                            procs.add(app);
5837                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5838                            app.removed = true;
5839                            procs.add(app);
5840                        }
5841                    }
5842                }
5843
5844                final int N = procs.size();
5845                for (int i = 0; i < N; i++) {
5846                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5847                }
5848
5849                mAllowLowerMemLevel = true;
5850
5851                updateOomAdjLocked();
5852                doLowMemReportIfNeededLocked(null);
5853            }
5854        } finally {
5855            Binder.restoreCallingIdentity(callingId);
5856        }
5857    }
5858
5859    /**
5860     * Kills all background processes, except those matching any of the
5861     * specified properties.
5862     *
5863     * @param minTargetSdk the target SDK version at or above which to preserve
5864     *                     processes, or {@code -1} to ignore the target SDK
5865     * @param maxProcState the process state at or below which to preserve
5866     *                     processes, or {@code -1} to ignore the process state
5867     */
5868    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5869        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5870                != PackageManager.PERMISSION_GRANTED) {
5871            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5872                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5873                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5874            Slog.w(TAG, msg);
5875            throw new SecurityException(msg);
5876        }
5877
5878        final long callingId = Binder.clearCallingIdentity();
5879        try {
5880            synchronized (this) {
5881                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5882                final int NP = mProcessNames.getMap().size();
5883                for (int ip = 0; ip < NP; ip++) {
5884                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5885                    final int NA = apps.size();
5886                    for (int ia = 0; ia < NA; ia++) {
5887                        final ProcessRecord app = apps.valueAt(ia);
5888                        if (app.removed) {
5889                            procs.add(app);
5890                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5891                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5892                            app.removed = true;
5893                            procs.add(app);
5894                        }
5895                    }
5896                }
5897
5898                final int N = procs.size();
5899                for (int i = 0; i < N; i++) {
5900                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5901                }
5902            }
5903        } finally {
5904            Binder.restoreCallingIdentity(callingId);
5905        }
5906    }
5907
5908    @Override
5909    public void forceStopPackage(final String packageName, int userId) {
5910        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5911                != PackageManager.PERMISSION_GRANTED) {
5912            String msg = "Permission Denial: forceStopPackage() from pid="
5913                    + Binder.getCallingPid()
5914                    + ", uid=" + Binder.getCallingUid()
5915                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5916            Slog.w(TAG, msg);
5917            throw new SecurityException(msg);
5918        }
5919        final int callingPid = Binder.getCallingPid();
5920        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5921                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5922        long callingId = Binder.clearCallingIdentity();
5923        try {
5924            IPackageManager pm = AppGlobals.getPackageManager();
5925            synchronized(this) {
5926                int[] users = userId == UserHandle.USER_ALL
5927                        ? mUserController.getUsers() : new int[] { userId };
5928                for (int user : users) {
5929                    int pkgUid = -1;
5930                    try {
5931                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5932                                user);
5933                    } catch (RemoteException e) {
5934                    }
5935                    if (pkgUid == -1) {
5936                        Slog.w(TAG, "Invalid packageName: " + packageName);
5937                        continue;
5938                    }
5939                    try {
5940                        pm.setPackageStoppedState(packageName, true, user);
5941                    } catch (RemoteException e) {
5942                    } catch (IllegalArgumentException e) {
5943                        Slog.w(TAG, "Failed trying to unstop package "
5944                                + packageName + ": " + e);
5945                    }
5946                    if (mUserController.isUserRunningLocked(user, 0)) {
5947                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5948                        finishForceStopPackageLocked(packageName, pkgUid);
5949                    }
5950                }
5951            }
5952        } finally {
5953            Binder.restoreCallingIdentity(callingId);
5954        }
5955    }
5956
5957    @Override
5958    public void addPackageDependency(String packageName) {
5959        synchronized (this) {
5960            int callingPid = Binder.getCallingPid();
5961            if (callingPid == myPid()) {
5962                //  Yeah, um, no.
5963                return;
5964            }
5965            ProcessRecord proc;
5966            synchronized (mPidsSelfLocked) {
5967                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5968            }
5969            if (proc != null) {
5970                if (proc.pkgDeps == null) {
5971                    proc.pkgDeps = new ArraySet<String>(1);
5972                }
5973                proc.pkgDeps.add(packageName);
5974            }
5975        }
5976    }
5977
5978    /*
5979     * The pkg name and app id have to be specified.
5980     */
5981    @Override
5982    public void killApplication(String pkg, int appId, int userId, String reason) {
5983        if (pkg == null) {
5984            return;
5985        }
5986        // Make sure the uid is valid.
5987        if (appId < 0) {
5988            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5989            return;
5990        }
5991        int callerUid = Binder.getCallingUid();
5992        // Only the system server can kill an application
5993        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
5994            // Post an aysnc message to kill the application
5995            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5996            msg.arg1 = appId;
5997            msg.arg2 = userId;
5998            Bundle bundle = new Bundle();
5999            bundle.putString("pkg", pkg);
6000            bundle.putString("reason", reason);
6001            msg.obj = bundle;
6002            mHandler.sendMessage(msg);
6003        } else {
6004            throw new SecurityException(callerUid + " cannot kill pkg: " +
6005                    pkg);
6006        }
6007    }
6008
6009    @Override
6010    public void closeSystemDialogs(String reason) {
6011        enforceNotIsolatedCaller("closeSystemDialogs");
6012
6013        final int pid = Binder.getCallingPid();
6014        final int uid = Binder.getCallingUid();
6015        final long origId = Binder.clearCallingIdentity();
6016        try {
6017            synchronized (this) {
6018                // Only allow this from foreground processes, so that background
6019                // applications can't abuse it to prevent system UI from being shown.
6020                if (uid >= FIRST_APPLICATION_UID) {
6021                    ProcessRecord proc;
6022                    synchronized (mPidsSelfLocked) {
6023                        proc = mPidsSelfLocked.get(pid);
6024                    }
6025                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6026                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6027                                + " from background process " + proc);
6028                        return;
6029                    }
6030                }
6031                closeSystemDialogsLocked(reason);
6032            }
6033        } finally {
6034            Binder.restoreCallingIdentity(origId);
6035        }
6036    }
6037
6038    void closeSystemDialogsLocked(String reason) {
6039        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6040        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6041                | Intent.FLAG_RECEIVER_FOREGROUND);
6042        if (reason != null) {
6043            intent.putExtra("reason", reason);
6044        }
6045        mWindowManager.closeSystemDialogs(reason);
6046
6047        mStackSupervisor.closeSystemDialogsLocked();
6048
6049        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6050                AppOpsManager.OP_NONE, null, false, false,
6051                -1, SYSTEM_UID, UserHandle.USER_ALL);
6052    }
6053
6054    @Override
6055    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6056        enforceNotIsolatedCaller("getProcessMemoryInfo");
6057        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6058        for (int i=pids.length-1; i>=0; i--) {
6059            ProcessRecord proc;
6060            int oomAdj;
6061            synchronized (this) {
6062                synchronized (mPidsSelfLocked) {
6063                    proc = mPidsSelfLocked.get(pids[i]);
6064                    oomAdj = proc != null ? proc.setAdj : 0;
6065                }
6066            }
6067            infos[i] = new Debug.MemoryInfo();
6068            Debug.getMemoryInfo(pids[i], infos[i]);
6069            if (proc != null) {
6070                synchronized (this) {
6071                    if (proc.thread != null && proc.setAdj == oomAdj) {
6072                        // Record this for posterity if the process has been stable.
6073                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6074                                infos[i].getTotalUss(), false, proc.pkgList);
6075                    }
6076                }
6077            }
6078        }
6079        return infos;
6080    }
6081
6082    @Override
6083    public long[] getProcessPss(int[] pids) {
6084        enforceNotIsolatedCaller("getProcessPss");
6085        long[] pss = new long[pids.length];
6086        for (int i=pids.length-1; i>=0; i--) {
6087            ProcessRecord proc;
6088            int oomAdj;
6089            synchronized (this) {
6090                synchronized (mPidsSelfLocked) {
6091                    proc = mPidsSelfLocked.get(pids[i]);
6092                    oomAdj = proc != null ? proc.setAdj : 0;
6093                }
6094            }
6095            long[] tmpUss = new long[1];
6096            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6097            if (proc != null) {
6098                synchronized (this) {
6099                    if (proc.thread != null && proc.setAdj == oomAdj) {
6100                        // Record this for posterity if the process has been stable.
6101                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6102                    }
6103                }
6104            }
6105        }
6106        return pss;
6107    }
6108
6109    @Override
6110    public void killApplicationProcess(String processName, int uid) {
6111        if (processName == null) {
6112            return;
6113        }
6114
6115        int callerUid = Binder.getCallingUid();
6116        // Only the system server can kill an application
6117        if (callerUid == SYSTEM_UID) {
6118            synchronized (this) {
6119                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6120                if (app != null && app.thread != null) {
6121                    try {
6122                        app.thread.scheduleSuicide();
6123                    } catch (RemoteException e) {
6124                        // If the other end already died, then our work here is done.
6125                    }
6126                } else {
6127                    Slog.w(TAG, "Process/uid not found attempting kill of "
6128                            + processName + " / " + uid);
6129                }
6130            }
6131        } else {
6132            throw new SecurityException(callerUid + " cannot kill app process: " +
6133                    processName);
6134        }
6135    }
6136
6137    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6138        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6139                false, true, false, false, UserHandle.getUserId(uid), reason);
6140    }
6141
6142    private void finishForceStopPackageLocked(final String packageName, int uid) {
6143        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6144                Uri.fromParts("package", packageName, null));
6145        if (!mProcessesReady) {
6146            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6147                    | Intent.FLAG_RECEIVER_FOREGROUND);
6148        }
6149        intent.putExtra(Intent.EXTRA_UID, uid);
6150        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6151        broadcastIntentLocked(null, null, intent,
6152                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6153                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6154    }
6155
6156
6157    private final boolean killPackageProcessesLocked(String packageName, int appId,
6158            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6159            boolean doit, boolean evenPersistent, String reason) {
6160        ArrayList<ProcessRecord> procs = new ArrayList<>();
6161
6162        // Remove all processes this package may have touched: all with the
6163        // same UID (except for the system or root user), and all whose name
6164        // matches the package name.
6165        final int NP = mProcessNames.getMap().size();
6166        for (int ip=0; ip<NP; ip++) {
6167            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6168            final int NA = apps.size();
6169            for (int ia=0; ia<NA; ia++) {
6170                ProcessRecord app = apps.valueAt(ia);
6171                if (app.persistent && !evenPersistent) {
6172                    // we don't kill persistent processes
6173                    continue;
6174                }
6175                if (app.removed) {
6176                    if (doit) {
6177                        procs.add(app);
6178                    }
6179                    continue;
6180                }
6181
6182                // Skip process if it doesn't meet our oom adj requirement.
6183                if (app.setAdj < minOomAdj) {
6184                    continue;
6185                }
6186
6187                // If no package is specified, we call all processes under the
6188                // give user id.
6189                if (packageName == null) {
6190                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6191                        continue;
6192                    }
6193                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6194                        continue;
6195                    }
6196                // Package has been specified, we want to hit all processes
6197                // that match it.  We need to qualify this by the processes
6198                // that are running under the specified app and user ID.
6199                } else {
6200                    final boolean isDep = app.pkgDeps != null
6201                            && app.pkgDeps.contains(packageName);
6202                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6203                        continue;
6204                    }
6205                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6206                        continue;
6207                    }
6208                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6209                        continue;
6210                    }
6211                }
6212
6213                // Process has passed all conditions, kill it!
6214                if (!doit) {
6215                    return true;
6216                }
6217                app.removed = true;
6218                procs.add(app);
6219            }
6220        }
6221
6222        int N = procs.size();
6223        for (int i=0; i<N; i++) {
6224            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6225        }
6226        updateOomAdjLocked();
6227        return N > 0;
6228    }
6229
6230    private void cleanupDisabledPackageComponentsLocked(
6231            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6232
6233        Set<String> disabledClasses = null;
6234        boolean packageDisabled = false;
6235        IPackageManager pm = AppGlobals.getPackageManager();
6236
6237        if (changedClasses == null) {
6238            // Nothing changed...
6239            return;
6240        }
6241
6242        // Determine enable/disable state of the package and its components.
6243        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6244        for (int i = changedClasses.length - 1; i >= 0; i--) {
6245            final String changedClass = changedClasses[i];
6246
6247            if (changedClass.equals(packageName)) {
6248                try {
6249                    // Entire package setting changed
6250                    enabled = pm.getApplicationEnabledSetting(packageName,
6251                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6252                } catch (Exception e) {
6253                    // No such package/component; probably racing with uninstall.  In any
6254                    // event it means we have nothing further to do here.
6255                    return;
6256                }
6257                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6258                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6259                if (packageDisabled) {
6260                    // Entire package is disabled.
6261                    // No need to continue to check component states.
6262                    disabledClasses = null;
6263                    break;
6264                }
6265            } else {
6266                try {
6267                    enabled = pm.getComponentEnabledSetting(
6268                            new ComponentName(packageName, changedClass),
6269                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6270                } catch (Exception e) {
6271                    // As above, probably racing with uninstall.
6272                    return;
6273                }
6274                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6275                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6276                    if (disabledClasses == null) {
6277                        disabledClasses = new ArraySet<>(changedClasses.length);
6278                    }
6279                    disabledClasses.add(changedClass);
6280                }
6281            }
6282        }
6283
6284        if (!packageDisabled && disabledClasses == null) {
6285            // Nothing to do here...
6286            return;
6287        }
6288
6289        // Clean-up disabled activities.
6290        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6291                packageName, disabledClasses, true, false, userId) && mBooted) {
6292            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6293            mStackSupervisor.scheduleIdleLocked();
6294        }
6295
6296        // Clean-up disabled tasks
6297        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6298
6299        // Clean-up disabled services.
6300        mServices.bringDownDisabledPackageServicesLocked(
6301                packageName, disabledClasses, userId, false, killProcess, true);
6302
6303        // Clean-up disabled providers.
6304        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6305        mProviderMap.collectPackageProvidersLocked(
6306                packageName, disabledClasses, true, false, userId, providers);
6307        for (int i = providers.size() - 1; i >= 0; i--) {
6308            removeDyingProviderLocked(null, providers.get(i), true);
6309        }
6310
6311        // Clean-up disabled broadcast receivers.
6312        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6313            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6314                    packageName, disabledClasses, userId, true);
6315        }
6316
6317    }
6318
6319    final boolean clearBroadcastQueueForUserLocked(int userId) {
6320        boolean didSomething = false;
6321        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6322            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6323                    null, null, userId, true);
6324        }
6325        return didSomething;
6326    }
6327
6328    final boolean forceStopPackageLocked(String packageName, int appId,
6329            boolean callerWillRestart, boolean purgeCache, boolean doit,
6330            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6331        int i;
6332
6333        if (userId == UserHandle.USER_ALL && packageName == null) {
6334            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6335        }
6336
6337        if (appId < 0 && packageName != null) {
6338            try {
6339                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6340                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6341            } catch (RemoteException e) {
6342            }
6343        }
6344
6345        if (doit) {
6346            if (packageName != null) {
6347                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6348                        + " user=" + userId + ": " + reason);
6349            } else {
6350                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6351            }
6352
6353            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6354        }
6355
6356        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6357                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6358                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6359
6360        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6361
6362        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6363                packageName, null, doit, evenPersistent, userId)) {
6364            if (!doit) {
6365                return true;
6366            }
6367            didSomething = true;
6368        }
6369
6370        if (mServices.bringDownDisabledPackageServicesLocked(
6371                packageName, null, userId, evenPersistent, true, doit)) {
6372            if (!doit) {
6373                return true;
6374            }
6375            didSomething = true;
6376        }
6377
6378        if (packageName == null) {
6379            // Remove all sticky broadcasts from this user.
6380            mStickyBroadcasts.remove(userId);
6381        }
6382
6383        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6384        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6385                userId, providers)) {
6386            if (!doit) {
6387                return true;
6388            }
6389            didSomething = true;
6390        }
6391        for (i = providers.size() - 1; i >= 0; i--) {
6392            removeDyingProviderLocked(null, providers.get(i), true);
6393        }
6394
6395        // Remove transient permissions granted from/to this package/user
6396        removeUriPermissionsForPackageLocked(packageName, userId, false);
6397
6398        if (doit) {
6399            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6400                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6401                        packageName, null, userId, doit);
6402            }
6403        }
6404
6405        if (packageName == null || uninstalling) {
6406            // Remove pending intents.  For now we only do this when force
6407            // stopping users, because we have some problems when doing this
6408            // for packages -- app widgets are not currently cleaned up for
6409            // such packages, so they can be left with bad pending intents.
6410            if (mIntentSenderRecords.size() > 0) {
6411                Iterator<WeakReference<PendingIntentRecord>> it
6412                        = mIntentSenderRecords.values().iterator();
6413                while (it.hasNext()) {
6414                    WeakReference<PendingIntentRecord> wpir = it.next();
6415                    if (wpir == null) {
6416                        it.remove();
6417                        continue;
6418                    }
6419                    PendingIntentRecord pir = wpir.get();
6420                    if (pir == null) {
6421                        it.remove();
6422                        continue;
6423                    }
6424                    if (packageName == null) {
6425                        // Stopping user, remove all objects for the user.
6426                        if (pir.key.userId != userId) {
6427                            // Not the same user, skip it.
6428                            continue;
6429                        }
6430                    } else {
6431                        if (UserHandle.getAppId(pir.uid) != appId) {
6432                            // Different app id, skip it.
6433                            continue;
6434                        }
6435                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6436                            // Different user, skip it.
6437                            continue;
6438                        }
6439                        if (!pir.key.packageName.equals(packageName)) {
6440                            // Different package, skip it.
6441                            continue;
6442                        }
6443                    }
6444                    if (!doit) {
6445                        return true;
6446                    }
6447                    didSomething = true;
6448                    it.remove();
6449                    makeIntentSenderCanceledLocked(pir);
6450                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6451                        pir.key.activity.pendingResults.remove(pir.ref);
6452                    }
6453                }
6454            }
6455        }
6456
6457        if (doit) {
6458            if (purgeCache && packageName != null) {
6459                AttributeCache ac = AttributeCache.instance();
6460                if (ac != null) {
6461                    ac.removePackage(packageName);
6462                }
6463            }
6464            if (mBooted) {
6465                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6466                mStackSupervisor.scheduleIdleLocked();
6467            }
6468        }
6469
6470        return didSomething;
6471    }
6472
6473    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6474        return removeProcessNameLocked(name, uid, null);
6475    }
6476
6477    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6478            final ProcessRecord expecting) {
6479        ProcessRecord old = mProcessNames.get(name, uid);
6480        // Only actually remove when the currently recorded value matches the
6481        // record that we expected; if it doesn't match then we raced with a
6482        // newly created process and we don't want to destroy the new one.
6483        if ((expecting == null) || (old == expecting)) {
6484            mProcessNames.remove(name, uid);
6485        }
6486        if (old != null && old.uidRecord != null) {
6487            old.uidRecord.numProcs--;
6488            if (old.uidRecord.numProcs == 0) {
6489                // No more processes using this uid, tell clients it is gone.
6490                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6491                        "No more processes in " + old.uidRecord);
6492                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6493                mActiveUids.remove(uid);
6494                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6495            }
6496            old.uidRecord = null;
6497        }
6498        mIsolatedProcesses.remove(uid);
6499        return old;
6500    }
6501
6502    private final void addProcessNameLocked(ProcessRecord proc) {
6503        // We shouldn't already have a process under this name, but just in case we
6504        // need to clean up whatever may be there now.
6505        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6506        if (old == proc && proc.persistent) {
6507            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6508            Slog.w(TAG, "Re-adding persistent process " + proc);
6509        } else if (old != null) {
6510            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6511        }
6512        UidRecord uidRec = mActiveUids.get(proc.uid);
6513        if (uidRec == null) {
6514            uidRec = new UidRecord(proc.uid);
6515            // This is the first appearance of the uid, report it now!
6516            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6517                    "Creating new process uid: " + uidRec);
6518            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6519                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6520                uidRec.setWhitelist = uidRec.curWhitelist = true;
6521            }
6522            uidRec.updateHasInternetPermission();
6523            mActiveUids.put(proc.uid, uidRec);
6524            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6525            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6526        }
6527        proc.uidRecord = uidRec;
6528
6529        // Reset render thread tid if it was already set, so new process can set it again.
6530        proc.renderThreadTid = 0;
6531        uidRec.numProcs++;
6532        mProcessNames.put(proc.processName, proc.uid, proc);
6533        if (proc.isolated) {
6534            mIsolatedProcesses.put(proc.uid, proc);
6535        }
6536    }
6537
6538    boolean removeProcessLocked(ProcessRecord app,
6539            boolean callerWillRestart, boolean allowRestart, String reason) {
6540        final String name = app.processName;
6541        final int uid = app.uid;
6542        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6543            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6544
6545        ProcessRecord old = mProcessNames.get(name, uid);
6546        if (old != app) {
6547            // This process is no longer active, so nothing to do.
6548            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6549            return false;
6550        }
6551        removeProcessNameLocked(name, uid);
6552        if (mHeavyWeightProcess == app) {
6553            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6554                    mHeavyWeightProcess.userId, 0));
6555            mHeavyWeightProcess = null;
6556        }
6557        boolean needRestart = false;
6558        if (app.pid > 0 && app.pid != MY_PID) {
6559            int pid = app.pid;
6560            synchronized (mPidsSelfLocked) {
6561                mPidsSelfLocked.remove(pid);
6562                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6563            }
6564            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6565            if (app.isolated) {
6566                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6567                getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6568            }
6569            boolean willRestart = false;
6570            if (app.persistent && !app.isolated) {
6571                if (!callerWillRestart) {
6572                    willRestart = true;
6573                } else {
6574                    needRestart = true;
6575                }
6576            }
6577            app.kill(reason, true);
6578            handleAppDiedLocked(app, willRestart, allowRestart);
6579            if (willRestart) {
6580                removeLruProcessLocked(app);
6581                addAppLocked(app.info, null, false, null /* ABI override */);
6582            }
6583        } else {
6584            mRemovedProcesses.add(app);
6585        }
6586
6587        return needRestart;
6588    }
6589
6590    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6591        cleanupAppInLaunchingProvidersLocked(app, true);
6592        removeProcessLocked(app, false, true, "timeout publishing content providers");
6593    }
6594
6595    private final void processStartTimedOutLocked(ProcessRecord app) {
6596        final int pid = app.pid;
6597        boolean gone = false;
6598        synchronized (mPidsSelfLocked) {
6599            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6600            if (knownApp != null && knownApp.thread == null) {
6601                mPidsSelfLocked.remove(pid);
6602                gone = true;
6603            }
6604        }
6605
6606        if (gone) {
6607            Slog.w(TAG, "Process " + app + " failed to attach");
6608            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6609                    pid, app.uid, app.processName);
6610            removeProcessNameLocked(app.processName, app.uid);
6611            if (mHeavyWeightProcess == app) {
6612                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6613                        mHeavyWeightProcess.userId, 0));
6614                mHeavyWeightProcess = null;
6615            }
6616            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6617            if (app.isolated) {
6618                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6619            }
6620            // Take care of any launching providers waiting for this process.
6621            cleanupAppInLaunchingProvidersLocked(app, true);
6622            // Take care of any services that are waiting for the process.
6623            mServices.processStartTimedOutLocked(app);
6624            app.kill("start timeout", true);
6625            removeLruProcessLocked(app);
6626            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6627                Slog.w(TAG, "Unattached app died before backup, skipping");
6628                mHandler.post(new Runnable() {
6629                @Override
6630                    public void run(){
6631                        try {
6632                            IBackupManager bm = IBackupManager.Stub.asInterface(
6633                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6634                            bm.agentDisconnected(app.info.packageName);
6635                        } catch (RemoteException e) {
6636                            // Can't happen; the backup manager is local
6637                        }
6638                    }
6639                });
6640            }
6641            if (isPendingBroadcastProcessLocked(pid)) {
6642                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6643                skipPendingBroadcastLocked(pid);
6644            }
6645        } else {
6646            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6647        }
6648    }
6649
6650    private final boolean attachApplicationLocked(IApplicationThread thread,
6651            int pid) {
6652
6653        // Find the application record that is being attached...  either via
6654        // the pid if we are running in multiple processes, or just pull the
6655        // next app record if we are emulating process with anonymous threads.
6656        ProcessRecord app;
6657        long startTime = SystemClock.uptimeMillis();
6658        if (pid != MY_PID && pid >= 0) {
6659            synchronized (mPidsSelfLocked) {
6660                app = mPidsSelfLocked.get(pid);
6661            }
6662        } else {
6663            app = null;
6664        }
6665
6666        if (app == null) {
6667            Slog.w(TAG, "No pending application record for pid " + pid
6668                    + " (IApplicationThread " + thread + "); dropping process");
6669            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6670            if (pid > 0 && pid != MY_PID) {
6671                killProcessQuiet(pid);
6672                //TODO: killProcessGroup(app.info.uid, pid);
6673            } else {
6674                try {
6675                    thread.scheduleExit();
6676                } catch (Exception e) {
6677                    // Ignore exceptions.
6678                }
6679            }
6680            return false;
6681        }
6682
6683        // If this application record is still attached to a previous
6684        // process, clean it up now.
6685        if (app.thread != null) {
6686            handleAppDiedLocked(app, true, true);
6687        }
6688
6689        // Tell the process all about itself.
6690
6691        if (DEBUG_ALL) Slog.v(
6692                TAG, "Binding process pid " + pid + " to record " + app);
6693
6694        final String processName = app.processName;
6695        try {
6696            AppDeathRecipient adr = new AppDeathRecipient(
6697                    app, pid, thread);
6698            thread.asBinder().linkToDeath(adr, 0);
6699            app.deathRecipient = adr;
6700        } catch (RemoteException e) {
6701            app.resetPackageList(mProcessStats);
6702            startProcessLocked(app, "link fail", processName);
6703            return false;
6704        }
6705
6706        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6707
6708        app.makeActive(thread, mProcessStats);
6709        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6710        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6711        app.forcingToForeground = null;
6712        updateProcessForegroundLocked(app, false, false);
6713        app.hasShownUi = false;
6714        app.debugging = false;
6715        app.cached = false;
6716        app.killedByAm = false;
6717        app.killed = false;
6718
6719
6720        // We carefully use the same state that PackageManager uses for
6721        // filtering, since we use this flag to decide if we need to install
6722        // providers when user is unlocked later
6723        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6724
6725        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6726
6727        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6728        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6729
6730        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6731            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6732            msg.obj = app;
6733            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6734        }
6735
6736        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6737
6738        if (!normalMode) {
6739            Slog.i(TAG, "Launching preboot mode app: " + app);
6740        }
6741
6742        if (DEBUG_ALL) Slog.v(
6743            TAG, "New app record " + app
6744            + " thread=" + thread.asBinder() + " pid=" + pid);
6745        try {
6746            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6747            if (mDebugApp != null && mDebugApp.equals(processName)) {
6748                testMode = mWaitForDebugger
6749                    ? ApplicationThreadConstants.DEBUG_WAIT
6750                    : ApplicationThreadConstants.DEBUG_ON;
6751                app.debugging = true;
6752                if (mDebugTransient) {
6753                    mDebugApp = mOrigDebugApp;
6754                    mWaitForDebugger = mOrigWaitForDebugger;
6755                }
6756            }
6757            String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6758            ParcelFileDescriptor profileFd = null;
6759            int samplingInterval = 0;
6760            boolean profileAutoStop = false;
6761            boolean profileStreamingOutput = false;
6762            if (mProfileApp != null && mProfileApp.equals(processName)) {
6763                mProfileProc = app;
6764                profileFile = mProfileFile;
6765                profileFd = mProfileFd;
6766                samplingInterval = mSamplingInterval;
6767                profileAutoStop = mAutoStopProfiler;
6768                profileStreamingOutput = mStreamingOutput;
6769            }
6770            boolean enableTrackAllocation = false;
6771            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6772                enableTrackAllocation = true;
6773                mTrackAllocationApp = null;
6774            }
6775
6776            // If the app is being launched for restore or full backup, set it up specially
6777            boolean isRestrictedBackupMode = false;
6778            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6779                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6780                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6781                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6782                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6783            }
6784
6785            if (app.instr != null) {
6786                notifyPackageUse(app.instr.mClass.getPackageName(),
6787                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6788            }
6789            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6790                    + processName + " with config " + getGlobalConfiguration());
6791            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6792            app.compat = compatibilityInfoForPackageLocked(appInfo);
6793            if (profileFd != null) {
6794                profileFd = profileFd.dup();
6795            }
6796            ProfilerInfo profilerInfo = profileFile == null ? null
6797                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6798                                       profileStreamingOutput);
6799
6800            // We deprecated Build.SERIAL and it is not accessible to
6801            // apps that target the v2 security sandbox. Since access to
6802            // the serial is now behind a permission we push down the value.
6803            String buildSerial = Build.UNKNOWN;
6804            if (appInfo.targetSandboxVersion != 2) {
6805                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6806                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6807                        .getSerial();
6808            }
6809
6810            // Check if this is a secondary process that should be incorporated into some
6811            // currently active instrumentation.  (Note we do this AFTER all of the profiling
6812            // stuff above because profiling can currently happen only in the primary
6813            // instrumentation process.)
6814            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6815                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6816                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6817                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6818                        if (aInstr.mTargetProcesses.length == 0) {
6819                            // This is the wildcard mode, where every process brought up for
6820                            // the target instrumentation should be included.
6821                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6822                                app.instr = aInstr;
6823                                aInstr.mRunningProcesses.add(app);
6824                            }
6825                        } else {
6826                            for (String proc : aInstr.mTargetProcesses) {
6827                                if (proc.equals(app.processName)) {
6828                                    app.instr = aInstr;
6829                                    aInstr.mRunningProcesses.add(app);
6830                                    break;
6831                                }
6832                            }
6833                        }
6834                    }
6835                }
6836            }
6837
6838            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6839            if (app.instr != null) {
6840                thread.bindApplication(processName, appInfo, providers,
6841                        app.instr.mClass,
6842                        profilerInfo, app.instr.mArguments,
6843                        app.instr.mWatcher,
6844                        app.instr.mUiAutomationConnection, testMode,
6845                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6846                        isRestrictedBackupMode || !normalMode, app.persistent,
6847                        new Configuration(getGlobalConfiguration()), app.compat,
6848                        getCommonServicesLocked(app.isolated),
6849                        mCoreSettingsObserver.getCoreSettingsLocked(),
6850                        buildSerial);
6851            } else {
6852                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6853                        null, null, null, testMode,
6854                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6855                        isRestrictedBackupMode || !normalMode, app.persistent,
6856                        new Configuration(getGlobalConfiguration()), app.compat,
6857                        getCommonServicesLocked(app.isolated),
6858                        mCoreSettingsObserver.getCoreSettingsLocked(),
6859                        buildSerial);
6860            }
6861
6862            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6863            updateLruProcessLocked(app, false, null);
6864            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6865            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6866        } catch (Exception e) {
6867            // todo: Yikes!  What should we do?  For now we will try to
6868            // start another process, but that could easily get us in
6869            // an infinite loop of restarting processes...
6870            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6871
6872            app.resetPackageList(mProcessStats);
6873            app.unlinkDeathRecipient();
6874            startProcessLocked(app, "bind fail", processName);
6875            return false;
6876        }
6877
6878        // Remove this record from the list of starting applications.
6879        mPersistentStartingProcesses.remove(app);
6880        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6881                "Attach application locked removing on hold: " + app);
6882        mProcessesOnHold.remove(app);
6883
6884        boolean badApp = false;
6885        boolean didSomething = false;
6886
6887        // See if the top visible activity is waiting to run in this process...
6888        if (normalMode) {
6889            try {
6890                if (mStackSupervisor.attachApplicationLocked(app)) {
6891                    didSomething = true;
6892                }
6893            } catch (Exception e) {
6894                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6895                badApp = true;
6896            }
6897        }
6898
6899        // Find any services that should be running in this process...
6900        if (!badApp) {
6901            try {
6902                didSomething |= mServices.attachApplicationLocked(app, processName);
6903                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6904            } catch (Exception e) {
6905                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6906                badApp = true;
6907            }
6908        }
6909
6910        // Check if a next-broadcast receiver is in this process...
6911        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6912            try {
6913                didSomething |= sendPendingBroadcastsLocked(app);
6914                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6915            } catch (Exception e) {
6916                // If the app died trying to launch the receiver we declare it 'bad'
6917                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6918                badApp = true;
6919            }
6920        }
6921
6922        // Check whether the next backup agent is in this process...
6923        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6924            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6925                    "New app is backup target, launching agent for " + app);
6926            notifyPackageUse(mBackupTarget.appInfo.packageName,
6927                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6928            try {
6929                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6930                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6931                        mBackupTarget.backupMode);
6932            } catch (Exception e) {
6933                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6934                badApp = true;
6935            }
6936        }
6937
6938        if (badApp) {
6939            app.kill("error during init", true);
6940            handleAppDiedLocked(app, false, true);
6941            return false;
6942        }
6943
6944        if (!didSomething) {
6945            updateOomAdjLocked();
6946            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6947        }
6948
6949        return true;
6950    }
6951
6952    @Override
6953    public final void attachApplication(IApplicationThread thread) {
6954        synchronized (this) {
6955            int callingPid = Binder.getCallingPid();
6956            final long origId = Binder.clearCallingIdentity();
6957            attachApplicationLocked(thread, callingPid);
6958            Binder.restoreCallingIdentity(origId);
6959        }
6960    }
6961
6962    @Override
6963    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6964        final long origId = Binder.clearCallingIdentity();
6965        synchronized (this) {
6966            ActivityStack stack = ActivityRecord.getStackLocked(token);
6967            if (stack != null) {
6968                ActivityRecord r =
6969                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
6970                                false /* processPausingActivities */, config);
6971                if (stopProfiling) {
6972                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6973                        try {
6974                            mProfileFd.close();
6975                        } catch (IOException e) {
6976                        }
6977                        clearProfilerLocked();
6978                    }
6979                }
6980            }
6981        }
6982        Binder.restoreCallingIdentity(origId);
6983    }
6984
6985    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6986        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6987                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6988    }
6989
6990    void enableScreenAfterBoot() {
6991        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6992                SystemClock.uptimeMillis());
6993        mWindowManager.enableScreenAfterBoot();
6994
6995        synchronized (this) {
6996            updateEventDispatchingLocked();
6997        }
6998    }
6999
7000    @Override
7001    public void showBootMessage(final CharSequence msg, final boolean always) {
7002        if (Binder.getCallingUid() != myUid()) {
7003            throw new SecurityException();
7004        }
7005        mWindowManager.showBootMessage(msg, always);
7006    }
7007
7008    @Override
7009    public void keyguardGoingAway(int flags) {
7010        enforceNotIsolatedCaller("keyguardGoingAway");
7011        final long token = Binder.clearCallingIdentity();
7012        try {
7013            synchronized (this) {
7014                mKeyguardController.keyguardGoingAway(flags);
7015            }
7016        } finally {
7017            Binder.restoreCallingIdentity(token);
7018        }
7019    }
7020
7021    /**
7022     * @return whther the keyguard is currently locked.
7023     */
7024    boolean isKeyguardLocked() {
7025        return mKeyguardController.isKeyguardLocked();
7026    }
7027
7028    final void finishBooting() {
7029        synchronized (this) {
7030            if (!mBootAnimationComplete) {
7031                mCallFinishBooting = true;
7032                return;
7033            }
7034            mCallFinishBooting = false;
7035        }
7036
7037        ArraySet<String> completedIsas = new ArraySet<String>();
7038        for (String abi : Build.SUPPORTED_ABIS) {
7039            zygoteProcess.establishZygoteConnectionForAbi(abi);
7040            final String instructionSet = VMRuntime.getInstructionSet(abi);
7041            if (!completedIsas.contains(instructionSet)) {
7042                try {
7043                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7044                } catch (InstallerException e) {
7045                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7046                            e.getMessage() +")");
7047                }
7048                completedIsas.add(instructionSet);
7049            }
7050        }
7051
7052        IntentFilter pkgFilter = new IntentFilter();
7053        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7054        pkgFilter.addDataScheme("package");
7055        mContext.registerReceiver(new BroadcastReceiver() {
7056            @Override
7057            public void onReceive(Context context, Intent intent) {
7058                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7059                if (pkgs != null) {
7060                    for (String pkg : pkgs) {
7061                        synchronized (ActivityManagerService.this) {
7062                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7063                                    0, "query restart")) {
7064                                setResultCode(Activity.RESULT_OK);
7065                                return;
7066                            }
7067                        }
7068                    }
7069                }
7070            }
7071        }, pkgFilter);
7072
7073        IntentFilter dumpheapFilter = new IntentFilter();
7074        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7075        mContext.registerReceiver(new BroadcastReceiver() {
7076            @Override
7077            public void onReceive(Context context, Intent intent) {
7078                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7079                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7080                } else {
7081                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7082                }
7083            }
7084        }, dumpheapFilter);
7085
7086        // Let system services know.
7087        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7088
7089        synchronized (this) {
7090            // Ensure that any processes we had put on hold are now started
7091            // up.
7092            final int NP = mProcessesOnHold.size();
7093            if (NP > 0) {
7094                ArrayList<ProcessRecord> procs =
7095                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7096                for (int ip=0; ip<NP; ip++) {
7097                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7098                            + procs.get(ip));
7099                    startProcessLocked(procs.get(ip), "on-hold", null);
7100                }
7101            }
7102
7103            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7104                // Start looking for apps that are abusing wake locks.
7105                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7106                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7107                // Tell anyone interested that we are done booting!
7108                SystemProperties.set("sys.boot_completed", "1");
7109
7110                // And trigger dev.bootcomplete if we are not showing encryption progress
7111                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7112                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7113                    SystemProperties.set("dev.bootcomplete", "1");
7114                }
7115                mUserController.sendBootCompletedLocked(
7116                        new IIntentReceiver.Stub() {
7117                            @Override
7118                            public void performReceive(Intent intent, int resultCode,
7119                                    String data, Bundle extras, boolean ordered,
7120                                    boolean sticky, int sendingUser) {
7121                                synchronized (ActivityManagerService.this) {
7122                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7123                                            true, false);
7124                                }
7125                            }
7126                        });
7127                scheduleStartProfilesLocked();
7128            }
7129        }
7130    }
7131
7132    @Override
7133    public void bootAnimationComplete() {
7134        final boolean callFinishBooting;
7135        synchronized (this) {
7136            callFinishBooting = mCallFinishBooting;
7137            mBootAnimationComplete = true;
7138        }
7139        if (callFinishBooting) {
7140            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7141            finishBooting();
7142            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7143        }
7144    }
7145
7146    final void ensureBootCompleted() {
7147        boolean booting;
7148        boolean enableScreen;
7149        synchronized (this) {
7150            booting = mBooting;
7151            mBooting = false;
7152            enableScreen = !mBooted;
7153            mBooted = true;
7154        }
7155
7156        if (booting) {
7157            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7158            finishBooting();
7159            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7160        }
7161
7162        if (enableScreen) {
7163            enableScreenAfterBoot();
7164        }
7165    }
7166
7167    @Override
7168    public final void activityResumed(IBinder token) {
7169        final long origId = Binder.clearCallingIdentity();
7170        synchronized(this) {
7171            ActivityRecord.activityResumedLocked(token);
7172            mWindowManager.notifyAppResumedFinished(token);
7173        }
7174        Binder.restoreCallingIdentity(origId);
7175    }
7176
7177    @Override
7178    public final void activityPaused(IBinder token) {
7179        final long origId = Binder.clearCallingIdentity();
7180        synchronized(this) {
7181            ActivityStack stack = ActivityRecord.getStackLocked(token);
7182            if (stack != null) {
7183                stack.activityPausedLocked(token, false);
7184            }
7185        }
7186        Binder.restoreCallingIdentity(origId);
7187    }
7188
7189    @Override
7190    public final void activityStopped(IBinder token, Bundle icicle,
7191            PersistableBundle persistentState, CharSequence description) {
7192        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7193
7194        // Refuse possible leaked file descriptors
7195        if (icicle != null && icicle.hasFileDescriptors()) {
7196            throw new IllegalArgumentException("File descriptors passed in Bundle");
7197        }
7198
7199        final long origId = Binder.clearCallingIdentity();
7200
7201        synchronized (this) {
7202            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7203            if (r != null) {
7204                r.activityStoppedLocked(icicle, persistentState, description);
7205            }
7206        }
7207
7208        trimApplications();
7209
7210        Binder.restoreCallingIdentity(origId);
7211    }
7212
7213    @Override
7214    public final void activityDestroyed(IBinder token) {
7215        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7216        synchronized (this) {
7217            ActivityStack stack = ActivityRecord.getStackLocked(token);
7218            if (stack != null) {
7219                stack.activityDestroyedLocked(token, "activityDestroyed");
7220            }
7221        }
7222    }
7223
7224    @Override
7225    public final void activityRelaunched(IBinder token) {
7226        final long origId = Binder.clearCallingIdentity();
7227        synchronized (this) {
7228            mStackSupervisor.activityRelaunchedLocked(token);
7229        }
7230        Binder.restoreCallingIdentity(origId);
7231    }
7232
7233    @Override
7234    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7235            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7236        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7237                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7238        synchronized (this) {
7239            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7240            if (record == null) {
7241                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7242                        + "found for: " + token);
7243            }
7244            record.setSizeConfigurations(horizontalSizeConfiguration,
7245                    verticalSizeConfigurations, smallestSizeConfigurations);
7246        }
7247    }
7248
7249    @Override
7250    public final void backgroundResourcesReleased(IBinder token) {
7251        final long origId = Binder.clearCallingIdentity();
7252        try {
7253            synchronized (this) {
7254                ActivityStack stack = ActivityRecord.getStackLocked(token);
7255                if (stack != null) {
7256                    stack.backgroundResourcesReleased();
7257                }
7258            }
7259        } finally {
7260            Binder.restoreCallingIdentity(origId);
7261        }
7262    }
7263
7264    @Override
7265    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7266        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7267    }
7268
7269    @Override
7270    public final void notifyEnterAnimationComplete(IBinder token) {
7271        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7272    }
7273
7274    @Override
7275    public String getCallingPackage(IBinder token) {
7276        synchronized (this) {
7277            ActivityRecord r = getCallingRecordLocked(token);
7278            return r != null ? r.info.packageName : null;
7279        }
7280    }
7281
7282    @Override
7283    public ComponentName getCallingActivity(IBinder token) {
7284        synchronized (this) {
7285            ActivityRecord r = getCallingRecordLocked(token);
7286            return r != null ? r.intent.getComponent() : null;
7287        }
7288    }
7289
7290    private ActivityRecord getCallingRecordLocked(IBinder token) {
7291        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7292        if (r == null) {
7293            return null;
7294        }
7295        return r.resultTo;
7296    }
7297
7298    @Override
7299    public ComponentName getActivityClassForToken(IBinder token) {
7300        synchronized(this) {
7301            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7302            if (r == null) {
7303                return null;
7304            }
7305            return r.intent.getComponent();
7306        }
7307    }
7308
7309    @Override
7310    public String getPackageForToken(IBinder token) {
7311        synchronized(this) {
7312            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7313            if (r == null) {
7314                return null;
7315            }
7316            return r.packageName;
7317        }
7318    }
7319
7320    @Override
7321    public boolean isRootVoiceInteraction(IBinder token) {
7322        synchronized(this) {
7323            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7324            if (r == null) {
7325                return false;
7326            }
7327            return r.rootVoiceInteraction;
7328        }
7329    }
7330
7331    @Override
7332    public IIntentSender getIntentSender(int type,
7333            String packageName, IBinder token, String resultWho,
7334            int requestCode, Intent[] intents, String[] resolvedTypes,
7335            int flags, Bundle bOptions, int userId) {
7336        enforceNotIsolatedCaller("getIntentSender");
7337        // Refuse possible leaked file descriptors
7338        if (intents != null) {
7339            if (intents.length < 1) {
7340                throw new IllegalArgumentException("Intents array length must be >= 1");
7341            }
7342            for (int i=0; i<intents.length; i++) {
7343                Intent intent = intents[i];
7344                if (intent != null) {
7345                    if (intent.hasFileDescriptors()) {
7346                        throw new IllegalArgumentException("File descriptors passed in Intent");
7347                    }
7348                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7349                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7350                        throw new IllegalArgumentException(
7351                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7352                    }
7353                    intents[i] = new Intent(intent);
7354                }
7355            }
7356            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7357                throw new IllegalArgumentException(
7358                        "Intent array length does not match resolvedTypes length");
7359            }
7360        }
7361        if (bOptions != null) {
7362            if (bOptions.hasFileDescriptors()) {
7363                throw new IllegalArgumentException("File descriptors passed in options");
7364            }
7365        }
7366
7367        synchronized(this) {
7368            int callingUid = Binder.getCallingUid();
7369            int origUserId = userId;
7370            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7371                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7372                    ALLOW_NON_FULL, "getIntentSender", null);
7373            if (origUserId == UserHandle.USER_CURRENT) {
7374                // We don't want to evaluate this until the pending intent is
7375                // actually executed.  However, we do want to always do the
7376                // security checking for it above.
7377                userId = UserHandle.USER_CURRENT;
7378            }
7379            try {
7380                if (callingUid != 0 && callingUid != SYSTEM_UID) {
7381                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7382                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7383                    if (!UserHandle.isSameApp(callingUid, uid)) {
7384                        String msg = "Permission Denial: getIntentSender() from pid="
7385                            + Binder.getCallingPid()
7386                            + ", uid=" + Binder.getCallingUid()
7387                            + ", (need uid=" + uid + ")"
7388                            + " is not allowed to send as package " + packageName;
7389                        Slog.w(TAG, msg);
7390                        throw new SecurityException(msg);
7391                    }
7392                }
7393
7394                return getIntentSenderLocked(type, packageName, callingUid, userId,
7395                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7396
7397            } catch (RemoteException e) {
7398                throw new SecurityException(e);
7399            }
7400        }
7401    }
7402
7403    IIntentSender getIntentSenderLocked(int type, String packageName,
7404            int callingUid, int userId, IBinder token, String resultWho,
7405            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7406            Bundle bOptions) {
7407        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7408        ActivityRecord activity = null;
7409        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7410            activity = ActivityRecord.isInStackLocked(token);
7411            if (activity == null) {
7412                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7413                return null;
7414            }
7415            if (activity.finishing) {
7416                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7417                return null;
7418            }
7419        }
7420
7421        // We're going to be splicing together extras before sending, so we're
7422        // okay poking into any contained extras.
7423        if (intents != null) {
7424            for (int i = 0; i < intents.length; i++) {
7425                intents[i].setDefusable(true);
7426            }
7427        }
7428        Bundle.setDefusable(bOptions, true);
7429
7430        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7431        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7432        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7433        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7434                |PendingIntent.FLAG_UPDATE_CURRENT);
7435
7436        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7437                type, packageName, activity, resultWho,
7438                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7439        WeakReference<PendingIntentRecord> ref;
7440        ref = mIntentSenderRecords.get(key);
7441        PendingIntentRecord rec = ref != null ? ref.get() : null;
7442        if (rec != null) {
7443            if (!cancelCurrent) {
7444                if (updateCurrent) {
7445                    if (rec.key.requestIntent != null) {
7446                        rec.key.requestIntent.replaceExtras(intents != null ?
7447                                intents[intents.length - 1] : null);
7448                    }
7449                    if (intents != null) {
7450                        intents[intents.length-1] = rec.key.requestIntent;
7451                        rec.key.allIntents = intents;
7452                        rec.key.allResolvedTypes = resolvedTypes;
7453                    } else {
7454                        rec.key.allIntents = null;
7455                        rec.key.allResolvedTypes = null;
7456                    }
7457                }
7458                return rec;
7459            }
7460            makeIntentSenderCanceledLocked(rec);
7461            mIntentSenderRecords.remove(key);
7462        }
7463        if (noCreate) {
7464            return rec;
7465        }
7466        rec = new PendingIntentRecord(this, key, callingUid);
7467        mIntentSenderRecords.put(key, rec.ref);
7468        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7469            if (activity.pendingResults == null) {
7470                activity.pendingResults
7471                        = new HashSet<WeakReference<PendingIntentRecord>>();
7472            }
7473            activity.pendingResults.add(rec.ref);
7474        }
7475        return rec;
7476    }
7477
7478    @Override
7479    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7480            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7481        if (target instanceof PendingIntentRecord) {
7482            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7483                    finishedReceiver, requiredPermission, options);
7484        } else {
7485            if (intent == null) {
7486                // Weird case: someone has given us their own custom IIntentSender, and now
7487                // they have someone else trying to send to it but of course this isn't
7488                // really a PendingIntent, so there is no base Intent, and the caller isn't
7489                // supplying an Intent... but we never want to dispatch a null Intent to
7490                // a receiver, so um...  let's make something up.
7491                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7492                intent = new Intent(Intent.ACTION_MAIN);
7493            }
7494            try {
7495                target.send(code, intent, resolvedType, null, requiredPermission, options);
7496            } catch (RemoteException e) {
7497            }
7498            // Platform code can rely on getting a result back when the send is done, but if
7499            // this intent sender is from outside of the system we can't rely on it doing that.
7500            // So instead we don't give it the result receiver, and instead just directly
7501            // report the finish immediately.
7502            if (finishedReceiver != null) {
7503                try {
7504                    finishedReceiver.performReceive(intent, 0,
7505                            null, null, false, false, UserHandle.getCallingUserId());
7506                } catch (RemoteException e) {
7507                }
7508            }
7509            return 0;
7510        }
7511    }
7512
7513    @Override
7514    public void cancelIntentSender(IIntentSender sender) {
7515        if (!(sender instanceof PendingIntentRecord)) {
7516            return;
7517        }
7518        synchronized(this) {
7519            PendingIntentRecord rec = (PendingIntentRecord)sender;
7520            try {
7521                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7522                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7523                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7524                    String msg = "Permission Denial: cancelIntentSender() from pid="
7525                        + Binder.getCallingPid()
7526                        + ", uid=" + Binder.getCallingUid()
7527                        + " is not allowed to cancel package "
7528                        + rec.key.packageName;
7529                    Slog.w(TAG, msg);
7530                    throw new SecurityException(msg);
7531                }
7532            } catch (RemoteException e) {
7533                throw new SecurityException(e);
7534            }
7535            cancelIntentSenderLocked(rec, true);
7536        }
7537    }
7538
7539    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7540        makeIntentSenderCanceledLocked(rec);
7541        mIntentSenderRecords.remove(rec.key);
7542        if (cleanActivity && rec.key.activity != null) {
7543            rec.key.activity.pendingResults.remove(rec.ref);
7544        }
7545    }
7546
7547    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7548        rec.canceled = true;
7549        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7550        if (callbacks != null) {
7551            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7552        }
7553    }
7554
7555    @Override
7556    public String getPackageForIntentSender(IIntentSender pendingResult) {
7557        if (!(pendingResult instanceof PendingIntentRecord)) {
7558            return null;
7559        }
7560        try {
7561            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7562            return res.key.packageName;
7563        } catch (ClassCastException e) {
7564        }
7565        return null;
7566    }
7567
7568    @Override
7569    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7570        if (!(sender instanceof PendingIntentRecord)) {
7571            return;
7572        }
7573        synchronized(this) {
7574            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7575        }
7576    }
7577
7578    @Override
7579    public void unregisterIntentSenderCancelListener(IIntentSender sender,
7580            IResultReceiver receiver) {
7581        if (!(sender instanceof PendingIntentRecord)) {
7582            return;
7583        }
7584        synchronized(this) {
7585            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7586        }
7587    }
7588
7589    @Override
7590    public int getUidForIntentSender(IIntentSender sender) {
7591        if (sender instanceof PendingIntentRecord) {
7592            try {
7593                PendingIntentRecord res = (PendingIntentRecord)sender;
7594                return res.uid;
7595            } catch (ClassCastException e) {
7596            }
7597        }
7598        return -1;
7599    }
7600
7601    @Override
7602    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7603        if (!(pendingResult instanceof PendingIntentRecord)) {
7604            return false;
7605        }
7606        try {
7607            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7608            if (res.key.allIntents == null) {
7609                return false;
7610            }
7611            for (int i=0; i<res.key.allIntents.length; i++) {
7612                Intent intent = res.key.allIntents[i];
7613                if (intent.getPackage() != null && intent.getComponent() != null) {
7614                    return false;
7615                }
7616            }
7617            return true;
7618        } catch (ClassCastException e) {
7619        }
7620        return false;
7621    }
7622
7623    @Override
7624    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7625        if (!(pendingResult instanceof PendingIntentRecord)) {
7626            return false;
7627        }
7628        try {
7629            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7630            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7631                return true;
7632            }
7633            return false;
7634        } catch (ClassCastException e) {
7635        }
7636        return false;
7637    }
7638
7639    @Override
7640    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7641        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7642                "getIntentForIntentSender()");
7643        if (!(pendingResult instanceof PendingIntentRecord)) {
7644            return null;
7645        }
7646        try {
7647            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7648            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7649        } catch (ClassCastException e) {
7650        }
7651        return null;
7652    }
7653
7654    @Override
7655    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7656        if (!(pendingResult instanceof PendingIntentRecord)) {
7657            return null;
7658        }
7659        try {
7660            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7661            synchronized (this) {
7662                return getTagForIntentSenderLocked(res, prefix);
7663            }
7664        } catch (ClassCastException e) {
7665        }
7666        return null;
7667    }
7668
7669    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7670        final Intent intent = res.key.requestIntent;
7671        if (intent != null) {
7672            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7673                    || res.lastTagPrefix.equals(prefix))) {
7674                return res.lastTag;
7675            }
7676            res.lastTagPrefix = prefix;
7677            final StringBuilder sb = new StringBuilder(128);
7678            if (prefix != null) {
7679                sb.append(prefix);
7680            }
7681            if (intent.getAction() != null) {
7682                sb.append(intent.getAction());
7683            } else if (intent.getComponent() != null) {
7684                intent.getComponent().appendShortString(sb);
7685            } else {
7686                sb.append("?");
7687            }
7688            return res.lastTag = sb.toString();
7689        }
7690        return null;
7691    }
7692
7693    @Override
7694    public void setProcessLimit(int max) {
7695        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7696                "setProcessLimit()");
7697        synchronized (this) {
7698            mConstants.setOverrideMaxCachedProcesses(max);
7699        }
7700        trimApplications();
7701    }
7702
7703    @Override
7704    public int getProcessLimit() {
7705        synchronized (this) {
7706            return mConstants.getOverrideMaxCachedProcesses();
7707        }
7708    }
7709
7710    void foregroundTokenDied(ForegroundToken token) {
7711        synchronized (ActivityManagerService.this) {
7712            synchronized (mPidsSelfLocked) {
7713                ForegroundToken cur
7714                    = mForegroundProcesses.get(token.pid);
7715                if (cur != token) {
7716                    return;
7717                }
7718                mForegroundProcesses.remove(token.pid);
7719                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7720                if (pr == null) {
7721                    return;
7722                }
7723                pr.forcingToForeground = null;
7724                updateProcessForegroundLocked(pr, false, false);
7725            }
7726            updateOomAdjLocked();
7727        }
7728    }
7729
7730    @Override
7731    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7732        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7733                "setProcessForeground()");
7734        synchronized(this) {
7735            boolean changed = false;
7736
7737            synchronized (mPidsSelfLocked) {
7738                ProcessRecord pr = mPidsSelfLocked.get(pid);
7739                if (pr == null && isForeground) {
7740                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7741                    return;
7742                }
7743                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7744                if (oldToken != null) {
7745                    oldToken.token.unlinkToDeath(oldToken, 0);
7746                    mForegroundProcesses.remove(pid);
7747                    if (pr != null) {
7748                        pr.forcingToForeground = null;
7749                    }
7750                    changed = true;
7751                }
7752                if (isForeground && token != null) {
7753                    ForegroundToken newToken = new ForegroundToken() {
7754                        @Override
7755                        public void binderDied() {
7756                            foregroundTokenDied(this);
7757                        }
7758                    };
7759                    newToken.pid = pid;
7760                    newToken.token = token;
7761                    try {
7762                        token.linkToDeath(newToken, 0);
7763                        mForegroundProcesses.put(pid, newToken);
7764                        pr.forcingToForeground = token;
7765                        changed = true;
7766                    } catch (RemoteException e) {
7767                        // If the process died while doing this, we will later
7768                        // do the cleanup with the process death link.
7769                    }
7770                }
7771            }
7772
7773            if (changed) {
7774                updateOomAdjLocked();
7775            }
7776        }
7777    }
7778
7779    @Override
7780    public boolean isAppForeground(int uid) throws RemoteException {
7781        synchronized (this) {
7782            UidRecord uidRec = mActiveUids.get(uid);
7783            if (uidRec == null || uidRec.idle) {
7784                return false;
7785            }
7786            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7787        }
7788    }
7789
7790    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7791    // be guarded by permission checking.
7792    int getUidState(int uid) {
7793        synchronized (this) {
7794            UidRecord uidRec = mActiveUids.get(uid);
7795            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7796        }
7797    }
7798
7799    @Override
7800    public boolean isInMultiWindowMode(IBinder token) {
7801        final long origId = Binder.clearCallingIdentity();
7802        try {
7803            synchronized(this) {
7804                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7805                if (r == null) {
7806                    return false;
7807                }
7808                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7809                return !r.getTask().mFullscreen;
7810            }
7811        } finally {
7812            Binder.restoreCallingIdentity(origId);
7813        }
7814    }
7815
7816    @Override
7817    public boolean isInPictureInPictureMode(IBinder token) {
7818        final long origId = Binder.clearCallingIdentity();
7819        try {
7820            synchronized(this) {
7821                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7822                if (stack == null) {
7823                    return false;
7824                }
7825                return stack.mStackId == PINNED_STACK_ID;
7826            }
7827        } finally {
7828            Binder.restoreCallingIdentity(origId);
7829        }
7830    }
7831
7832    @Override
7833    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureArgs args) {
7834        final long origId = Binder.clearCallingIdentity();
7835        try {
7836            synchronized(this) {
7837                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7838                        "enterPictureInPictureMode", token, args);
7839
7840                // Activity supports picture-in-picture, now check that we can enter PiP at this
7841                // point, if it is
7842                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7843                        false /* noThrow */, false /* beforeStopping */)) {
7844                    return false;
7845                }
7846
7847                final Runnable enterPipRunnable = () -> {
7848                    // Only update the saved args from the args that are set
7849                    r.pictureInPictureArgs.copyOnlySet(args);
7850                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
7851                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
7852                    // Adjust the source bounds by the insets for the transition down
7853                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
7854                    final Rect insets = r.pictureInPictureArgs.getSourceRectHintInsets();
7855                    if (insets != null) {
7856                        sourceBounds.offsetTo(Math.max(0, sourceBounds.left - insets.left),
7857                                Math.max(0, sourceBounds.top - insets.top));
7858                    }
7859
7860                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
7861                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
7862                    final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
7863                    stack.setPictureInPictureAspectRatio(aspectRatio);
7864                    stack.setPictureInPictureActions(actions);
7865
7866                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
7867                            r.supportsPictureInPictureWhilePausing);
7868                    logPictureInPictureArgs(args);
7869                };
7870
7871                if (isKeyguardLocked()) {
7872                    // If the keyguard is showing or occluded, then try and dismiss it before
7873                    // entering picture-in-picture (this will prompt the user to authenticate if the
7874                    // device is currently locked).
7875                    try {
7876                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7877                            @Override
7878                            public void onDismissError() throws RemoteException {
7879                                // Do nothing
7880                            }
7881
7882                            @Override
7883                            public void onDismissSucceeded() throws RemoteException {
7884                                mHandler.post(enterPipRunnable);
7885                            }
7886
7887                            @Override
7888                            public void onDismissCancelled() throws RemoteException {
7889                                // Do nothing
7890                            }
7891                        });
7892                    } catch (RemoteException e) {
7893                        // Local call
7894                    }
7895                } else {
7896                    // Enter picture in picture immediately otherwise
7897                    enterPipRunnable.run();
7898                }
7899                return true;
7900            }
7901        } finally {
7902            Binder.restoreCallingIdentity(origId);
7903        }
7904    }
7905
7906    @Override
7907    public void setPictureInPictureArgs(IBinder token, final PictureInPictureArgs args) {
7908        final long origId = Binder.clearCallingIdentity();
7909        try {
7910            synchronized(this) {
7911                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7912                        "setPictureInPictureArgs", token, args);
7913
7914                // Only update the saved args from the args that are set
7915                r.pictureInPictureArgs.copyOnlySet(args);
7916                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7917                    // If the activity is already in picture-in-picture, update the pinned stack now
7918                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
7919                    // be used the next time the activity enters PiP
7920                    final PinnedActivityStack stack = r.getStack();
7921                    if (!stack.isAnimatingBoundsToFullscreen()) {
7922                        stack.setPictureInPictureAspectRatio(
7923                                r.pictureInPictureArgs.getAspectRatio());
7924                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
7925                    }
7926                }
7927                logPictureInPictureArgs(args);
7928            }
7929        } finally {
7930            Binder.restoreCallingIdentity(origId);
7931        }
7932    }
7933
7934    private void logPictureInPictureArgs(PictureInPictureArgs args) {
7935        if (args.hasSetActions()) {
7936            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
7937                    args.getActions().size());
7938        }
7939        if (args.hasSetAspectRatio()) {
7940            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
7941            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, args.getAspectRatio());
7942            MetricsLogger.action(lm);
7943        }
7944    }
7945
7946    /**
7947     * Checks the state of the system and the activity associated with the given {@param token} to
7948     * verify that picture-in-picture is supported for that activity.
7949     *
7950     * @return the activity record for the given {@param token} if all the checks pass.
7951     */
7952    private ActivityRecord ensureValidPictureInPictureActivityArgsLocked(String caller,
7953            IBinder token, PictureInPictureArgs args) {
7954        if (!mSupportsPictureInPicture) {
7955            throw new IllegalStateException(caller
7956                    + ": Device doesn't support picture-in-picture mode.");
7957        }
7958
7959        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7960        if (r == null) {
7961            throw new IllegalStateException(caller
7962                    + ": Can't find activity for token=" + token);
7963        }
7964
7965        if (!r.supportsPictureInPicture()) {
7966            throw new IllegalStateException(caller
7967                    + ": Current activity does not support picture-in-picture.");
7968        }
7969
7970        if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
7971            throw new IllegalStateException(caller
7972                    + ": Activities on the home, assistant, or recents stack not supported");
7973        }
7974
7975        if (args.hasSetAspectRatio()
7976                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
7977                        args.getAspectRatio())) {
7978            final float minAspectRatio = mContext.getResources().getFloat(
7979                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
7980            final float maxAspectRatio = mContext.getResources().getFloat(
7981                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
7982            throw new IllegalArgumentException(String.format(caller
7983                    + ": Aspect ratio is too extreme (must be between %f and %f).",
7984                            minAspectRatio, maxAspectRatio));
7985        }
7986
7987        if (args.hasSetActions()
7988                && args.getActions().size() > ActivityManager.getMaxNumPictureInPictureActions()) {
7989            throw new IllegalArgumentException(String.format(caller + ": Invalid number of"
7990                    + "picture-in-picture actions.  Only a maximum of %d actions allowed",
7991                            ActivityManager.getMaxNumPictureInPictureActions()));
7992        }
7993
7994        return r;
7995    }
7996
7997    // =========================================================
7998    // PROCESS INFO
7999    // =========================================================
8000
8001    static class ProcessInfoService extends IProcessInfoService.Stub {
8002        final ActivityManagerService mActivityManagerService;
8003        ProcessInfoService(ActivityManagerService activityManagerService) {
8004            mActivityManagerService = activityManagerService;
8005        }
8006
8007        @Override
8008        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8009            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8010                    /*in*/ pids, /*out*/ states, null);
8011        }
8012
8013        @Override
8014        public void getProcessStatesAndOomScoresFromPids(
8015                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8016            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8017                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8018        }
8019    }
8020
8021    /**
8022     * For each PID in the given input array, write the current process state
8023     * for that process into the states array, or -1 to indicate that no
8024     * process with the given PID exists. If scores array is provided, write
8025     * the oom score for the process into the scores array, with INVALID_ADJ
8026     * indicating the PID doesn't exist.
8027     */
8028    public void getProcessStatesAndOomScoresForPIDs(
8029            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8030        if (scores != null) {
8031            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8032                    "getProcessStatesAndOomScoresForPIDs()");
8033        }
8034
8035        if (pids == null) {
8036            throw new NullPointerException("pids");
8037        } else if (states == null) {
8038            throw new NullPointerException("states");
8039        } else if (pids.length != states.length) {
8040            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8041        } else if (scores != null && pids.length != scores.length) {
8042            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8043        }
8044
8045        synchronized (mPidsSelfLocked) {
8046            for (int i = 0; i < pids.length; i++) {
8047                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8048                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8049                        pr.curProcState;
8050                if (scores != null) {
8051                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8052                }
8053            }
8054        }
8055    }
8056
8057    // =========================================================
8058    // PERMISSIONS
8059    // =========================================================
8060
8061    static class PermissionController extends IPermissionController.Stub {
8062        ActivityManagerService mActivityManagerService;
8063        PermissionController(ActivityManagerService activityManagerService) {
8064            mActivityManagerService = activityManagerService;
8065        }
8066
8067        @Override
8068        public boolean checkPermission(String permission, int pid, int uid) {
8069            return mActivityManagerService.checkPermission(permission, pid,
8070                    uid) == PackageManager.PERMISSION_GRANTED;
8071        }
8072
8073        @Override
8074        public String[] getPackagesForUid(int uid) {
8075            return mActivityManagerService.mContext.getPackageManager()
8076                    .getPackagesForUid(uid);
8077        }
8078
8079        @Override
8080        public boolean isRuntimePermission(String permission) {
8081            try {
8082                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8083                        .getPermissionInfo(permission, 0);
8084                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8085                        == PermissionInfo.PROTECTION_DANGEROUS;
8086            } catch (NameNotFoundException nnfe) {
8087                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8088            }
8089            return false;
8090        }
8091    }
8092
8093    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8094        @Override
8095        public int checkComponentPermission(String permission, int pid, int uid,
8096                int owningUid, boolean exported) {
8097            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8098                    owningUid, exported);
8099        }
8100
8101        @Override
8102        public Object getAMSLock() {
8103            return ActivityManagerService.this;
8104        }
8105    }
8106
8107    /**
8108     * This can be called with or without the global lock held.
8109     */
8110    int checkComponentPermission(String permission, int pid, int uid,
8111            int owningUid, boolean exported) {
8112        if (pid == MY_PID) {
8113            return PackageManager.PERMISSION_GRANTED;
8114        }
8115        return ActivityManager.checkComponentPermission(permission, uid,
8116                owningUid, exported);
8117    }
8118
8119    /**
8120     * As the only public entry point for permissions checking, this method
8121     * can enforce the semantic that requesting a check on a null global
8122     * permission is automatically denied.  (Internally a null permission
8123     * string is used when calling {@link #checkComponentPermission} in cases
8124     * when only uid-based security is needed.)
8125     *
8126     * This can be called with or without the global lock held.
8127     */
8128    @Override
8129    public int checkPermission(String permission, int pid, int uid) {
8130        if (permission == null) {
8131            return PackageManager.PERMISSION_DENIED;
8132        }
8133        return checkComponentPermission(permission, pid, uid, -1, true);
8134    }
8135
8136    @Override
8137    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8138        if (permission == null) {
8139            return PackageManager.PERMISSION_DENIED;
8140        }
8141
8142        // We might be performing an operation on behalf of an indirect binder
8143        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8144        // client identity accordingly before proceeding.
8145        Identity tlsIdentity = sCallerIdentity.get();
8146        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8147            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8148                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8149            uid = tlsIdentity.uid;
8150            pid = tlsIdentity.pid;
8151        }
8152
8153        return checkComponentPermission(permission, pid, uid, -1, true);
8154    }
8155
8156    /**
8157     * Binder IPC calls go through the public entry point.
8158     * This can be called with or without the global lock held.
8159     */
8160    int checkCallingPermission(String permission) {
8161        return checkPermission(permission,
8162                Binder.getCallingPid(),
8163                UserHandle.getAppId(Binder.getCallingUid()));
8164    }
8165
8166    /**
8167     * This can be called with or without the global lock held.
8168     */
8169    void enforceCallingPermission(String permission, String func) {
8170        if (checkCallingPermission(permission)
8171                == PackageManager.PERMISSION_GRANTED) {
8172            return;
8173        }
8174
8175        String msg = "Permission Denial: " + func + " from pid="
8176                + Binder.getCallingPid()
8177                + ", uid=" + Binder.getCallingUid()
8178                + " requires " + permission;
8179        Slog.w(TAG, msg);
8180        throw new SecurityException(msg);
8181    }
8182
8183    /**
8184     * Determine if UID is holding permissions required to access {@link Uri} in
8185     * the given {@link ProviderInfo}. Final permission checking is always done
8186     * in {@link ContentProvider}.
8187     */
8188    private final boolean checkHoldingPermissionsLocked(
8189            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8190        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8191                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8192        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8193            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8194                    != PERMISSION_GRANTED) {
8195                return false;
8196            }
8197        }
8198        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8199    }
8200
8201    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8202            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8203        if (pi.applicationInfo.uid == uid) {
8204            return true;
8205        } else if (!pi.exported) {
8206            return false;
8207        }
8208
8209        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8210        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8211        try {
8212            // check if target holds top-level <provider> permissions
8213            if (!readMet && pi.readPermission != null && considerUidPermissions
8214                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8215                readMet = true;
8216            }
8217            if (!writeMet && pi.writePermission != null && considerUidPermissions
8218                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8219                writeMet = true;
8220            }
8221
8222            // track if unprotected read/write is allowed; any denied
8223            // <path-permission> below removes this ability
8224            boolean allowDefaultRead = pi.readPermission == null;
8225            boolean allowDefaultWrite = pi.writePermission == null;
8226
8227            // check if target holds any <path-permission> that match uri
8228            final PathPermission[] pps = pi.pathPermissions;
8229            if (pps != null) {
8230                final String path = grantUri.uri.getPath();
8231                int i = pps.length;
8232                while (i > 0 && (!readMet || !writeMet)) {
8233                    i--;
8234                    PathPermission pp = pps[i];
8235                    if (pp.match(path)) {
8236                        if (!readMet) {
8237                            final String pprperm = pp.getReadPermission();
8238                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8239                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8240                                    + ": match=" + pp.match(path)
8241                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8242                            if (pprperm != null) {
8243                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8244                                        == PERMISSION_GRANTED) {
8245                                    readMet = true;
8246                                } else {
8247                                    allowDefaultRead = false;
8248                                }
8249                            }
8250                        }
8251                        if (!writeMet) {
8252                            final String ppwperm = pp.getWritePermission();
8253                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8254                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8255                                    + ": match=" + pp.match(path)
8256                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8257                            if (ppwperm != null) {
8258                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8259                                        == PERMISSION_GRANTED) {
8260                                    writeMet = true;
8261                                } else {
8262                                    allowDefaultWrite = false;
8263                                }
8264                            }
8265                        }
8266                    }
8267                }
8268            }
8269
8270            // grant unprotected <provider> read/write, if not blocked by
8271            // <path-permission> above
8272            if (allowDefaultRead) readMet = true;
8273            if (allowDefaultWrite) writeMet = true;
8274
8275        } catch (RemoteException e) {
8276            return false;
8277        }
8278
8279        return readMet && writeMet;
8280    }
8281
8282    public boolean isAppStartModeDisabled(int uid, String packageName) {
8283        synchronized (this) {
8284            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8285                    == ActivityManager.APP_START_MODE_DISABLED;
8286        }
8287    }
8288
8289    // Unified app-op and target sdk check
8290    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8291        // Apps that target O+ are always subject to background check
8292        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8293            if (DEBUG_BACKGROUND_CHECK) {
8294                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8295            }
8296            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8297        }
8298        // ...and legacy apps get an AppOp check
8299        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8300                uid, packageName);
8301        if (DEBUG_BACKGROUND_CHECK) {
8302            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8303        }
8304        switch (appop) {
8305            case AppOpsManager.MODE_ALLOWED:
8306                return ActivityManager.APP_START_MODE_NORMAL;
8307            case AppOpsManager.MODE_IGNORED:
8308                return ActivityManager.APP_START_MODE_DELAYED;
8309            default:
8310                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8311        }
8312    }
8313
8314    // Service launch is available to apps with run-in-background exemptions but
8315    // some other background operations are not.  If we're doing a check
8316    // of service-launch policy, allow those callers to proceed unrestricted.
8317    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8318        // Persistent app?
8319        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8320            if (DEBUG_BACKGROUND_CHECK) {
8321                Slog.i(TAG, "App " + uid + "/" + packageName
8322                        + " is persistent; not restricted in background");
8323            }
8324            return ActivityManager.APP_START_MODE_NORMAL;
8325        }
8326
8327        // Non-persistent but background whitelisted?
8328        if (uidOnBackgroundWhitelist(uid)) {
8329            if (DEBUG_BACKGROUND_CHECK) {
8330                Slog.i(TAG, "App " + uid + "/" + packageName
8331                        + " on background whitelist; not restricted in background");
8332            }
8333            return ActivityManager.APP_START_MODE_NORMAL;
8334        }
8335
8336        // Is this app on the battery whitelist?
8337        if (isOnDeviceIdleWhitelistLocked(uid)) {
8338            if (DEBUG_BACKGROUND_CHECK) {
8339                Slog.i(TAG, "App " + uid + "/" + packageName
8340                        + " on idle whitelist; not restricted in background");
8341            }
8342            return ActivityManager.APP_START_MODE_NORMAL;
8343        }
8344
8345        // None of the service-policy criteria apply, so we apply the common criteria
8346        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8347    }
8348
8349    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8350            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8351        UidRecord uidRec = mActiveUids.get(uid);
8352        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8353                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8354                + (uidRec != null ? uidRec.idle : false));
8355        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8356            boolean ephemeral;
8357            if (uidRec == null) {
8358                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8359                        UserHandle.getUserId(uid), packageName);
8360            } else {
8361                ephemeral = uidRec.ephemeral;
8362            }
8363
8364            if (ephemeral) {
8365                // We are hard-core about ephemeral apps not running in the background.
8366                return ActivityManager.APP_START_MODE_DISABLED;
8367            } else {
8368                if (disabledOnly) {
8369                    // The caller is only interested in whether app starts are completely
8370                    // disabled for the given package (that is, it is an instant app).  So
8371                    // we don't need to go further, which is all just seeing if we should
8372                    // apply a "delayed" mode for a regular app.
8373                    return ActivityManager.APP_START_MODE_NORMAL;
8374                }
8375                final int startMode = (alwaysRestrict)
8376                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8377                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8378                                packageTargetSdk);
8379                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8380                        + " pkg=" + packageName + " startMode=" + startMode
8381                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8382                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8383                    // This is an old app that has been forced into a "compatible as possible"
8384                    // mode of background check.  To increase compatibility, we will allow other
8385                    // foreground apps to cause its services to start.
8386                    if (callingPid >= 0) {
8387                        ProcessRecord proc;
8388                        synchronized (mPidsSelfLocked) {
8389                            proc = mPidsSelfLocked.get(callingPid);
8390                        }
8391                        if (proc != null && proc.curProcState
8392                                < ActivityManager.PROCESS_STATE_RECEIVER) {
8393                            // Whoever is instigating this is in the foreground, so we will allow it
8394                            // to go through.
8395                            return ActivityManager.APP_START_MODE_NORMAL;
8396                        }
8397                    }
8398                }
8399                return startMode;
8400            }
8401        }
8402        return ActivityManager.APP_START_MODE_NORMAL;
8403    }
8404
8405    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8406        final int appId = UserHandle.getAppId(uid);
8407        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8408                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8409                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8410    }
8411
8412    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8413        ProviderInfo pi = null;
8414        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8415        if (cpr != null) {
8416            pi = cpr.info;
8417        } else {
8418            try {
8419                pi = AppGlobals.getPackageManager().resolveContentProvider(
8420                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8421                        userHandle);
8422            } catch (RemoteException ex) {
8423            }
8424        }
8425        return pi;
8426    }
8427
8428    void grantEphemeralAccessLocked(int userId, Intent intent,
8429            int targetAppId, int ephemeralAppId) {
8430        getPackageManagerInternalLocked().
8431                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8432    }
8433
8434    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8435        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8436        if (targetUris != null) {
8437            return targetUris.get(grantUri);
8438        }
8439        return null;
8440    }
8441
8442    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8443            String targetPkg, int targetUid, GrantUri grantUri) {
8444        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8445        if (targetUris == null) {
8446            targetUris = Maps.newArrayMap();
8447            mGrantedUriPermissions.put(targetUid, targetUris);
8448        }
8449
8450        UriPermission perm = targetUris.get(grantUri);
8451        if (perm == null) {
8452            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8453            targetUris.put(grantUri, perm);
8454        }
8455
8456        return perm;
8457    }
8458
8459    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8460            final int modeFlags) {
8461        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8462        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8463                : UriPermission.STRENGTH_OWNED;
8464
8465        // Root gets to do everything.
8466        if (uid == 0) {
8467            return true;
8468        }
8469
8470        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8471        if (perms == null) return false;
8472
8473        // First look for exact match
8474        final UriPermission exactPerm = perms.get(grantUri);
8475        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8476            return true;
8477        }
8478
8479        // No exact match, look for prefixes
8480        final int N = perms.size();
8481        for (int i = 0; i < N; i++) {
8482            final UriPermission perm = perms.valueAt(i);
8483            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8484                    && perm.getStrength(modeFlags) >= minStrength) {
8485                return true;
8486            }
8487        }
8488
8489        return false;
8490    }
8491
8492    /**
8493     * @param uri This uri must NOT contain an embedded userId.
8494     * @param userId The userId in which the uri is to be resolved.
8495     */
8496    @Override
8497    public int checkUriPermission(Uri uri, int pid, int uid,
8498            final int modeFlags, int userId, IBinder callerToken) {
8499        enforceNotIsolatedCaller("checkUriPermission");
8500
8501        // Another redirected-binder-call permissions check as in
8502        // {@link checkPermissionWithToken}.
8503        Identity tlsIdentity = sCallerIdentity.get();
8504        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8505            uid = tlsIdentity.uid;
8506            pid = tlsIdentity.pid;
8507        }
8508
8509        // Our own process gets to do everything.
8510        if (pid == MY_PID) {
8511            return PackageManager.PERMISSION_GRANTED;
8512        }
8513        synchronized (this) {
8514            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8515                    ? PackageManager.PERMISSION_GRANTED
8516                    : PackageManager.PERMISSION_DENIED;
8517        }
8518    }
8519
8520    /**
8521     * Check if the targetPkg can be granted permission to access uri by
8522     * the callingUid using the given modeFlags.  Throws a security exception
8523     * if callingUid is not allowed to do this.  Returns the uid of the target
8524     * if the URI permission grant should be performed; returns -1 if it is not
8525     * needed (for example targetPkg already has permission to access the URI).
8526     * If you already know the uid of the target, you can supply it in
8527     * lastTargetUid else set that to -1.
8528     */
8529    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8530            final int modeFlags, int lastTargetUid) {
8531        if (!Intent.isAccessUriMode(modeFlags)) {
8532            return -1;
8533        }
8534
8535        if (targetPkg != null) {
8536            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8537                    "Checking grant " + targetPkg + " permission to " + grantUri);
8538        }
8539
8540        final IPackageManager pm = AppGlobals.getPackageManager();
8541
8542        // If this is not a content: uri, we can't do anything with it.
8543        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8544            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8545                    "Can't grant URI permission for non-content URI: " + grantUri);
8546            return -1;
8547        }
8548
8549        final String authority = grantUri.uri.getAuthority();
8550        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8551                MATCH_DEBUG_TRIAGED_MISSING);
8552        if (pi == null) {
8553            Slog.w(TAG, "No content provider found for permission check: " +
8554                    grantUri.uri.toSafeString());
8555            return -1;
8556        }
8557
8558        int targetUid = lastTargetUid;
8559        if (targetUid < 0 && targetPkg != null) {
8560            try {
8561                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8562                        UserHandle.getUserId(callingUid));
8563                if (targetUid < 0) {
8564                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8565                            "Can't grant URI permission no uid for: " + targetPkg);
8566                    return -1;
8567                }
8568            } catch (RemoteException ex) {
8569                return -1;
8570            }
8571        }
8572
8573        // If we're extending a persistable grant, then we always need to create
8574        // the grant data structure so that take/release APIs work
8575        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8576            return targetUid;
8577        }
8578
8579        if (targetUid >= 0) {
8580            // First...  does the target actually need this permission?
8581            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8582                // No need to grant the target this permission.
8583                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8584                        "Target " + targetPkg + " already has full permission to " + grantUri);
8585                return -1;
8586            }
8587        } else {
8588            // First...  there is no target package, so can anyone access it?
8589            boolean allowed = pi.exported;
8590            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8591                if (pi.readPermission != null) {
8592                    allowed = false;
8593                }
8594            }
8595            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8596                if (pi.writePermission != null) {
8597                    allowed = false;
8598                }
8599            }
8600            if (allowed) {
8601                return -1;
8602            }
8603        }
8604
8605        /* There is a special cross user grant if:
8606         * - The target is on another user.
8607         * - Apps on the current user can access the uri without any uid permissions.
8608         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8609         * grant uri permissions.
8610         */
8611        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8612                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8613                modeFlags, false /*without considering the uid permissions*/);
8614
8615        // Second...  is the provider allowing granting of URI permissions?
8616        if (!specialCrossUserGrant) {
8617            if (!pi.grantUriPermissions) {
8618                throw new SecurityException("Provider " + pi.packageName
8619                        + "/" + pi.name
8620                        + " does not allow granting of Uri permissions (uri "
8621                        + grantUri + ")");
8622            }
8623            if (pi.uriPermissionPatterns != null) {
8624                final int N = pi.uriPermissionPatterns.length;
8625                boolean allowed = false;
8626                for (int i=0; i<N; i++) {
8627                    if (pi.uriPermissionPatterns[i] != null
8628                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8629                        allowed = true;
8630                        break;
8631                    }
8632                }
8633                if (!allowed) {
8634                    throw new SecurityException("Provider " + pi.packageName
8635                            + "/" + pi.name
8636                            + " does not allow granting of permission to path of Uri "
8637                            + grantUri);
8638                }
8639            }
8640        }
8641
8642        // Third...  does the caller itself have permission to access
8643        // this uri?
8644        final int callingAppId = UserHandle.getAppId(callingUid);
8645        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8646            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8647                // Exempted authority for cropping user photos in Settings app
8648            } else {
8649                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8650                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8651                return -1;
8652            }
8653        }
8654        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8655            // Require they hold a strong enough Uri permission
8656            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8657                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8658                    throw new SecurityException(
8659                            "UID " + callingUid + " does not have permission to " + grantUri
8660                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8661                                    + "or related APIs");
8662                } else {
8663                    throw new SecurityException(
8664                            "UID " + callingUid + " does not have permission to " + grantUri);
8665                }
8666            }
8667        }
8668        return targetUid;
8669    }
8670
8671    /**
8672     * @param uri This uri must NOT contain an embedded userId.
8673     * @param userId The userId in which the uri is to be resolved.
8674     */
8675    @Override
8676    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8677            final int modeFlags, int userId) {
8678        enforceNotIsolatedCaller("checkGrantUriPermission");
8679        synchronized(this) {
8680            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8681                    new GrantUri(userId, uri, false), modeFlags, -1);
8682        }
8683    }
8684
8685    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8686            final int modeFlags, UriPermissionOwner owner) {
8687        if (!Intent.isAccessUriMode(modeFlags)) {
8688            return;
8689        }
8690
8691        // So here we are: the caller has the assumed permission
8692        // to the uri, and the target doesn't.  Let's now give this to
8693        // the target.
8694
8695        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8696                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8697
8698        final String authority = grantUri.uri.getAuthority();
8699        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8700                MATCH_DEBUG_TRIAGED_MISSING);
8701        if (pi == null) {
8702            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8703            return;
8704        }
8705
8706        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8707            grantUri.prefix = true;
8708        }
8709        final UriPermission perm = findOrCreateUriPermissionLocked(
8710                pi.packageName, targetPkg, targetUid, grantUri);
8711        perm.grantModes(modeFlags, owner);
8712    }
8713
8714    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8715            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8716        if (targetPkg == null) {
8717            throw new NullPointerException("targetPkg");
8718        }
8719        int targetUid;
8720        final IPackageManager pm = AppGlobals.getPackageManager();
8721        try {
8722            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8723        } catch (RemoteException ex) {
8724            return;
8725        }
8726
8727        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8728                targetUid);
8729        if (targetUid < 0) {
8730            return;
8731        }
8732
8733        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8734                owner);
8735    }
8736
8737    static class NeededUriGrants extends ArrayList<GrantUri> {
8738        final String targetPkg;
8739        final int targetUid;
8740        final int flags;
8741
8742        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8743            this.targetPkg = targetPkg;
8744            this.targetUid = targetUid;
8745            this.flags = flags;
8746        }
8747    }
8748
8749    /**
8750     * Like checkGrantUriPermissionLocked, but takes an Intent.
8751     */
8752    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8753            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8754        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8755                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8756                + " clip=" + (intent != null ? intent.getClipData() : null)
8757                + " from " + intent + "; flags=0x"
8758                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8759
8760        if (targetPkg == null) {
8761            throw new NullPointerException("targetPkg");
8762        }
8763
8764        if (intent == null) {
8765            return null;
8766        }
8767        Uri data = intent.getData();
8768        ClipData clip = intent.getClipData();
8769        if (data == null && clip == null) {
8770            return null;
8771        }
8772        // Default userId for uris in the intent (if they don't specify it themselves)
8773        int contentUserHint = intent.getContentUserHint();
8774        if (contentUserHint == UserHandle.USER_CURRENT) {
8775            contentUserHint = UserHandle.getUserId(callingUid);
8776        }
8777        final IPackageManager pm = AppGlobals.getPackageManager();
8778        int targetUid;
8779        if (needed != null) {
8780            targetUid = needed.targetUid;
8781        } else {
8782            try {
8783                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8784                        targetUserId);
8785            } catch (RemoteException ex) {
8786                return null;
8787            }
8788            if (targetUid < 0) {
8789                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8790                        "Can't grant URI permission no uid for: " + targetPkg
8791                        + " on user " + targetUserId);
8792                return null;
8793            }
8794        }
8795        if (data != null) {
8796            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8797            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8798                    targetUid);
8799            if (targetUid > 0) {
8800                if (needed == null) {
8801                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8802                }
8803                needed.add(grantUri);
8804            }
8805        }
8806        if (clip != null) {
8807            for (int i=0; i<clip.getItemCount(); i++) {
8808                Uri uri = clip.getItemAt(i).getUri();
8809                if (uri != null) {
8810                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8811                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8812                            targetUid);
8813                    if (targetUid > 0) {
8814                        if (needed == null) {
8815                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8816                        }
8817                        needed.add(grantUri);
8818                    }
8819                } else {
8820                    Intent clipIntent = clip.getItemAt(i).getIntent();
8821                    if (clipIntent != null) {
8822                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8823                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8824                        if (newNeeded != null) {
8825                            needed = newNeeded;
8826                        }
8827                    }
8828                }
8829            }
8830        }
8831
8832        return needed;
8833    }
8834
8835    /**
8836     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8837     */
8838    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8839            UriPermissionOwner owner) {
8840        if (needed != null) {
8841            for (int i=0; i<needed.size(); i++) {
8842                GrantUri grantUri = needed.get(i);
8843                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8844                        grantUri, needed.flags, owner);
8845            }
8846        }
8847    }
8848
8849    void grantUriPermissionFromIntentLocked(int callingUid,
8850            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8851        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8852                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8853        if (needed == null) {
8854            return;
8855        }
8856
8857        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8858    }
8859
8860    /**
8861     * @param uri This uri must NOT contain an embedded userId.
8862     * @param userId The userId in which the uri is to be resolved.
8863     */
8864    @Override
8865    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8866            final int modeFlags, int userId) {
8867        enforceNotIsolatedCaller("grantUriPermission");
8868        GrantUri grantUri = new GrantUri(userId, uri, false);
8869        synchronized(this) {
8870            final ProcessRecord r = getRecordForAppLocked(caller);
8871            if (r == null) {
8872                throw new SecurityException("Unable to find app for caller "
8873                        + caller
8874                        + " when granting permission to uri " + grantUri);
8875            }
8876            if (targetPkg == null) {
8877                throw new IllegalArgumentException("null target");
8878            }
8879            if (grantUri == null) {
8880                throw new IllegalArgumentException("null uri");
8881            }
8882
8883            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8884                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8885                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8886                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8887
8888            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8889                    UserHandle.getUserId(r.uid));
8890        }
8891    }
8892
8893    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8894        if (perm.modeFlags == 0) {
8895            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8896                    perm.targetUid);
8897            if (perms != null) {
8898                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8899                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8900
8901                perms.remove(perm.uri);
8902                if (perms.isEmpty()) {
8903                    mGrantedUriPermissions.remove(perm.targetUid);
8904                }
8905            }
8906        }
8907    }
8908
8909    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
8910            final int modeFlags) {
8911        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8912                "Revoking all granted permissions to " + grantUri);
8913
8914        final IPackageManager pm = AppGlobals.getPackageManager();
8915        final String authority = grantUri.uri.getAuthority();
8916        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8917                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8918        if (pi == null) {
8919            Slog.w(TAG, "No content provider found for permission revoke: "
8920                    + grantUri.toSafeString());
8921            return;
8922        }
8923
8924        // Does the caller have this permission on the URI?
8925        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8926            // If they don't have direct access to the URI, then revoke any
8927            // ownerless URI permissions that have been granted to them.
8928            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8929            if (perms != null) {
8930                boolean persistChanged = false;
8931                for (int i = perms.size()-1; i >= 0; i--) {
8932                    final UriPermission perm = perms.valueAt(i);
8933                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
8934                        continue;
8935                    }
8936                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8937                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8938                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8939                                "Revoking non-owned " + perm.targetUid
8940                                + " permission to " + perm.uri);
8941                        persistChanged |= perm.revokeModes(
8942                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8943                        if (perm.modeFlags == 0) {
8944                            perms.removeAt(i);
8945                        }
8946                    }
8947                }
8948                if (perms.isEmpty()) {
8949                    mGrantedUriPermissions.remove(callingUid);
8950                }
8951                if (persistChanged) {
8952                    schedulePersistUriGrants();
8953                }
8954            }
8955            return;
8956        }
8957
8958        boolean persistChanged = false;
8959
8960        // Go through all of the permissions and remove any that match.
8961        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
8962            final int targetUid = mGrantedUriPermissions.keyAt(i);
8963            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8964
8965            for (int j = perms.size()-1; j >= 0; j--) {
8966                final UriPermission perm = perms.valueAt(j);
8967                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
8968                    continue;
8969                }
8970                if (perm.uri.sourceUserId == grantUri.sourceUserId
8971                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8972                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8973                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8974                    persistChanged |= perm.revokeModes(
8975                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
8976                            targetPackage == null);
8977                    if (perm.modeFlags == 0) {
8978                        perms.removeAt(j);
8979                    }
8980                }
8981            }
8982
8983            if (perms.isEmpty()) {
8984                mGrantedUriPermissions.removeAt(i);
8985            }
8986        }
8987
8988        if (persistChanged) {
8989            schedulePersistUriGrants();
8990        }
8991    }
8992
8993    /**
8994     * @param uri This uri must NOT contain an embedded userId.
8995     * @param userId The userId in which the uri is to be resolved.
8996     */
8997    @Override
8998    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
8999            final int modeFlags, int userId) {
9000        enforceNotIsolatedCaller("revokeUriPermission");
9001        synchronized(this) {
9002            final ProcessRecord r = getRecordForAppLocked(caller);
9003            if (r == null) {
9004                throw new SecurityException("Unable to find app for caller "
9005                        + caller
9006                        + " when revoking permission to uri " + uri);
9007            }
9008            if (uri == null) {
9009                Slog.w(TAG, "revokeUriPermission: null uri");
9010                return;
9011            }
9012
9013            if (!Intent.isAccessUriMode(modeFlags)) {
9014                return;
9015            }
9016
9017            final String authority = uri.getAuthority();
9018            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9019                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9020            if (pi == null) {
9021                Slog.w(TAG, "No content provider found for permission revoke: "
9022                        + uri.toSafeString());
9023                return;
9024            }
9025
9026            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9027                    modeFlags);
9028        }
9029    }
9030
9031    /**
9032     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9033     * given package.
9034     *
9035     * @param packageName Package name to match, or {@code null} to apply to all
9036     *            packages.
9037     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9038     *            to all users.
9039     * @param persistable If persistable grants should be removed.
9040     */
9041    private void removeUriPermissionsForPackageLocked(
9042            String packageName, int userHandle, boolean persistable) {
9043        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9044            throw new IllegalArgumentException("Must narrow by either package or user");
9045        }
9046
9047        boolean persistChanged = false;
9048
9049        int N = mGrantedUriPermissions.size();
9050        for (int i = 0; i < N; i++) {
9051            final int targetUid = mGrantedUriPermissions.keyAt(i);
9052            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9053
9054            // Only inspect grants matching user
9055            if (userHandle == UserHandle.USER_ALL
9056                    || userHandle == UserHandle.getUserId(targetUid)) {
9057                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9058                    final UriPermission perm = it.next();
9059
9060                    // Only inspect grants matching package
9061                    if (packageName == null || perm.sourcePkg.equals(packageName)
9062                            || perm.targetPkg.equals(packageName)) {
9063                        // Hacky solution as part of fixing a security bug; ignore
9064                        // grants associated with DownloadManager so we don't have
9065                        // to immediately launch it to regrant the permissions
9066                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9067                                && !persistable) continue;
9068
9069                        persistChanged |= perm.revokeModes(persistable
9070                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9071
9072                        // Only remove when no modes remain; any persisted grants
9073                        // will keep this alive.
9074                        if (perm.modeFlags == 0) {
9075                            it.remove();
9076                        }
9077                    }
9078                }
9079
9080                if (perms.isEmpty()) {
9081                    mGrantedUriPermissions.remove(targetUid);
9082                    N--;
9083                    i--;
9084                }
9085            }
9086        }
9087
9088        if (persistChanged) {
9089            schedulePersistUriGrants();
9090        }
9091    }
9092
9093    @Override
9094    public IBinder newUriPermissionOwner(String name) {
9095        enforceNotIsolatedCaller("newUriPermissionOwner");
9096        synchronized(this) {
9097            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9098            return owner.getExternalTokenLocked();
9099        }
9100    }
9101
9102    @Override
9103    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9104        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9105        synchronized(this) {
9106            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9107            if (r == null) {
9108                throw new IllegalArgumentException("Activity does not exist; token="
9109                        + activityToken);
9110            }
9111            return r.getUriPermissionsLocked().getExternalTokenLocked();
9112        }
9113    }
9114    /**
9115     * @param uri This uri must NOT contain an embedded userId.
9116     * @param sourceUserId The userId in which the uri is to be resolved.
9117     * @param targetUserId The userId of the app that receives the grant.
9118     */
9119    @Override
9120    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9121            final int modeFlags, int sourceUserId, int targetUserId) {
9122        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9123                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9124                "grantUriPermissionFromOwner", null);
9125        synchronized(this) {
9126            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9127            if (owner == null) {
9128                throw new IllegalArgumentException("Unknown owner: " + token);
9129            }
9130            if (fromUid != Binder.getCallingUid()) {
9131                if (Binder.getCallingUid() != myUid()) {
9132                    // Only system code can grant URI permissions on behalf
9133                    // of other users.
9134                    throw new SecurityException("nice try");
9135                }
9136            }
9137            if (targetPkg == null) {
9138                throw new IllegalArgumentException("null target");
9139            }
9140            if (uri == null) {
9141                throw new IllegalArgumentException("null uri");
9142            }
9143
9144            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9145                    modeFlags, owner, targetUserId);
9146        }
9147    }
9148
9149    /**
9150     * @param uri This uri must NOT contain an embedded userId.
9151     * @param userId The userId in which the uri is to be resolved.
9152     */
9153    @Override
9154    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9155        synchronized(this) {
9156            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9157            if (owner == null) {
9158                throw new IllegalArgumentException("Unknown owner: " + token);
9159            }
9160
9161            if (uri == null) {
9162                owner.removeUriPermissionsLocked(mode);
9163            } else {
9164                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9165                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9166            }
9167        }
9168    }
9169
9170    private void schedulePersistUriGrants() {
9171        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9172            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9173                    10 * DateUtils.SECOND_IN_MILLIS);
9174        }
9175    }
9176
9177    private void writeGrantedUriPermissions() {
9178        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9179
9180        // Snapshot permissions so we can persist without lock
9181        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9182        synchronized (this) {
9183            final int size = mGrantedUriPermissions.size();
9184            for (int i = 0; i < size; i++) {
9185                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9186                for (UriPermission perm : perms.values()) {
9187                    if (perm.persistedModeFlags != 0) {
9188                        persist.add(perm.snapshot());
9189                    }
9190                }
9191            }
9192        }
9193
9194        FileOutputStream fos = null;
9195        try {
9196            fos = mGrantFile.startWrite();
9197
9198            XmlSerializer out = new FastXmlSerializer();
9199            out.setOutput(fos, StandardCharsets.UTF_8.name());
9200            out.startDocument(null, true);
9201            out.startTag(null, TAG_URI_GRANTS);
9202            for (UriPermission.Snapshot perm : persist) {
9203                out.startTag(null, TAG_URI_GRANT);
9204                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9205                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9206                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9207                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9208                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9209                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9210                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9211                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9212                out.endTag(null, TAG_URI_GRANT);
9213            }
9214            out.endTag(null, TAG_URI_GRANTS);
9215            out.endDocument();
9216
9217            mGrantFile.finishWrite(fos);
9218        } catch (IOException e) {
9219            if (fos != null) {
9220                mGrantFile.failWrite(fos);
9221            }
9222        }
9223    }
9224
9225    private void readGrantedUriPermissionsLocked() {
9226        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9227
9228        final long now = System.currentTimeMillis();
9229
9230        FileInputStream fis = null;
9231        try {
9232            fis = mGrantFile.openRead();
9233            final XmlPullParser in = Xml.newPullParser();
9234            in.setInput(fis, StandardCharsets.UTF_8.name());
9235
9236            int type;
9237            while ((type = in.next()) != END_DOCUMENT) {
9238                final String tag = in.getName();
9239                if (type == START_TAG) {
9240                    if (TAG_URI_GRANT.equals(tag)) {
9241                        final int sourceUserId;
9242                        final int targetUserId;
9243                        final int userHandle = readIntAttribute(in,
9244                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9245                        if (userHandle != UserHandle.USER_NULL) {
9246                            // For backwards compatibility.
9247                            sourceUserId = userHandle;
9248                            targetUserId = userHandle;
9249                        } else {
9250                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9251                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9252                        }
9253                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9254                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9255                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9256                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9257                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9258                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9259
9260                        // Sanity check that provider still belongs to source package
9261                        // Both direct boot aware and unaware packages are fine as we
9262                        // will do filtering at query time to avoid multiple parsing.
9263                        final ProviderInfo pi = getProviderInfoLocked(
9264                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9265                                        | MATCH_DIRECT_BOOT_UNAWARE);
9266                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9267                            int targetUid = -1;
9268                            try {
9269                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9270                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9271                            } catch (RemoteException e) {
9272                            }
9273                            if (targetUid != -1) {
9274                                final UriPermission perm = findOrCreateUriPermissionLocked(
9275                                        sourcePkg, targetPkg, targetUid,
9276                                        new GrantUri(sourceUserId, uri, prefix));
9277                                perm.initPersistedModes(modeFlags, createdTime);
9278                            }
9279                        } else {
9280                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9281                                    + " but instead found " + pi);
9282                        }
9283                    }
9284                }
9285            }
9286        } catch (FileNotFoundException e) {
9287            // Missing grants is okay
9288        } catch (IOException e) {
9289            Slog.wtf(TAG, "Failed reading Uri grants", e);
9290        } catch (XmlPullParserException e) {
9291            Slog.wtf(TAG, "Failed reading Uri grants", e);
9292        } finally {
9293            IoUtils.closeQuietly(fis);
9294        }
9295    }
9296
9297    /**
9298     * @param uri This uri must NOT contain an embedded userId.
9299     * @param userId The userId in which the uri is to be resolved.
9300     */
9301    @Override
9302    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9303        enforceNotIsolatedCaller("takePersistableUriPermission");
9304
9305        Preconditions.checkFlagsArgument(modeFlags,
9306                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9307
9308        synchronized (this) {
9309            final int callingUid = Binder.getCallingUid();
9310            boolean persistChanged = false;
9311            GrantUri grantUri = new GrantUri(userId, uri, false);
9312
9313            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9314                    new GrantUri(userId, uri, false));
9315            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9316                    new GrantUri(userId, uri, true));
9317
9318            final boolean exactValid = (exactPerm != null)
9319                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9320            final boolean prefixValid = (prefixPerm != null)
9321                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9322
9323            if (!(exactValid || prefixValid)) {
9324                throw new SecurityException("No persistable permission grants found for UID "
9325                        + callingUid + " and Uri " + grantUri.toSafeString());
9326            }
9327
9328            if (exactValid) {
9329                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9330            }
9331            if (prefixValid) {
9332                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9333            }
9334
9335            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9336
9337            if (persistChanged) {
9338                schedulePersistUriGrants();
9339            }
9340        }
9341    }
9342
9343    /**
9344     * @param uri This uri must NOT contain an embedded userId.
9345     * @param userId The userId in which the uri is to be resolved.
9346     */
9347    @Override
9348    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9349        enforceNotIsolatedCaller("releasePersistableUriPermission");
9350
9351        Preconditions.checkFlagsArgument(modeFlags,
9352                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9353
9354        synchronized (this) {
9355            final int callingUid = Binder.getCallingUid();
9356            boolean persistChanged = false;
9357
9358            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9359                    new GrantUri(userId, uri, false));
9360            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9361                    new GrantUri(userId, uri, true));
9362            if (exactPerm == null && prefixPerm == null) {
9363                throw new SecurityException("No permission grants found for UID " + callingUid
9364                        + " and Uri " + uri.toSafeString());
9365            }
9366
9367            if (exactPerm != null) {
9368                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9369                removeUriPermissionIfNeededLocked(exactPerm);
9370            }
9371            if (prefixPerm != null) {
9372                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9373                removeUriPermissionIfNeededLocked(prefixPerm);
9374            }
9375
9376            if (persistChanged) {
9377                schedulePersistUriGrants();
9378            }
9379        }
9380    }
9381
9382    /**
9383     * Prune any older {@link UriPermission} for the given UID until outstanding
9384     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9385     *
9386     * @return if any mutations occured that require persisting.
9387     */
9388    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9389        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9390        if (perms == null) return false;
9391        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9392
9393        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9394        for (UriPermission perm : perms.values()) {
9395            if (perm.persistedModeFlags != 0) {
9396                persisted.add(perm);
9397            }
9398        }
9399
9400        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9401        if (trimCount <= 0) return false;
9402
9403        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9404        for (int i = 0; i < trimCount; i++) {
9405            final UriPermission perm = persisted.get(i);
9406
9407            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9408                    "Trimming grant created at " + perm.persistedCreateTime);
9409
9410            perm.releasePersistableModes(~0);
9411            removeUriPermissionIfNeededLocked(perm);
9412        }
9413
9414        return true;
9415    }
9416
9417    @Override
9418    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9419            String packageName, boolean incoming) {
9420        enforceNotIsolatedCaller("getPersistedUriPermissions");
9421        Preconditions.checkNotNull(packageName, "packageName");
9422
9423        final int callingUid = Binder.getCallingUid();
9424        final int callingUserId = UserHandle.getUserId(callingUid);
9425        final IPackageManager pm = AppGlobals.getPackageManager();
9426        try {
9427            final int packageUid = pm.getPackageUid(packageName,
9428                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9429            if (packageUid != callingUid) {
9430                throw new SecurityException(
9431                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9432            }
9433        } catch (RemoteException e) {
9434            throw new SecurityException("Failed to verify package name ownership");
9435        }
9436
9437        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9438        synchronized (this) {
9439            if (incoming) {
9440                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9441                        callingUid);
9442                if (perms == null) {
9443                    Slog.w(TAG, "No permission grants found for " + packageName);
9444                } else {
9445                    for (UriPermission perm : perms.values()) {
9446                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9447                            result.add(perm.buildPersistedPublicApiObject());
9448                        }
9449                    }
9450                }
9451            } else {
9452                final int size = mGrantedUriPermissions.size();
9453                for (int i = 0; i < size; i++) {
9454                    final ArrayMap<GrantUri, UriPermission> perms =
9455                            mGrantedUriPermissions.valueAt(i);
9456                    for (UriPermission perm : perms.values()) {
9457                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9458                            result.add(perm.buildPersistedPublicApiObject());
9459                        }
9460                    }
9461                }
9462            }
9463        }
9464        return new ParceledListSlice<android.content.UriPermission>(result);
9465    }
9466
9467    @Override
9468    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9469            String packageName, int userId) {
9470        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9471                "getGrantedUriPermissions");
9472
9473        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9474        synchronized (this) {
9475            final int size = mGrantedUriPermissions.size();
9476            for (int i = 0; i < size; i++) {
9477                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9478                for (UriPermission perm : perms.values()) {
9479                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9480                            && perm.persistedModeFlags != 0) {
9481                        result.add(perm.buildPersistedPublicApiObject());
9482                    }
9483                }
9484            }
9485        }
9486        return new ParceledListSlice<android.content.UriPermission>(result);
9487    }
9488
9489    @Override
9490    public void clearGrantedUriPermissions(String packageName, int userId) {
9491        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9492                "clearGrantedUriPermissions");
9493        removeUriPermissionsForPackageLocked(packageName, userId, true);
9494    }
9495
9496    @Override
9497    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9498        synchronized (this) {
9499            ProcessRecord app =
9500                who != null ? getRecordForAppLocked(who) : null;
9501            if (app == null) return;
9502
9503            Message msg = Message.obtain();
9504            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9505            msg.obj = app;
9506            msg.arg1 = waiting ? 1 : 0;
9507            mUiHandler.sendMessage(msg);
9508        }
9509    }
9510
9511    @Override
9512    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9513        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9514        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9515        outInfo.availMem = getFreeMemory();
9516        outInfo.totalMem = getTotalMemory();
9517        outInfo.threshold = homeAppMem;
9518        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9519        outInfo.hiddenAppThreshold = cachedAppMem;
9520        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9521                ProcessList.SERVICE_ADJ);
9522        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9523                ProcessList.VISIBLE_APP_ADJ);
9524        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9525                ProcessList.FOREGROUND_APP_ADJ);
9526    }
9527
9528    // =========================================================
9529    // TASK MANAGEMENT
9530    // =========================================================
9531
9532    @Override
9533    public List<IBinder> getAppTasks(String callingPackage) {
9534        int callingUid = Binder.getCallingUid();
9535        long ident = Binder.clearCallingIdentity();
9536
9537        synchronized(this) {
9538            ArrayList<IBinder> list = new ArrayList<IBinder>();
9539            try {
9540                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9541
9542                final int N = mRecentTasks.size();
9543                for (int i = 0; i < N; i++) {
9544                    TaskRecord tr = mRecentTasks.get(i);
9545                    // Skip tasks that do not match the caller.  We don't need to verify
9546                    // callingPackage, because we are also limiting to callingUid and know
9547                    // that will limit to the correct security sandbox.
9548                    if (tr.effectiveUid != callingUid) {
9549                        continue;
9550                    }
9551                    Intent intent = tr.getBaseIntent();
9552                    if (intent == null ||
9553                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9554                        continue;
9555                    }
9556                    ActivityManager.RecentTaskInfo taskInfo =
9557                            createRecentTaskInfoFromTaskRecord(tr);
9558                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9559                    list.add(taskImpl.asBinder());
9560                }
9561            } finally {
9562                Binder.restoreCallingIdentity(ident);
9563            }
9564            return list;
9565        }
9566    }
9567
9568    @Override
9569    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9570        final int callingUid = Binder.getCallingUid();
9571        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9572
9573        synchronized(this) {
9574            if (DEBUG_ALL) Slog.v(
9575                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9576
9577            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9578                    callingUid);
9579
9580            // TODO: Improve with MRU list from all ActivityStacks.
9581            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9582        }
9583
9584        return list;
9585    }
9586
9587    /**
9588     * Creates a new RecentTaskInfo from a TaskRecord.
9589     */
9590    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9591        // Update the task description to reflect any changes in the task stack
9592        tr.updateTaskDescription();
9593
9594        // Compose the recent task info
9595        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9596        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9597        rti.persistentId = tr.taskId;
9598        rti.baseIntent = new Intent(tr.getBaseIntent());
9599        rti.origActivity = tr.origActivity;
9600        rti.realActivity = tr.realActivity;
9601        rti.description = tr.lastDescription;
9602        rti.stackId = tr.getStackId();
9603        rti.userId = tr.userId;
9604        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9605        rti.firstActiveTime = tr.firstActiveTime;
9606        rti.lastActiveTime = tr.lastActiveTime;
9607        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9608        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9609        rti.numActivities = 0;
9610        if (tr.mBounds != null) {
9611            rti.bounds = new Rect(tr.mBounds);
9612        }
9613        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9614        rti.resizeMode = tr.mResizeMode;
9615
9616        ActivityRecord base = null;
9617        ActivityRecord top = null;
9618        ActivityRecord tmp;
9619
9620        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9621            tmp = tr.mActivities.get(i);
9622            if (tmp.finishing) {
9623                continue;
9624            }
9625            base = tmp;
9626            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9627                top = base;
9628            }
9629            rti.numActivities++;
9630        }
9631
9632        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9633        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9634
9635        return rti;
9636    }
9637
9638    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9639        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9640                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9641        if (!allowed) {
9642            if (checkPermission(android.Manifest.permission.GET_TASKS,
9643                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9644                // Temporary compatibility: some existing apps on the system image may
9645                // still be requesting the old permission and not switched to the new
9646                // one; if so, we'll still allow them full access.  This means we need
9647                // to see if they are holding the old permission and are a system app.
9648                try {
9649                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9650                        allowed = true;
9651                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9652                                + " is using old GET_TASKS but privileged; allowing");
9653                    }
9654                } catch (RemoteException e) {
9655                }
9656            }
9657        }
9658        if (!allowed) {
9659            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9660                    + " does not hold REAL_GET_TASKS; limiting output");
9661        }
9662        return allowed;
9663    }
9664
9665    @Override
9666    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9667            int userId) {
9668        final int callingUid = Binder.getCallingUid();
9669        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9670                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9671
9672        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9673        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9674        synchronized (this) {
9675            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9676                    callingUid);
9677            final boolean detailed = checkCallingPermission(
9678                    android.Manifest.permission.GET_DETAILED_TASKS)
9679                    == PackageManager.PERMISSION_GRANTED;
9680
9681            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9682                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9683                return ParceledListSlice.emptyList();
9684            }
9685            mRecentTasks.loadUserRecentsLocked(userId);
9686
9687            final int recentsCount = mRecentTasks.size();
9688            ArrayList<ActivityManager.RecentTaskInfo> res =
9689                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9690
9691            final Set<Integer> includedUsers;
9692            if (includeProfiles) {
9693                includedUsers = mUserController.getProfileIds(userId);
9694            } else {
9695                includedUsers = new HashSet<>();
9696            }
9697            includedUsers.add(Integer.valueOf(userId));
9698
9699            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9700                TaskRecord tr = mRecentTasks.get(i);
9701                // Only add calling user or related users recent tasks
9702                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9703                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9704                    continue;
9705                }
9706
9707                if (tr.realActivitySuspended) {
9708                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9709                    continue;
9710                }
9711
9712                // Return the entry if desired by the caller.  We always return
9713                // the first entry, because callers always expect this to be the
9714                // foreground app.  We may filter others if the caller has
9715                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9716                // we should exclude the entry.
9717
9718                if (i == 0
9719                        || withExcluded
9720                        || (tr.intent == null)
9721                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9722                                == 0)) {
9723                    if (!allowed) {
9724                        // If the caller doesn't have the GET_TASKS permission, then only
9725                        // allow them to see a small subset of tasks -- their own and home.
9726                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9727                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9728                            continue;
9729                        }
9730                    }
9731                    final ActivityStack stack = tr.getStack();
9732                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9733                        if (stack != null && stack.isHomeOrRecentsStack()) {
9734                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9735                                    "Skipping, home or recents stack task: " + tr);
9736                            continue;
9737                        }
9738                    }
9739                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9740                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9741                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9742                                    "Skipping, top task in docked stack: " + tr);
9743                            continue;
9744                        }
9745                    }
9746                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9747                        if (stack != null && stack.isPinnedStack()) {
9748                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9749                                    "Skipping, pinned stack task: " + tr);
9750                            continue;
9751                        }
9752                    }
9753                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9754                        // Don't include auto remove tasks that are finished or finishing.
9755                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9756                                "Skipping, auto-remove without activity: " + tr);
9757                        continue;
9758                    }
9759                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9760                            && !tr.isAvailable) {
9761                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9762                                "Skipping, unavail real act: " + tr);
9763                        continue;
9764                    }
9765
9766                    if (!tr.mUserSetupComplete) {
9767                        // Don't include task launched while user is not done setting-up.
9768                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9769                                "Skipping, user setup not complete: " + tr);
9770                        continue;
9771                    }
9772
9773                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9774                    if (!detailed) {
9775                        rti.baseIntent.replaceExtras((Bundle)null);
9776                    }
9777
9778                    res.add(rti);
9779                    maxNum--;
9780                }
9781            }
9782            return new ParceledListSlice<>(res);
9783        }
9784    }
9785
9786    @Override
9787    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9788        synchronized (this) {
9789            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9790                    "getTaskThumbnail()");
9791            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9792                    id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9793            if (tr != null) {
9794                return tr.getTaskThumbnailLocked();
9795            }
9796        }
9797        return null;
9798    }
9799
9800    @Override
9801    public ActivityManager.TaskDescription getTaskDescription(int id) {
9802        synchronized (this) {
9803            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9804                    "getTaskDescription()");
9805            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9806                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9807            if (tr != null) {
9808                return tr.lastTaskDescription;
9809            }
9810        }
9811        return null;
9812    }
9813
9814    @Override
9815    public int addAppTask(IBinder activityToken, Intent intent,
9816            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9817        final int callingUid = Binder.getCallingUid();
9818        final long callingIdent = Binder.clearCallingIdentity();
9819
9820        try {
9821            synchronized (this) {
9822                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9823                if (r == null) {
9824                    throw new IllegalArgumentException("Activity does not exist; token="
9825                            + activityToken);
9826                }
9827                ComponentName comp = intent.getComponent();
9828                if (comp == null) {
9829                    throw new IllegalArgumentException("Intent " + intent
9830                            + " must specify explicit component");
9831                }
9832                if (thumbnail.getWidth() != mThumbnailWidth
9833                        || thumbnail.getHeight() != mThumbnailHeight) {
9834                    throw new IllegalArgumentException("Bad thumbnail size: got "
9835                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9836                            + mThumbnailWidth + "x" + mThumbnailHeight);
9837                }
9838                if (intent.getSelector() != null) {
9839                    intent.setSelector(null);
9840                }
9841                if (intent.getSourceBounds() != null) {
9842                    intent.setSourceBounds(null);
9843                }
9844                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9845                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9846                        // The caller has added this as an auto-remove task...  that makes no
9847                        // sense, so turn off auto-remove.
9848                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9849                    }
9850                }
9851                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9852                    mLastAddedTaskActivity = null;
9853                }
9854                ActivityInfo ainfo = mLastAddedTaskActivity;
9855                if (ainfo == null) {
9856                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9857                            comp, 0, UserHandle.getUserId(callingUid));
9858                    if (ainfo.applicationInfo.uid != callingUid) {
9859                        throw new SecurityException(
9860                                "Can't add task for another application: target uid="
9861                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9862                    }
9863                }
9864
9865                TaskRecord task = new TaskRecord(this,
9866                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9867                        ainfo, intent, description, new TaskThumbnailInfo());
9868
9869                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9870                if (trimIdx >= 0) {
9871                    // If this would have caused a trim, then we'll abort because that
9872                    // means it would be added at the end of the list but then just removed.
9873                    return INVALID_TASK_ID;
9874                }
9875
9876                final int N = mRecentTasks.size();
9877                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9878                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9879                    tr.removedFromRecents();
9880                }
9881
9882                task.inRecents = true;
9883                mRecentTasks.add(task);
9884                r.getStack().addTask(task, false, "addAppTask");
9885
9886                task.setLastThumbnailLocked(thumbnail);
9887                task.freeLastThumbnail();
9888                return task.taskId;
9889            }
9890        } finally {
9891            Binder.restoreCallingIdentity(callingIdent);
9892        }
9893    }
9894
9895    @Override
9896    public Point getAppTaskThumbnailSize() {
9897        synchronized (this) {
9898            return new Point(mThumbnailWidth,  mThumbnailHeight);
9899        }
9900    }
9901
9902    @Override
9903    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9904        synchronized (this) {
9905            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9906            if (r != null) {
9907                r.setTaskDescription(td);
9908                final TaskRecord task = r.getTask();
9909                task.updateTaskDescription();
9910                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
9911            }
9912        }
9913    }
9914
9915    @Override
9916    public void setTaskResizeable(int taskId, int resizeableMode) {
9917        synchronized (this) {
9918            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9919                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9920            if (task == null) {
9921                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9922                return;
9923            }
9924            task.setResizeMode(resizeableMode);
9925        }
9926    }
9927
9928    @Override
9929    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9930        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9931        long ident = Binder.clearCallingIdentity();
9932        try {
9933            synchronized (this) {
9934                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9935                if (task == null) {
9936                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9937                    return;
9938                }
9939                // Place the task in the right stack if it isn't there already based on
9940                // the requested bounds.
9941                // The stack transition logic is:
9942                // - a null bounds on a freeform task moves that task to fullscreen
9943                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9944                //   that task to freeform
9945                // - otherwise the task is not moved
9946                int stackId = task.getStackId();
9947                if (!StackId.isTaskResizeAllowed(stackId)) {
9948                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9949                }
9950                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9951                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9952                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9953                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9954                }
9955
9956                // Reparent the task to the right stack if necessary
9957                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9958                if (stackId != task.getStackId()) {
9959                    // Defer resume until the task is resized below
9960                    task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
9961                            DEFER_RESUME, "resizeTask");
9962                    preserveWindow = false;
9963                }
9964
9965                // After reparenting (which only resizes the task to the stack bounds), resize the
9966                // task to the actual bounds provided
9967                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
9968            }
9969        } finally {
9970            Binder.restoreCallingIdentity(ident);
9971        }
9972    }
9973
9974    @Override
9975    public Rect getTaskBounds(int taskId) {
9976        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9977        long ident = Binder.clearCallingIdentity();
9978        Rect rect = new Rect();
9979        try {
9980            synchronized (this) {
9981                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
9982                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9983                if (task == null) {
9984                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9985                    return rect;
9986                }
9987                if (task.getStack() != null) {
9988                    // Return the bounds from window manager since it will be adjusted for various
9989                    // things like the presense of a docked stack for tasks that aren't resizeable.
9990                    task.getWindowContainerBounds(rect);
9991                } else {
9992                    // Task isn't in window manager yet since it isn't associated with a stack.
9993                    // Return the persist value from activity manager
9994                    if (task.mBounds != null) {
9995                        rect.set(task.mBounds);
9996                    } else if (task.mLastNonFullscreenBounds != null) {
9997                        rect.set(task.mLastNonFullscreenBounds);
9998                    }
9999                }
10000            }
10001        } finally {
10002            Binder.restoreCallingIdentity(ident);
10003        }
10004        return rect;
10005    }
10006
10007    @Override
10008    public void cancelTaskWindowTransition(int taskId) {
10009        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10010        final long ident = Binder.clearCallingIdentity();
10011        try {
10012            synchronized (this) {
10013                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10014                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10015                if (task == null) {
10016                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10017                    return;
10018                }
10019                task.cancelWindowTransition();
10020            }
10021        } finally {
10022            Binder.restoreCallingIdentity(ident);
10023        }
10024    }
10025
10026    @Override
10027    public void cancelTaskThumbnailTransition(int taskId) {
10028        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10029        final long ident = Binder.clearCallingIdentity();
10030        try {
10031            synchronized (this) {
10032                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10033                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10034                if (task == null) {
10035                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10036                    return;
10037                }
10038                task.cancelThumbnailTransition();
10039            }
10040        } finally {
10041            Binder.restoreCallingIdentity(ident);
10042        }
10043    }
10044
10045    @Override
10046    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10047        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10048        final long ident = Binder.clearCallingIdentity();
10049        try {
10050            final TaskRecord task;
10051            synchronized (this) {
10052                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10053                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10054                if (task == null) {
10055                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10056                    return null;
10057                }
10058            }
10059            // Don't call this while holding the lock as this operation might hit the disk.
10060            return task.getSnapshot(reducedResolution);
10061        } finally {
10062            Binder.restoreCallingIdentity(ident);
10063        }
10064    }
10065
10066    @Override
10067    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10068        if (userId != UserHandle.getCallingUserId()) {
10069            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10070                    "getTaskDescriptionIcon");
10071        }
10072        final File passedIconFile = new File(filePath);
10073        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10074                passedIconFile.getName());
10075        if (!legitIconFile.getPath().equals(filePath)
10076                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10077            throw new IllegalArgumentException("Bad file path: " + filePath
10078                    + " passed for userId " + userId);
10079        }
10080        return mRecentTasks.getTaskDescriptionIcon(filePath);
10081    }
10082
10083    @Override
10084    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10085            throws RemoteException {
10086        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10087        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10088                activityOptions.getCustomInPlaceResId() == 0) {
10089            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10090                    "with valid animation");
10091        }
10092        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10093        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10094                activityOptions.getCustomInPlaceResId());
10095        mWindowManager.executeAppTransition();
10096    }
10097
10098    private void removeTasksByPackageNameLocked(String packageName, int userId) {
10099        // Remove all tasks with activities in the specified package from the list of recent tasks
10100        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10101            TaskRecord tr = mRecentTasks.get(i);
10102            if (tr.userId != userId) continue;
10103
10104            ComponentName cn = tr.intent.getComponent();
10105            if (cn != null && cn.getPackageName().equals(packageName)) {
10106                // If the package name matches, remove the task.
10107                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10108            }
10109        }
10110    }
10111
10112    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10113            int userId) {
10114
10115        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10116            TaskRecord tr = mRecentTasks.get(i);
10117            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10118                continue;
10119            }
10120
10121            ComponentName cn = tr.intent.getComponent();
10122            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10123                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10124            if (sameComponent) {
10125                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10126            }
10127        }
10128    }
10129
10130    @Override
10131    public void removeStack(int stackId) {
10132        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10133        if (StackId.isHomeOrRecentsStack(stackId)) {
10134            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10135        }
10136
10137        synchronized (this) {
10138            final long ident = Binder.clearCallingIdentity();
10139            try {
10140                mStackSupervisor.removeStackLocked(stackId);
10141            } finally {
10142                Binder.restoreCallingIdentity(ident);
10143            }
10144        }
10145    }
10146
10147    @Override
10148    public void moveStackToDisplay(int stackId, int displayId) {
10149        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
10150
10151        synchronized (this) {
10152            final long ident = Binder.clearCallingIdentity();
10153            try {
10154                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10155                        + " to displayId=" + displayId);
10156                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10157            } finally {
10158                Binder.restoreCallingIdentity(ident);
10159            }
10160        }
10161    }
10162
10163    @Override
10164    public boolean removeTask(int taskId) {
10165        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10166        synchronized (this) {
10167            final long ident = Binder.clearCallingIdentity();
10168            try {
10169                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10170            } finally {
10171                Binder.restoreCallingIdentity(ident);
10172            }
10173        }
10174    }
10175
10176    /**
10177     * TODO: Add mController hook
10178     */
10179    @Override
10180    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10181        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10182
10183        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10184        synchronized(this) {
10185            moveTaskToFrontLocked(taskId, flags, bOptions);
10186        }
10187    }
10188
10189    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
10190        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10191
10192        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10193                Binder.getCallingUid(), -1, -1, "Task to front")) {
10194            ActivityOptions.abort(options);
10195            return;
10196        }
10197        final long origId = Binder.clearCallingIdentity();
10198        try {
10199            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10200            if (task == null) {
10201                Slog.d(TAG, "Could not find task for id: "+ taskId);
10202                return;
10203            }
10204            if (mStackSupervisor.isLockTaskModeViolation(task)) {
10205                mStackSupervisor.showLockTaskToast();
10206                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10207                return;
10208            }
10209            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10210            if (prev != null) {
10211                task.setTaskToReturnTo(prev);
10212            }
10213            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10214                    false /* forceNonResizable */);
10215
10216            final ActivityRecord topActivity = task.getTopActivity();
10217            if (topActivity != null) {
10218
10219                // We are reshowing a task, use a starting window to hide the initial draw delay
10220                // so the transition can start earlier.
10221                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10222                        true /* taskSwitch */);
10223            }
10224        } finally {
10225            Binder.restoreCallingIdentity(origId);
10226        }
10227        ActivityOptions.abort(options);
10228    }
10229
10230    /**
10231     * Attempts to move a task backwards in z-order (the order of activities within the task is
10232     * unchanged).
10233     *
10234     * There are several possible results of this call:
10235     * - if the task is locked, then we will show the lock toast
10236     * - if there is a task behind the provided task, then that task is made visible and resumed as
10237     *   this task is moved to the back
10238     * - otherwise, if there are no other tasks in the stack:
10239     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10240     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10241     *       (depending on whether it is visible)
10242     *     - otherwise, we simply return home and hide this task
10243     *
10244     * @param token A reference to the activity we wish to move
10245     * @param nonRoot If false then this only works if the activity is the root
10246     *                of a task; if true it will work for any activity in a task.
10247     * @return Returns true if the move completed, false if not.
10248     */
10249    @Override
10250    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10251        enforceNotIsolatedCaller("moveActivityTaskToBack");
10252        synchronized(this) {
10253            final long origId = Binder.clearCallingIdentity();
10254            try {
10255                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10256                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10257                if (task != null) {
10258                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10259                }
10260            } finally {
10261                Binder.restoreCallingIdentity(origId);
10262            }
10263        }
10264        return false;
10265    }
10266
10267    @Override
10268    public void moveTaskBackwards(int task) {
10269        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10270                "moveTaskBackwards()");
10271
10272        synchronized(this) {
10273            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10274                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10275                return;
10276            }
10277            final long origId = Binder.clearCallingIdentity();
10278            moveTaskBackwardsLocked(task);
10279            Binder.restoreCallingIdentity(origId);
10280        }
10281    }
10282
10283    private final void moveTaskBackwardsLocked(int task) {
10284        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10285    }
10286
10287    @Override
10288    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10289            IActivityContainerCallback callback) throws RemoteException {
10290        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10291        synchronized (this) {
10292            if (parentActivityToken == null) {
10293                throw new IllegalArgumentException("parent token must not be null");
10294            }
10295            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10296            if (r == null) {
10297                return null;
10298            }
10299            if (callback == null) {
10300                throw new IllegalArgumentException("callback must not be null");
10301            }
10302            return mStackSupervisor.createVirtualActivityContainer(r, callback);
10303        }
10304    }
10305
10306    @Override
10307    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10308        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10309        synchronized (this) {
10310            final int stackId = mStackSupervisor.getNextStackId();
10311            final ActivityStack stack =
10312                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10313            if (stack == null) {
10314                return null;
10315            }
10316            return stack.mActivityContainer;
10317        }
10318    }
10319
10320    @Override
10321    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10322        synchronized (this) {
10323            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10324            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10325                return stack.mActivityContainer.getDisplayId();
10326            }
10327            return DEFAULT_DISPLAY;
10328        }
10329    }
10330
10331    @Override
10332    public int getActivityStackId(IBinder token) throws RemoteException {
10333        synchronized (this) {
10334            ActivityStack stack = ActivityRecord.getStackLocked(token);
10335            if (stack == null) {
10336                return INVALID_STACK_ID;
10337            }
10338            return stack.mStackId;
10339        }
10340    }
10341
10342    @Override
10343    public void exitFreeformMode(IBinder token) throws RemoteException {
10344        synchronized (this) {
10345            long ident = Binder.clearCallingIdentity();
10346            try {
10347                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10348                if (r == null) {
10349                    throw new IllegalArgumentException(
10350                            "exitFreeformMode: No activity record matching token=" + token);
10351                }
10352
10353                final ActivityStack stack = r.getStack();
10354                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10355                    throw new IllegalStateException(
10356                            "exitFreeformMode: You can only go fullscreen from freeform.");
10357                }
10358
10359                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10360                r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10361                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10362            } finally {
10363                Binder.restoreCallingIdentity(ident);
10364            }
10365        }
10366    }
10367
10368    @Override
10369    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10370        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10371        if (StackId.isHomeOrRecentsStack(stackId)) {
10372            throw new IllegalArgumentException(
10373                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10374        }
10375        synchronized (this) {
10376            long ident = Binder.clearCallingIdentity();
10377            try {
10378                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10379                if (task == null) {
10380                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10381                    return;
10382                }
10383
10384                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10385                        + " to stackId=" + stackId + " toTop=" + toTop);
10386                if (stackId == DOCKED_STACK_ID) {
10387                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10388                            null /* initialBounds */);
10389                }
10390                task.reparent(stackId, toTop,
10391                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10392            } finally {
10393                Binder.restoreCallingIdentity(ident);
10394            }
10395        }
10396    }
10397
10398    @Override
10399    public void swapDockedAndFullscreenStack() throws RemoteException {
10400        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10401        synchronized (this) {
10402            long ident = Binder.clearCallingIdentity();
10403            try {
10404                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10405                        FULLSCREEN_WORKSPACE_STACK_ID);
10406                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10407                        : null;
10408                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10409                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10410                        : null;
10411                if (topTask == null || tasks == null || tasks.size() == 0) {
10412                    Slog.w(TAG,
10413                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10414                    return;
10415                }
10416
10417                // TODO: App transition
10418                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10419
10420                // Defer the resume until we move all the docked tasks to the fullscreen stack below
10421                topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10422                        DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10423                final int size = tasks.size();
10424                for (int i = 0; i < size; i++) {
10425                    final int id = tasks.get(i).taskId;
10426                    if (id == topTask.taskId) {
10427                        continue;
10428                    }
10429
10430                    // Defer the resume until after all the tasks have been moved
10431                    tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10432                            REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10433                            "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10434                }
10435
10436                // Because we deferred the resume to avoid conflicts with stack switches while
10437                // resuming, we need to do it after all the tasks are moved.
10438                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10439                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10440
10441                mWindowManager.executeAppTransition();
10442            } finally {
10443                Binder.restoreCallingIdentity(ident);
10444            }
10445        }
10446    }
10447
10448    /**
10449     * Moves the input task to the docked stack.
10450     *
10451     * @param taskId Id of task to move.
10452     * @param createMode The mode the docked stack should be created in if it doesn't exist
10453     *                   already. See
10454     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10455     *                   and
10456     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10457     * @param toTop If the task and stack should be moved to the top.
10458     * @param animate Whether we should play an animation for the moving the task
10459     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10460     *                      docked stack. Pass {@code null} to use default bounds.
10461     */
10462    @Override
10463    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10464            Rect initialBounds) {
10465        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10466        synchronized (this) {
10467            long ident = Binder.clearCallingIdentity();
10468            try {
10469                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10470                if (task == null) {
10471                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10472                    return false;
10473                }
10474
10475                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10476                        + " to createMode=" + createMode + " toTop=" + toTop);
10477                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10478
10479                // Defer resuming until we move the home stack to the front below
10480                final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10481                        REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10482                        "moveTaskToDockedStack");
10483                if (moved) {
10484                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10485                }
10486                return moved;
10487            } finally {
10488                Binder.restoreCallingIdentity(ident);
10489            }
10490        }
10491    }
10492
10493    /**
10494     * Moves the top activity in the input stackId to the pinned stack.
10495     *
10496     * @param stackId Id of stack to move the top activity to pinned stack.
10497     * @param bounds Bounds to use for pinned stack.
10498     *
10499     * @return True if the top activity of the input stack was successfully moved to the pinned
10500     *          stack.
10501     */
10502    @Override
10503    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10504        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10505        synchronized (this) {
10506            if (!mSupportsPictureInPicture) {
10507                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10508                        + "Device doesn't support picture-in-picture mode");
10509            }
10510
10511            long ident = Binder.clearCallingIdentity();
10512            try {
10513                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10514            } finally {
10515                Binder.restoreCallingIdentity(ident);
10516            }
10517        }
10518    }
10519
10520    @Override
10521    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10522            boolean preserveWindows, boolean animate, int animationDuration) {
10523        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10524        long ident = Binder.clearCallingIdentity();
10525        try {
10526            synchronized (this) {
10527                if (animate) {
10528                    if (stackId == PINNED_STACK_ID) {
10529                        final PinnedActivityStack pinnedStack =
10530                                mStackSupervisor.getStack(PINNED_STACK_ID);
10531                        if (pinnedStack != null) {
10532                            pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10533                                    destBounds, animationDuration,
10534                                    false /* schedulePipModeChangedOnAnimationEnd */);
10535                        }
10536                    } else {
10537                        throw new IllegalArgumentException("Stack: " + stackId
10538                                + " doesn't support animated resize.");
10539                    }
10540                } else {
10541                    mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10542                            null /* tempTaskInsetBounds */, preserveWindows,
10543                            allowResizeInDockedMode, !DEFER_RESUME);
10544                }
10545            }
10546        } finally {
10547            Binder.restoreCallingIdentity(ident);
10548        }
10549    }
10550
10551    @Override
10552    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10553            Rect tempDockedTaskInsetBounds,
10554            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10555        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10556                "resizeDockedStack()");
10557        long ident = Binder.clearCallingIdentity();
10558        try {
10559            synchronized (this) {
10560                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10561                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10562                        PRESERVE_WINDOWS);
10563            }
10564        } finally {
10565            Binder.restoreCallingIdentity(ident);
10566        }
10567    }
10568
10569    @Override
10570    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10571        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10572                "resizePinnedStack()");
10573        final long ident = Binder.clearCallingIdentity();
10574        try {
10575            synchronized (this) {
10576                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10577            }
10578        } finally {
10579            Binder.restoreCallingIdentity(ident);
10580        }
10581    }
10582
10583    /**
10584     * Try to place task to provided position. The final position might be different depending on
10585     * current user and stacks state. The task will be moved to target stack if it's currently in
10586     * different stack.
10587     */
10588    @Override
10589    public void positionTaskInStack(int taskId, int stackId, int position) {
10590        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10591        if (StackId.isHomeOrRecentsStack(stackId)) {
10592            throw new IllegalArgumentException(
10593                    "positionTaskInStack: Attempt to change the position of task "
10594                    + taskId + " in/to home/recents stack");
10595        }
10596        synchronized (this) {
10597            long ident = Binder.clearCallingIdentity();
10598            try {
10599                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10600                        + taskId + " in stackId=" + stackId + " at position=" + position);
10601                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10602                if (task == null) {
10603                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10604                            + taskId);
10605                }
10606
10607                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10608                        !ON_TOP);
10609
10610                // TODO: Have the callers of this API call a separate reparent method if that is
10611                // what they intended to do vs. having this method also do reparenting.
10612                if (task.getStack() == stack) {
10613                    // Change position in current stack.
10614                    stack.positionChildAt(task, position);
10615                } else {
10616                    // Reparent to new stack.
10617                    task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10618                            !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10619                }
10620            } finally {
10621                Binder.restoreCallingIdentity(ident);
10622            }
10623        }
10624    }
10625
10626    @Override
10627    public List<StackInfo> getAllStackInfos() {
10628        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10629        long ident = Binder.clearCallingIdentity();
10630        try {
10631            synchronized (this) {
10632                return mStackSupervisor.getAllStackInfosLocked();
10633            }
10634        } finally {
10635            Binder.restoreCallingIdentity(ident);
10636        }
10637    }
10638
10639    @Override
10640    public StackInfo getStackInfo(int stackId) {
10641        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10642        long ident = Binder.clearCallingIdentity();
10643        try {
10644            synchronized (this) {
10645                return mStackSupervisor.getStackInfoLocked(stackId);
10646            }
10647        } finally {
10648            Binder.restoreCallingIdentity(ident);
10649        }
10650    }
10651
10652    @Override
10653    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10654        synchronized(this) {
10655            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10656        }
10657    }
10658
10659    @Override
10660    public void updateDeviceOwner(String packageName) {
10661        final int callingUid = Binder.getCallingUid();
10662        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10663            throw new SecurityException("updateDeviceOwner called from non-system process");
10664        }
10665        synchronized (this) {
10666            mDeviceOwnerName = packageName;
10667        }
10668    }
10669
10670    @Override
10671    public void updateLockTaskPackages(int userId, String[] packages) {
10672        final int callingUid = Binder.getCallingUid();
10673        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10674            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10675                    "updateLockTaskPackages()");
10676        }
10677        synchronized (this) {
10678            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10679                    Arrays.toString(packages));
10680            mLockTaskPackages.put(userId, packages);
10681            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10682        }
10683    }
10684
10685
10686    void startLockTaskModeLocked(TaskRecord task) {
10687        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10688        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10689            return;
10690        }
10691
10692        // When a task is locked, dismiss the pinned stack if it exists
10693        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10694                PINNED_STACK_ID);
10695        if (pinnedStack != null) {
10696            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10697        }
10698
10699        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10700        // is initiated by system after the pinning request was shown and locked mode is initiated
10701        // by an authorized app directly
10702        final int callingUid = Binder.getCallingUid();
10703        boolean isSystemInitiated = callingUid == SYSTEM_UID;
10704        long ident = Binder.clearCallingIdentity();
10705        try {
10706            if (!isSystemInitiated) {
10707                task.mLockTaskUid = callingUid;
10708                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10709                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10710                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10711                    StatusBarManagerInternal statusBarManager =
10712                            LocalServices.getService(StatusBarManagerInternal.class);
10713                    if (statusBarManager != null) {
10714                        statusBarManager.showScreenPinningRequest(task.taskId);
10715                    }
10716                    return;
10717                }
10718
10719                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10720                if (stack == null || task != stack.topTask()) {
10721                    throw new IllegalArgumentException("Invalid task, not in foreground");
10722                }
10723            }
10724            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10725                    "Locking fully");
10726            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10727                    ActivityManager.LOCK_TASK_MODE_PINNED :
10728                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10729                    "startLockTask", true);
10730        } finally {
10731            Binder.restoreCallingIdentity(ident);
10732        }
10733    }
10734
10735    @Override
10736    public void startLockTaskModeById(int taskId) {
10737        synchronized (this) {
10738            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10739            if (task != null) {
10740                startLockTaskModeLocked(task);
10741            }
10742        }
10743    }
10744
10745    @Override
10746    public void startLockTaskModeByToken(IBinder token) {
10747        synchronized (this) {
10748            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10749            if (r == null) {
10750                return;
10751            }
10752            final TaskRecord task = r.getTask();
10753            if (task != null) {
10754                startLockTaskModeLocked(task);
10755            }
10756        }
10757    }
10758
10759    @Override
10760    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10761        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10762        // This makes inner call to look as if it was initiated by system.
10763        long ident = Binder.clearCallingIdentity();
10764        try {
10765            synchronized (this) {
10766                startLockTaskModeById(taskId);
10767            }
10768        } finally {
10769            Binder.restoreCallingIdentity(ident);
10770        }
10771    }
10772
10773    @Override
10774    public void stopLockTaskMode() {
10775        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10776        if (lockTask == null) {
10777            // Our work here is done.
10778            return;
10779        }
10780
10781        final int callingUid = Binder.getCallingUid();
10782        final int lockTaskUid = lockTask.mLockTaskUid;
10783        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10784        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10785            // Done.
10786            return;
10787        } else {
10788            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10789            // It is possible lockTaskMode was started by the system process because
10790            // android:lockTaskMode is set to a locking value in the application manifest
10791            // instead of the app calling startLockTaskMode. In this case
10792            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10793            // {@link TaskRecord.effectiveUid} instead. Also caller with
10794            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10795            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10796                    && callingUid != lockTaskUid
10797                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10798                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10799                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10800            }
10801        }
10802        long ident = Binder.clearCallingIdentity();
10803        try {
10804            Log.d(TAG, "stopLockTaskMode");
10805            // Stop lock task
10806            synchronized (this) {
10807                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10808                        "stopLockTask", true);
10809            }
10810            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10811            if (tm != null) {
10812                tm.showInCallScreen(false);
10813            }
10814        } finally {
10815            Binder.restoreCallingIdentity(ident);
10816        }
10817    }
10818
10819    /**
10820     * This API should be called by SystemUI only when user perform certain action to dismiss
10821     * lock task mode. We should only dismiss pinned lock task mode in this case.
10822     */
10823    @Override
10824    public void stopSystemLockTaskMode() throws RemoteException {
10825        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10826            stopLockTaskMode();
10827        } else {
10828            mStackSupervisor.showLockTaskToast();
10829        }
10830    }
10831
10832    @Override
10833    public boolean isInLockTaskMode() {
10834        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10835    }
10836
10837    @Override
10838    public int getLockTaskModeState() {
10839        synchronized (this) {
10840            return mStackSupervisor.getLockTaskModeState();
10841        }
10842    }
10843
10844    @Override
10845    public void showLockTaskEscapeMessage(IBinder token) {
10846        synchronized (this) {
10847            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10848            if (r == null) {
10849                return;
10850            }
10851            mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
10852        }
10853    }
10854
10855    @Override
10856    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
10857            throws RemoteException {
10858        synchronized (this) {
10859            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10860            if (r == null) {
10861                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
10862                        + token);
10863                return;
10864            }
10865            final long origId = Binder.clearCallingIdentity();
10866            try {
10867                r.setDisablePreviewScreenshots(disable);
10868            } finally {
10869                Binder.restoreCallingIdentity(origId);
10870            }
10871        }
10872    }
10873
10874    // =========================================================
10875    // CONTENT PROVIDERS
10876    // =========================================================
10877
10878    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10879        List<ProviderInfo> providers = null;
10880        try {
10881            providers = AppGlobals.getPackageManager()
10882                    .queryContentProviders(app.processName, app.uid,
10883                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10884                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
10885                    .getList();
10886        } catch (RemoteException ex) {
10887        }
10888        if (DEBUG_MU) Slog.v(TAG_MU,
10889                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10890        int userId = app.userId;
10891        if (providers != null) {
10892            int N = providers.size();
10893            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10894            for (int i=0; i<N; i++) {
10895                // TODO: keep logic in sync with installEncryptionUnawareProviders
10896                ProviderInfo cpi =
10897                    (ProviderInfo)providers.get(i);
10898                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10899                        cpi.name, cpi.flags);
10900                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10901                    // This is a singleton provider, but a user besides the
10902                    // default user is asking to initialize a process it runs
10903                    // in...  well, no, it doesn't actually run in this process,
10904                    // it runs in the process of the default user.  Get rid of it.
10905                    providers.remove(i);
10906                    N--;
10907                    i--;
10908                    continue;
10909                }
10910
10911                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10912                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10913                if (cpr == null) {
10914                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10915                    mProviderMap.putProviderByClass(comp, cpr);
10916                }
10917                if (DEBUG_MU) Slog.v(TAG_MU,
10918                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10919                app.pubProviders.put(cpi.name, cpr);
10920                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10921                    // Don't add this if it is a platform component that is marked
10922                    // to run in multiple processes, because this is actually
10923                    // part of the framework so doesn't make sense to track as a
10924                    // separate apk in the process.
10925                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10926                            mProcessStats);
10927                }
10928                notifyPackageUse(cpi.applicationInfo.packageName,
10929                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10930            }
10931        }
10932        return providers;
10933    }
10934
10935    /**
10936     * Check if the calling UID has a possible chance at accessing the provider
10937     * at the given authority and user.
10938     */
10939    public String checkContentProviderAccess(String authority, int userId) {
10940        if (userId == UserHandle.USER_ALL) {
10941            mContext.enforceCallingOrSelfPermission(
10942                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10943            userId = UserHandle.getCallingUserId();
10944        }
10945
10946        ProviderInfo cpi = null;
10947        try {
10948            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10949                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10950                            | PackageManager.MATCH_DISABLED_COMPONENTS
10951                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10952                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10953                    userId);
10954        } catch (RemoteException ignored) {
10955        }
10956        if (cpi == null) {
10957            return "Failed to find provider " + authority + " for user " + userId
10958                    + "; expected to find a valid ContentProvider for this authority";
10959        }
10960
10961        ProcessRecord r = null;
10962        synchronized (mPidsSelfLocked) {
10963            r = mPidsSelfLocked.get(Binder.getCallingPid());
10964        }
10965        if (r == null) {
10966            return "Failed to find PID " + Binder.getCallingPid();
10967        }
10968
10969        synchronized (this) {
10970            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10971        }
10972    }
10973
10974    /**
10975     * Check if {@link ProcessRecord} has a possible chance at accessing the
10976     * given {@link ProviderInfo}. Final permission checking is always done
10977     * in {@link ContentProvider}.
10978     */
10979    private final String checkContentProviderPermissionLocked(
10980            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10981        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10982        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10983        boolean checkedGrants = false;
10984        if (checkUser) {
10985            // Looking for cross-user grants before enforcing the typical cross-users permissions
10986            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10987            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10988                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10989                    return null;
10990                }
10991                checkedGrants = true;
10992            }
10993            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10994                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10995            if (userId != tmpTargetUserId) {
10996                // When we actually went to determine the final targer user ID, this ended
10997                // up different than our initial check for the authority.  This is because
10998                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10999                // SELF.  So we need to re-check the grants again.
11000                checkedGrants = false;
11001            }
11002        }
11003        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11004                cpi.applicationInfo.uid, cpi.exported)
11005                == PackageManager.PERMISSION_GRANTED) {
11006            return null;
11007        }
11008        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11009                cpi.applicationInfo.uid, cpi.exported)
11010                == PackageManager.PERMISSION_GRANTED) {
11011            return null;
11012        }
11013
11014        PathPermission[] pps = cpi.pathPermissions;
11015        if (pps != null) {
11016            int i = pps.length;
11017            while (i > 0) {
11018                i--;
11019                PathPermission pp = pps[i];
11020                String pprperm = pp.getReadPermission();
11021                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11022                        cpi.applicationInfo.uid, cpi.exported)
11023                        == PackageManager.PERMISSION_GRANTED) {
11024                    return null;
11025                }
11026                String ppwperm = pp.getWritePermission();
11027                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11028                        cpi.applicationInfo.uid, cpi.exported)
11029                        == PackageManager.PERMISSION_GRANTED) {
11030                    return null;
11031                }
11032            }
11033        }
11034        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11035            return null;
11036        }
11037
11038        final String suffix;
11039        if (!cpi.exported) {
11040            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11041        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11042            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11043        } else {
11044            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11045        }
11046        final String msg = "Permission Denial: opening provider " + cpi.name
11047                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11048                + ", uid=" + callingUid + ")" + suffix;
11049        Slog.w(TAG, msg);
11050        return msg;
11051    }
11052
11053    /**
11054     * Returns if the ContentProvider has granted a uri to callingUid
11055     */
11056    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11057        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11058        if (perms != null) {
11059            for (int i=perms.size()-1; i>=0; i--) {
11060                GrantUri grantUri = perms.keyAt(i);
11061                if (grantUri.sourceUserId == userId || !checkUser) {
11062                    if (matchesProvider(grantUri.uri, cpi)) {
11063                        return true;
11064                    }
11065                }
11066            }
11067        }
11068        return false;
11069    }
11070
11071    /**
11072     * Returns true if the uri authority is one of the authorities specified in the provider.
11073     */
11074    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11075        String uriAuth = uri.getAuthority();
11076        String cpiAuth = cpi.authority;
11077        if (cpiAuth.indexOf(';') == -1) {
11078            return cpiAuth.equals(uriAuth);
11079        }
11080        String[] cpiAuths = cpiAuth.split(";");
11081        int length = cpiAuths.length;
11082        for (int i = 0; i < length; i++) {
11083            if (cpiAuths[i].equals(uriAuth)) return true;
11084        }
11085        return false;
11086    }
11087
11088    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11089            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11090        if (r != null) {
11091            for (int i=0; i<r.conProviders.size(); i++) {
11092                ContentProviderConnection conn = r.conProviders.get(i);
11093                if (conn.provider == cpr) {
11094                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11095                            "Adding provider requested by "
11096                            + r.processName + " from process "
11097                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11098                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11099                    if (stable) {
11100                        conn.stableCount++;
11101                        conn.numStableIncs++;
11102                    } else {
11103                        conn.unstableCount++;
11104                        conn.numUnstableIncs++;
11105                    }
11106                    return conn;
11107                }
11108            }
11109            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11110            if (stable) {
11111                conn.stableCount = 1;
11112                conn.numStableIncs = 1;
11113            } else {
11114                conn.unstableCount = 1;
11115                conn.numUnstableIncs = 1;
11116            }
11117            cpr.connections.add(conn);
11118            r.conProviders.add(conn);
11119            startAssociationLocked(r.uid, r.processName, r.curProcState,
11120                    cpr.uid, cpr.name, cpr.info.processName);
11121            return conn;
11122        }
11123        cpr.addExternalProcessHandleLocked(externalProcessToken);
11124        return null;
11125    }
11126
11127    boolean decProviderCountLocked(ContentProviderConnection conn,
11128            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11129        if (conn != null) {
11130            cpr = conn.provider;
11131            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11132                    "Removing provider requested by "
11133                    + conn.client.processName + " from process "
11134                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11135                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11136            if (stable) {
11137                conn.stableCount--;
11138            } else {
11139                conn.unstableCount--;
11140            }
11141            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11142                cpr.connections.remove(conn);
11143                conn.client.conProviders.remove(conn);
11144                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11145                    // The client is more important than last activity -- note the time this
11146                    // is happening, so we keep the old provider process around a bit as last
11147                    // activity to avoid thrashing it.
11148                    if (cpr.proc != null) {
11149                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11150                    }
11151                }
11152                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11153                return true;
11154            }
11155            return false;
11156        }
11157        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11158        return false;
11159    }
11160
11161    private void checkTime(long startTime, String where) {
11162        long now = SystemClock.uptimeMillis();
11163        if ((now-startTime) > 50) {
11164            // If we are taking more than 50ms, log about it.
11165            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11166        }
11167    }
11168
11169    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11170            PROC_SPACE_TERM,
11171            PROC_SPACE_TERM|PROC_PARENS,
11172            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11173    };
11174
11175    private final long[] mProcessStateStatsLongs = new long[1];
11176
11177    boolean isProcessAliveLocked(ProcessRecord proc) {
11178        if (proc.procStatFile == null) {
11179            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11180        }
11181        mProcessStateStatsLongs[0] = 0;
11182        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11183                mProcessStateStatsLongs, null)) {
11184            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11185            return false;
11186        }
11187        final long state = mProcessStateStatsLongs[0];
11188        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11189                + (char)state);
11190        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11191    }
11192
11193    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11194            String name, IBinder token, boolean stable, int userId) {
11195        ContentProviderRecord cpr;
11196        ContentProviderConnection conn = null;
11197        ProviderInfo cpi = null;
11198
11199        synchronized(this) {
11200            long startTime = SystemClock.uptimeMillis();
11201
11202            ProcessRecord r = null;
11203            if (caller != null) {
11204                r = getRecordForAppLocked(caller);
11205                if (r == null) {
11206                    throw new SecurityException(
11207                            "Unable to find app for caller " + caller
11208                          + " (pid=" + Binder.getCallingPid()
11209                          + ") when getting content provider " + name);
11210                }
11211            }
11212
11213            boolean checkCrossUser = true;
11214
11215            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11216
11217            // First check if this content provider has been published...
11218            cpr = mProviderMap.getProviderByName(name, userId);
11219            // If that didn't work, check if it exists for user 0 and then
11220            // verify that it's a singleton provider before using it.
11221            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11222                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11223                if (cpr != null) {
11224                    cpi = cpr.info;
11225                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11226                            cpi.name, cpi.flags)
11227                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11228                        userId = UserHandle.USER_SYSTEM;
11229                        checkCrossUser = false;
11230                    } else {
11231                        cpr = null;
11232                        cpi = null;
11233                    }
11234                }
11235            }
11236
11237            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11238            if (providerRunning) {
11239                cpi = cpr.info;
11240                String msg;
11241                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11242                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11243                        != null) {
11244                    throw new SecurityException(msg);
11245                }
11246                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11247
11248                if (r != null && cpr.canRunHere(r)) {
11249                    // This provider has been published or is in the process
11250                    // of being published...  but it is also allowed to run
11251                    // in the caller's process, so don't make a connection
11252                    // and just let the caller instantiate its own instance.
11253                    ContentProviderHolder holder = cpr.newHolder(null);
11254                    // don't give caller the provider object, it needs
11255                    // to make its own.
11256                    holder.provider = null;
11257                    return holder;
11258                }
11259                // Don't expose instant app providers
11260                if (cpr.appInfo.isInstantApp()) {
11261                    return null;
11262                }
11263
11264                final long origId = Binder.clearCallingIdentity();
11265
11266                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11267
11268                // In this case the provider instance already exists, so we can
11269                // return it right away.
11270                conn = incProviderCountLocked(r, cpr, token, stable);
11271                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11272                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11273                        // If this is a perceptible app accessing the provider,
11274                        // make sure to count it as being accessed and thus
11275                        // back up on the LRU list.  This is good because
11276                        // content providers are often expensive to start.
11277                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11278                        updateLruProcessLocked(cpr.proc, false, null);
11279                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11280                    }
11281                }
11282
11283                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11284                final int verifiedAdj = cpr.proc.verifiedAdj;
11285                boolean success = updateOomAdjLocked(cpr.proc);
11286                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11287                // if the process has been successfully adjusted.  So to reduce races with
11288                // it, we will check whether the process still exists.  Note that this doesn't
11289                // completely get rid of races with LMK killing the process, but should make
11290                // them much smaller.
11291                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11292                    success = false;
11293                }
11294                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11295                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11296                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11297                // NOTE: there is still a race here where a signal could be
11298                // pending on the process even though we managed to update its
11299                // adj level.  Not sure what to do about this, but at least
11300                // the race is now smaller.
11301                if (!success) {
11302                    // Uh oh...  it looks like the provider's process
11303                    // has been killed on us.  We need to wait for a new
11304                    // process to be started, and make sure its death
11305                    // doesn't kill our process.
11306                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11307                            + " is crashing; detaching " + r);
11308                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11309                    checkTime(startTime, "getContentProviderImpl: before appDied");
11310                    appDiedLocked(cpr.proc);
11311                    checkTime(startTime, "getContentProviderImpl: after appDied");
11312                    if (!lastRef) {
11313                        // This wasn't the last ref our process had on
11314                        // the provider...  we have now been killed, bail.
11315                        return null;
11316                    }
11317                    providerRunning = false;
11318                    conn = null;
11319                } else {
11320                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11321                }
11322
11323                Binder.restoreCallingIdentity(origId);
11324            }
11325
11326            if (!providerRunning) {
11327                try {
11328                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11329                    cpi = AppGlobals.getPackageManager().
11330                        resolveContentProvider(name,
11331                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11332                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11333                } catch (RemoteException ex) {
11334                }
11335                if (cpi == null) {
11336                    return null;
11337                }
11338                // If the provider is a singleton AND
11339                // (it's a call within the same user || the provider is a
11340                // privileged app)
11341                // Then allow connecting to the singleton provider
11342                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11343                        cpi.name, cpi.flags)
11344                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11345                if (singleton) {
11346                    userId = UserHandle.USER_SYSTEM;
11347                }
11348                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11349                checkTime(startTime, "getContentProviderImpl: got app info for user");
11350
11351                String msg;
11352                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11353                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11354                        != null) {
11355                    throw new SecurityException(msg);
11356                }
11357                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11358
11359                if (!mProcessesReady
11360                        && !cpi.processName.equals("system")) {
11361                    // If this content provider does not run in the system
11362                    // process, and the system is not yet ready to run other
11363                    // processes, then fail fast instead of hanging.
11364                    throw new IllegalArgumentException(
11365                            "Attempt to launch content provider before system ready");
11366                }
11367
11368                // Make sure that the user who owns this provider is running.  If not,
11369                // we don't want to allow it to run.
11370                if (!mUserController.isUserRunningLocked(userId, 0)) {
11371                    Slog.w(TAG, "Unable to launch app "
11372                            + cpi.applicationInfo.packageName + "/"
11373                            + cpi.applicationInfo.uid + " for provider "
11374                            + name + ": user " + userId + " is stopped");
11375                    return null;
11376                }
11377
11378                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11379                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11380                cpr = mProviderMap.getProviderByClass(comp, userId);
11381                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11382                final boolean firstClass = cpr == null;
11383                if (firstClass) {
11384                    final long ident = Binder.clearCallingIdentity();
11385
11386                    // If permissions need a review before any of the app components can run,
11387                    // we return no provider and launch a review activity if the calling app
11388                    // is in the foreground.
11389                    if (mPermissionReviewRequired) {
11390                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11391                            return null;
11392                        }
11393                    }
11394
11395                    try {
11396                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11397                        ApplicationInfo ai =
11398                            AppGlobals.getPackageManager().
11399                                getApplicationInfo(
11400                                        cpi.applicationInfo.packageName,
11401                                        STOCK_PM_FLAGS, userId);
11402                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11403                        if (ai == null) {
11404                            Slog.w(TAG, "No package info for content provider "
11405                                    + cpi.name);
11406                            return null;
11407                        }
11408                        ai = getAppInfoForUser(ai, userId);
11409                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11410                    } catch (RemoteException ex) {
11411                        // pm is in same process, this will never happen.
11412                    } finally {
11413                        Binder.restoreCallingIdentity(ident);
11414                    }
11415                }
11416
11417                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11418
11419                if (r != null && cpr.canRunHere(r)) {
11420                    // If this is a multiprocess provider, then just return its
11421                    // info and allow the caller to instantiate it.  Only do
11422                    // this if the provider is the same user as the caller's
11423                    // process, or can run as root (so can be in any process).
11424                    return cpr.newHolder(null);
11425                }
11426
11427                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11428                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11429                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11430
11431                // This is single process, and our app is now connecting to it.
11432                // See if we are already in the process of launching this
11433                // provider.
11434                final int N = mLaunchingProviders.size();
11435                int i;
11436                for (i = 0; i < N; i++) {
11437                    if (mLaunchingProviders.get(i) == cpr) {
11438                        break;
11439                    }
11440                }
11441
11442                // If the provider is not already being launched, then get it
11443                // started.
11444                if (i >= N) {
11445                    final long origId = Binder.clearCallingIdentity();
11446
11447                    try {
11448                        // Content provider is now in use, its package can't be stopped.
11449                        try {
11450                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11451                            AppGlobals.getPackageManager().setPackageStoppedState(
11452                                    cpr.appInfo.packageName, false, userId);
11453                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11454                        } catch (RemoteException e) {
11455                        } catch (IllegalArgumentException e) {
11456                            Slog.w(TAG, "Failed trying to unstop package "
11457                                    + cpr.appInfo.packageName + ": " + e);
11458                        }
11459
11460                        // Use existing process if already started
11461                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11462                        ProcessRecord proc = getProcessRecordLocked(
11463                                cpi.processName, cpr.appInfo.uid, false);
11464                        if (proc != null && proc.thread != null && !proc.killed) {
11465                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11466                                    "Installing in existing process " + proc);
11467                            if (!proc.pubProviders.containsKey(cpi.name)) {
11468                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11469                                proc.pubProviders.put(cpi.name, cpr);
11470                                try {
11471                                    proc.thread.scheduleInstallProvider(cpi);
11472                                } catch (RemoteException e) {
11473                                }
11474                            }
11475                        } else {
11476                            checkTime(startTime, "getContentProviderImpl: before start process");
11477                            proc = startProcessLocked(cpi.processName,
11478                                    cpr.appInfo, false, 0, "content provider",
11479                                    new ComponentName(cpi.applicationInfo.packageName,
11480                                            cpi.name), false, false, false);
11481                            checkTime(startTime, "getContentProviderImpl: after start process");
11482                            if (proc == null) {
11483                                Slog.w(TAG, "Unable to launch app "
11484                                        + cpi.applicationInfo.packageName + "/"
11485                                        + cpi.applicationInfo.uid + " for provider "
11486                                        + name + ": process is bad");
11487                                return null;
11488                            }
11489                        }
11490                        cpr.launchingApp = proc;
11491                        mLaunchingProviders.add(cpr);
11492                    } finally {
11493                        Binder.restoreCallingIdentity(origId);
11494                    }
11495                }
11496
11497                checkTime(startTime, "getContentProviderImpl: updating data structures");
11498
11499                // Make sure the provider is published (the same provider class
11500                // may be published under multiple names).
11501                if (firstClass) {
11502                    mProviderMap.putProviderByClass(comp, cpr);
11503                }
11504
11505                mProviderMap.putProviderByName(name, cpr);
11506                conn = incProviderCountLocked(r, cpr, token, stable);
11507                if (conn != null) {
11508                    conn.waiting = true;
11509                }
11510            }
11511            checkTime(startTime, "getContentProviderImpl: done!");
11512
11513            grantEphemeralAccessLocked(userId, null /*intent*/,
11514                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11515        }
11516
11517        // Wait for the provider to be published...
11518        synchronized (cpr) {
11519            while (cpr.provider == null) {
11520                if (cpr.launchingApp == null) {
11521                    Slog.w(TAG, "Unable to launch app "
11522                            + cpi.applicationInfo.packageName + "/"
11523                            + cpi.applicationInfo.uid + " for provider "
11524                            + name + ": launching app became null");
11525                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11526                            UserHandle.getUserId(cpi.applicationInfo.uid),
11527                            cpi.applicationInfo.packageName,
11528                            cpi.applicationInfo.uid, name);
11529                    return null;
11530                }
11531                try {
11532                    if (DEBUG_MU) Slog.v(TAG_MU,
11533                            "Waiting to start provider " + cpr
11534                            + " launchingApp=" + cpr.launchingApp);
11535                    if (conn != null) {
11536                        conn.waiting = true;
11537                    }
11538                    cpr.wait();
11539                } catch (InterruptedException ex) {
11540                } finally {
11541                    if (conn != null) {
11542                        conn.waiting = false;
11543                    }
11544                }
11545            }
11546        }
11547        return cpr != null ? cpr.newHolder(conn) : null;
11548    }
11549
11550    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11551            ProcessRecord r, final int userId) {
11552        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11553                cpi.packageName, userId)) {
11554
11555            final boolean callerForeground = r == null || r.setSchedGroup
11556                    != ProcessList.SCHED_GROUP_BACKGROUND;
11557
11558            // Show a permission review UI only for starting from a foreground app
11559            if (!callerForeground) {
11560                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11561                        + cpi.packageName + " requires a permissions review");
11562                return false;
11563            }
11564
11565            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11566            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11567                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11568            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11569
11570            if (DEBUG_PERMISSIONS_REVIEW) {
11571                Slog.i(TAG, "u" + userId + " Launching permission review "
11572                        + "for package " + cpi.packageName);
11573            }
11574
11575            final UserHandle userHandle = new UserHandle(userId);
11576            mHandler.post(new Runnable() {
11577                @Override
11578                public void run() {
11579                    mContext.startActivityAsUser(intent, userHandle);
11580                }
11581            });
11582
11583            return false;
11584        }
11585
11586        return true;
11587    }
11588
11589    PackageManagerInternal getPackageManagerInternalLocked() {
11590        if (mPackageManagerInt == null) {
11591            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11592        }
11593        return mPackageManagerInt;
11594    }
11595
11596    @Override
11597    public final ContentProviderHolder getContentProvider(
11598            IApplicationThread caller, String name, int userId, boolean stable) {
11599        enforceNotIsolatedCaller("getContentProvider");
11600        if (caller == null) {
11601            String msg = "null IApplicationThread when getting content provider "
11602                    + name;
11603            Slog.w(TAG, msg);
11604            throw new SecurityException(msg);
11605        }
11606        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11607        // with cross-user grant.
11608        return getContentProviderImpl(caller, name, null, stable, userId);
11609    }
11610
11611    public ContentProviderHolder getContentProviderExternal(
11612            String name, int userId, IBinder token) {
11613        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11614            "Do not have permission in call getContentProviderExternal()");
11615        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11616                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11617        return getContentProviderExternalUnchecked(name, token, userId);
11618    }
11619
11620    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11621            IBinder token, int userId) {
11622        return getContentProviderImpl(null, name, token, true, userId);
11623    }
11624
11625    /**
11626     * Drop a content provider from a ProcessRecord's bookkeeping
11627     */
11628    public void removeContentProvider(IBinder connection, boolean stable) {
11629        enforceNotIsolatedCaller("removeContentProvider");
11630        long ident = Binder.clearCallingIdentity();
11631        try {
11632            synchronized (this) {
11633                ContentProviderConnection conn;
11634                try {
11635                    conn = (ContentProviderConnection)connection;
11636                } catch (ClassCastException e) {
11637                    String msg ="removeContentProvider: " + connection
11638                            + " not a ContentProviderConnection";
11639                    Slog.w(TAG, msg);
11640                    throw new IllegalArgumentException(msg);
11641                }
11642                if (conn == null) {
11643                    throw new NullPointerException("connection is null");
11644                }
11645                if (decProviderCountLocked(conn, null, null, stable)) {
11646                    updateOomAdjLocked();
11647                }
11648            }
11649        } finally {
11650            Binder.restoreCallingIdentity(ident);
11651        }
11652    }
11653
11654    public void removeContentProviderExternal(String name, IBinder token) {
11655        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11656            "Do not have permission in call removeContentProviderExternal()");
11657        int userId = UserHandle.getCallingUserId();
11658        long ident = Binder.clearCallingIdentity();
11659        try {
11660            removeContentProviderExternalUnchecked(name, token, userId);
11661        } finally {
11662            Binder.restoreCallingIdentity(ident);
11663        }
11664    }
11665
11666    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11667        synchronized (this) {
11668            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11669            if(cpr == null) {
11670                //remove from mProvidersByClass
11671                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11672                return;
11673            }
11674
11675            //update content provider record entry info
11676            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11677            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11678            if (localCpr.hasExternalProcessHandles()) {
11679                if (localCpr.removeExternalProcessHandleLocked(token)) {
11680                    updateOomAdjLocked();
11681                } else {
11682                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11683                            + " with no external reference for token: "
11684                            + token + ".");
11685                }
11686            } else {
11687                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11688                        + " with no external references.");
11689            }
11690        }
11691    }
11692
11693    public final void publishContentProviders(IApplicationThread caller,
11694            List<ContentProviderHolder> providers) {
11695        if (providers == null) {
11696            return;
11697        }
11698
11699        enforceNotIsolatedCaller("publishContentProviders");
11700        synchronized (this) {
11701            final ProcessRecord r = getRecordForAppLocked(caller);
11702            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11703            if (r == null) {
11704                throw new SecurityException(
11705                        "Unable to find app for caller " + caller
11706                      + " (pid=" + Binder.getCallingPid()
11707                      + ") when publishing content providers");
11708            }
11709
11710            final long origId = Binder.clearCallingIdentity();
11711
11712            final int N = providers.size();
11713            for (int i = 0; i < N; i++) {
11714                ContentProviderHolder src = providers.get(i);
11715                if (src == null || src.info == null || src.provider == null) {
11716                    continue;
11717                }
11718                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11719                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11720                if (dst != null) {
11721                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11722                    mProviderMap.putProviderByClass(comp, dst);
11723                    String names[] = dst.info.authority.split(";");
11724                    for (int j = 0; j < names.length; j++) {
11725                        mProviderMap.putProviderByName(names[j], dst);
11726                    }
11727
11728                    int launchingCount = mLaunchingProviders.size();
11729                    int j;
11730                    boolean wasInLaunchingProviders = false;
11731                    for (j = 0; j < launchingCount; j++) {
11732                        if (mLaunchingProviders.get(j) == dst) {
11733                            mLaunchingProviders.remove(j);
11734                            wasInLaunchingProviders = true;
11735                            j--;
11736                            launchingCount--;
11737                        }
11738                    }
11739                    if (wasInLaunchingProviders) {
11740                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11741                    }
11742                    synchronized (dst) {
11743                        dst.provider = src.provider;
11744                        dst.proc = r;
11745                        dst.notifyAll();
11746                    }
11747                    updateOomAdjLocked(r);
11748                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11749                            src.info.authority);
11750                }
11751            }
11752
11753            Binder.restoreCallingIdentity(origId);
11754        }
11755    }
11756
11757    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11758        ContentProviderConnection conn;
11759        try {
11760            conn = (ContentProviderConnection)connection;
11761        } catch (ClassCastException e) {
11762            String msg ="refContentProvider: " + connection
11763                    + " not a ContentProviderConnection";
11764            Slog.w(TAG, msg);
11765            throw new IllegalArgumentException(msg);
11766        }
11767        if (conn == null) {
11768            throw new NullPointerException("connection is null");
11769        }
11770
11771        synchronized (this) {
11772            if (stable > 0) {
11773                conn.numStableIncs += stable;
11774            }
11775            stable = conn.stableCount + stable;
11776            if (stable < 0) {
11777                throw new IllegalStateException("stableCount < 0: " + stable);
11778            }
11779
11780            if (unstable > 0) {
11781                conn.numUnstableIncs += unstable;
11782            }
11783            unstable = conn.unstableCount + unstable;
11784            if (unstable < 0) {
11785                throw new IllegalStateException("unstableCount < 0: " + unstable);
11786            }
11787
11788            if ((stable+unstable) <= 0) {
11789                throw new IllegalStateException("ref counts can't go to zero here: stable="
11790                        + stable + " unstable=" + unstable);
11791            }
11792            conn.stableCount = stable;
11793            conn.unstableCount = unstable;
11794            return !conn.dead;
11795        }
11796    }
11797
11798    public void unstableProviderDied(IBinder connection) {
11799        ContentProviderConnection conn;
11800        try {
11801            conn = (ContentProviderConnection)connection;
11802        } catch (ClassCastException e) {
11803            String msg ="refContentProvider: " + connection
11804                    + " not a ContentProviderConnection";
11805            Slog.w(TAG, msg);
11806            throw new IllegalArgumentException(msg);
11807        }
11808        if (conn == null) {
11809            throw new NullPointerException("connection is null");
11810        }
11811
11812        // Safely retrieve the content provider associated with the connection.
11813        IContentProvider provider;
11814        synchronized (this) {
11815            provider = conn.provider.provider;
11816        }
11817
11818        if (provider == null) {
11819            // Um, yeah, we're way ahead of you.
11820            return;
11821        }
11822
11823        // Make sure the caller is being honest with us.
11824        if (provider.asBinder().pingBinder()) {
11825            // Er, no, still looks good to us.
11826            synchronized (this) {
11827                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11828                        + " says " + conn + " died, but we don't agree");
11829                return;
11830            }
11831        }
11832
11833        // Well look at that!  It's dead!
11834        synchronized (this) {
11835            if (conn.provider.provider != provider) {
11836                // But something changed...  good enough.
11837                return;
11838            }
11839
11840            ProcessRecord proc = conn.provider.proc;
11841            if (proc == null || proc.thread == null) {
11842                // Seems like the process is already cleaned up.
11843                return;
11844            }
11845
11846            // As far as we're concerned, this is just like receiving a
11847            // death notification...  just a bit prematurely.
11848            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11849                    + ") early provider death");
11850            final long ident = Binder.clearCallingIdentity();
11851            try {
11852                appDiedLocked(proc);
11853            } finally {
11854                Binder.restoreCallingIdentity(ident);
11855            }
11856        }
11857    }
11858
11859    @Override
11860    public void appNotRespondingViaProvider(IBinder connection) {
11861        enforceCallingPermission(
11862                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11863
11864        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11865        if (conn == null) {
11866            Slog.w(TAG, "ContentProviderConnection is null");
11867            return;
11868        }
11869
11870        final ProcessRecord host = conn.provider.proc;
11871        if (host == null) {
11872            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11873            return;
11874        }
11875
11876        mHandler.post(new Runnable() {
11877            @Override
11878            public void run() {
11879                mAppErrors.appNotResponding(host, null, null, false,
11880                        "ContentProvider not responding");
11881            }
11882        });
11883    }
11884
11885    public final void installSystemProviders() {
11886        List<ProviderInfo> providers;
11887        synchronized (this) {
11888            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
11889            providers = generateApplicationProvidersLocked(app);
11890            if (providers != null) {
11891                for (int i=providers.size()-1; i>=0; i--) {
11892                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11893                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11894                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11895                                + ": not system .apk");
11896                        providers.remove(i);
11897                    }
11898                }
11899            }
11900        }
11901        if (providers != null) {
11902            mSystemThread.installSystemProviders(providers);
11903        }
11904
11905        mConstants.start(mContext.getContentResolver());
11906        mCoreSettingsObserver = new CoreSettingsObserver(this);
11907        mFontScaleSettingObserver = new FontScaleSettingObserver();
11908
11909        // Now that the settings provider is published we can consider sending
11910        // in a rescue party.
11911        RescueParty.onSettingsProviderPublished(mContext);
11912
11913        //mUsageStatsService.monitorPackages();
11914    }
11915
11916    private void startPersistentApps(int matchFlags) {
11917        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11918
11919        synchronized (this) {
11920            try {
11921                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11922                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11923                for (ApplicationInfo app : apps) {
11924                    if (!"android".equals(app.packageName)) {
11925                        addAppLocked(app, null, false, null /* ABI override */);
11926                    }
11927                }
11928            } catch (RemoteException ex) {
11929            }
11930        }
11931    }
11932
11933    /**
11934     * When a user is unlocked, we need to install encryption-unaware providers
11935     * belonging to any running apps.
11936     */
11937    private void installEncryptionUnawareProviders(int userId) {
11938        // We're only interested in providers that are encryption unaware, and
11939        // we don't care about uninstalled apps, since there's no way they're
11940        // running at this point.
11941        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11942
11943        synchronized (this) {
11944            final int NP = mProcessNames.getMap().size();
11945            for (int ip = 0; ip < NP; ip++) {
11946                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11947                final int NA = apps.size();
11948                for (int ia = 0; ia < NA; ia++) {
11949                    final ProcessRecord app = apps.valueAt(ia);
11950                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11951
11952                    final int NG = app.pkgList.size();
11953                    for (int ig = 0; ig < NG; ig++) {
11954                        try {
11955                            final String pkgName = app.pkgList.keyAt(ig);
11956                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11957                                    .getPackageInfo(pkgName, matchFlags, userId);
11958                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11959                                for (ProviderInfo pi : pkgInfo.providers) {
11960                                    // TODO: keep in sync with generateApplicationProvidersLocked
11961                                    final boolean processMatch = Objects.equals(pi.processName,
11962                                            app.processName) || pi.multiprocess;
11963                                    final boolean userMatch = isSingleton(pi.processName,
11964                                            pi.applicationInfo, pi.name, pi.flags)
11965                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11966                                    if (processMatch && userMatch) {
11967                                        Log.v(TAG, "Installing " + pi);
11968                                        app.thread.scheduleInstallProvider(pi);
11969                                    } else {
11970                                        Log.v(TAG, "Skipping " + pi);
11971                                    }
11972                                }
11973                            }
11974                        } catch (RemoteException ignored) {
11975                        }
11976                    }
11977                }
11978            }
11979        }
11980    }
11981
11982    /**
11983     * Allows apps to retrieve the MIME type of a URI.
11984     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11985     * users, then it does not need permission to access the ContentProvider.
11986     * Either, it needs cross-user uri grants.
11987     *
11988     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11989     *
11990     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11991     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11992     */
11993    public String getProviderMimeType(Uri uri, int userId) {
11994        enforceNotIsolatedCaller("getProviderMimeType");
11995        final String name = uri.getAuthority();
11996        int callingUid = Binder.getCallingUid();
11997        int callingPid = Binder.getCallingPid();
11998        long ident = 0;
11999        boolean clearedIdentity = false;
12000        synchronized (this) {
12001            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12002        }
12003        if (canClearIdentity(callingPid, callingUid, userId)) {
12004            clearedIdentity = true;
12005            ident = Binder.clearCallingIdentity();
12006        }
12007        ContentProviderHolder holder = null;
12008        try {
12009            holder = getContentProviderExternalUnchecked(name, null, userId);
12010            if (holder != null) {
12011                return holder.provider.getType(uri);
12012            }
12013        } catch (RemoteException e) {
12014            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12015            return null;
12016        } catch (Exception e) {
12017            Log.w(TAG, "Exception while determining type of " + uri, e);
12018            return null;
12019        } finally {
12020            // We need to clear the identity to call removeContentProviderExternalUnchecked
12021            if (!clearedIdentity) {
12022                ident = Binder.clearCallingIdentity();
12023            }
12024            try {
12025                if (holder != null) {
12026                    removeContentProviderExternalUnchecked(name, null, userId);
12027                }
12028            } finally {
12029                Binder.restoreCallingIdentity(ident);
12030            }
12031        }
12032
12033        return null;
12034    }
12035
12036    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12037        if (UserHandle.getUserId(callingUid) == userId) {
12038            return true;
12039        }
12040        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12041                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12042                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12043                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12044                return true;
12045        }
12046        return false;
12047    }
12048
12049    // =========================================================
12050    // GLOBAL MANAGEMENT
12051    // =========================================================
12052
12053    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12054            boolean isolated, int isolatedUid) {
12055        String proc = customProcess != null ? customProcess : info.processName;
12056        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12057        final int userId = UserHandle.getUserId(info.uid);
12058        int uid = info.uid;
12059        if (isolated) {
12060            if (isolatedUid == 0) {
12061                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12062                while (true) {
12063                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12064                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12065                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12066                    }
12067                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12068                    mNextIsolatedProcessUid++;
12069                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12070                        // No process for this uid, use it.
12071                        break;
12072                    }
12073                    stepsLeft--;
12074                    if (stepsLeft <= 0) {
12075                        return null;
12076                    }
12077                }
12078            } else {
12079                // Special case for startIsolatedProcess (internal only), where
12080                // the uid of the isolated process is specified by the caller.
12081                uid = isolatedUid;
12082            }
12083            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12084
12085            // Register the isolated UID with this application so BatteryStats knows to
12086            // attribute resource usage to the application.
12087            //
12088            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12089            // about the process state of the isolated UID *before* it is registered with the
12090            // owning application.
12091            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12092        }
12093        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12094        if (!mBooted && !mBooting
12095                && userId == UserHandle.USER_SYSTEM
12096                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12097            r.persistent = true;
12098            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12099        }
12100        addProcessNameLocked(r);
12101        return r;
12102    }
12103
12104    private boolean uidOnBackgroundWhitelist(final int uid) {
12105        final int N = mBackgroundUidWhitelist.length;
12106        for (int i = 0; i < N; i++) {
12107            if (uid == mBackgroundUidWhitelist[i]) {
12108                return true;
12109            }
12110        }
12111        return false;
12112    }
12113
12114    @Override
12115    public void backgroundWhitelistUid(final int uid) {
12116        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12117            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12118        }
12119
12120        if (DEBUG_BACKGROUND_CHECK) {
12121            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12122        }
12123        synchronized (this) {
12124            final int N = mBackgroundUidWhitelist.length;
12125            int[] newList = new int[N+1];
12126            System.arraycopy(mBackgroundUidWhitelist, 0, newList, 0, N);
12127            newList[N] = uid;
12128            mBackgroundUidWhitelist = newList;
12129        }
12130    }
12131
12132    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12133            String abiOverride) {
12134        ProcessRecord app;
12135        if (!isolated) {
12136            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12137                    info.uid, true);
12138        } else {
12139            app = null;
12140        }
12141
12142        if (app == null) {
12143            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12144            updateLruProcessLocked(app, false, null);
12145            updateOomAdjLocked();
12146        }
12147
12148        // This package really, really can not be stopped.
12149        try {
12150            AppGlobals.getPackageManager().setPackageStoppedState(
12151                    info.packageName, false, UserHandle.getUserId(app.uid));
12152        } catch (RemoteException e) {
12153        } catch (IllegalArgumentException e) {
12154            Slog.w(TAG, "Failed trying to unstop package "
12155                    + info.packageName + ": " + e);
12156        }
12157
12158        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12159            app.persistent = true;
12160            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12161        }
12162        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12163            mPersistentStartingProcesses.add(app);
12164            startProcessLocked(app, "added application",
12165                    customProcess != null ? customProcess : app.processName, abiOverride,
12166                    null /* entryPoint */, null /* entryPointArgs */);
12167        }
12168
12169        return app;
12170    }
12171
12172    public void unhandledBack() {
12173        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12174                "unhandledBack()");
12175
12176        synchronized(this) {
12177            final long origId = Binder.clearCallingIdentity();
12178            try {
12179                getFocusedStack().unhandledBackLocked();
12180            } finally {
12181                Binder.restoreCallingIdentity(origId);
12182            }
12183        }
12184    }
12185
12186    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12187        enforceNotIsolatedCaller("openContentUri");
12188        final int userId = UserHandle.getCallingUserId();
12189        final Uri uri = Uri.parse(uriString);
12190        String name = uri.getAuthority();
12191        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12192        ParcelFileDescriptor pfd = null;
12193        if (cph != null) {
12194            // We record the binder invoker's uid in thread-local storage before
12195            // going to the content provider to open the file.  Later, in the code
12196            // that handles all permissions checks, we look for this uid and use
12197            // that rather than the Activity Manager's own uid.  The effect is that
12198            // we do the check against the caller's permissions even though it looks
12199            // to the content provider like the Activity Manager itself is making
12200            // the request.
12201            Binder token = new Binder();
12202            sCallerIdentity.set(new Identity(
12203                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12204            try {
12205                pfd = cph.provider.openFile(null, uri, "r", null, token);
12206            } catch (FileNotFoundException e) {
12207                // do nothing; pfd will be returned null
12208            } finally {
12209                // Ensure that whatever happens, we clean up the identity state
12210                sCallerIdentity.remove();
12211                // Ensure we're done with the provider.
12212                removeContentProviderExternalUnchecked(name, null, userId);
12213            }
12214        } else {
12215            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12216        }
12217        return pfd;
12218    }
12219
12220    // Actually is sleeping or shutting down or whatever else in the future
12221    // is an inactive state.
12222    boolean isSleepingOrShuttingDownLocked() {
12223        return isSleepingLocked() || mShuttingDown;
12224    }
12225
12226    boolean isShuttingDownLocked() {
12227        return mShuttingDown;
12228    }
12229
12230    boolean isSleepingLocked() {
12231        return mSleeping;
12232    }
12233
12234    void onWakefulnessChanged(int wakefulness) {
12235        synchronized(this) {
12236            mWakefulness = wakefulness;
12237            updateSleepIfNeededLocked();
12238        }
12239    }
12240
12241    void finishRunningVoiceLocked() {
12242        if (mRunningVoice != null) {
12243            mRunningVoice = null;
12244            mVoiceWakeLock.release();
12245            updateSleepIfNeededLocked();
12246        }
12247    }
12248
12249    void startTimeTrackingFocusedActivityLocked() {
12250        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12251        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12252            mCurAppTimeTracker.start(resumedActivity.packageName);
12253        }
12254    }
12255
12256    void updateSleepIfNeededLocked() {
12257        if (mSleeping && !shouldSleepLocked()) {
12258            mSleeping = false;
12259            startTimeTrackingFocusedActivityLocked();
12260            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12261            mStackSupervisor.comeOutOfSleepIfNeededLocked();
12262            sendNotifyVrManagerOfSleepState(false);
12263            updateOomAdjLocked();
12264        } else if (!mSleeping && shouldSleepLocked()) {
12265            mSleeping = true;
12266            if (mCurAppTimeTracker != null) {
12267                mCurAppTimeTracker.stop();
12268            }
12269            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12270            mStackSupervisor.goingToSleepLocked();
12271            sendNotifyVrManagerOfSleepState(true);
12272            updateOomAdjLocked();
12273
12274            // Initialize the wake times of all processes.
12275            checkExcessivePowerUsageLocked(false);
12276            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12277            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12278            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
12279        }
12280    }
12281
12282    private boolean shouldSleepLocked() {
12283        // Resume applications while running a voice interactor.
12284        if (mRunningVoice != null) {
12285            return false;
12286        }
12287
12288        // TODO: Transform the lock screen state into a sleep token instead.
12289        switch (mWakefulness) {
12290            case PowerManagerInternal.WAKEFULNESS_AWAKE:
12291            case PowerManagerInternal.WAKEFULNESS_DREAMING:
12292            case PowerManagerInternal.WAKEFULNESS_DOZING:
12293                // Pause applications whenever the lock screen is shown or any sleep
12294                // tokens have been acquired.
12295                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12296            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12297            default:
12298                // If we're asleep then pause applications unconditionally.
12299                return true;
12300        }
12301    }
12302
12303    /** Pokes the task persister. */
12304    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12305        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12306    }
12307
12308    /**
12309     * Notifies all listeners when the pinned stack animation starts.
12310     */
12311    @Override
12312    public void notifyPinnedStackAnimationStarted() {
12313        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12314    }
12315
12316    /**
12317     * Notifies all listeners when the pinned stack animation ends.
12318     */
12319    @Override
12320    public void notifyPinnedStackAnimationEnded() {
12321        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12322    }
12323
12324    @Override
12325    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12326        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12327    }
12328
12329    @Override
12330    public boolean shutdown(int timeout) {
12331        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12332                != PackageManager.PERMISSION_GRANTED) {
12333            throw new SecurityException("Requires permission "
12334                    + android.Manifest.permission.SHUTDOWN);
12335        }
12336
12337        boolean timedout = false;
12338
12339        synchronized(this) {
12340            mShuttingDown = true;
12341            updateEventDispatchingLocked();
12342            timedout = mStackSupervisor.shutdownLocked(timeout);
12343        }
12344
12345        mAppOpsService.shutdown();
12346        if (mUsageStatsService != null) {
12347            mUsageStatsService.prepareShutdown();
12348        }
12349        mBatteryStatsService.shutdown();
12350        synchronized (this) {
12351            mProcessStats.shutdownLocked();
12352            notifyTaskPersisterLocked(null, true);
12353        }
12354
12355        return timedout;
12356    }
12357
12358    public final void activitySlept(IBinder token) {
12359        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12360
12361        final long origId = Binder.clearCallingIdentity();
12362
12363        synchronized (this) {
12364            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12365            if (r != null) {
12366                mStackSupervisor.activitySleptLocked(r);
12367            }
12368        }
12369
12370        Binder.restoreCallingIdentity(origId);
12371    }
12372
12373    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12374        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12375        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12376        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12377            boolean wasRunningVoice = mRunningVoice != null;
12378            mRunningVoice = session;
12379            if (!wasRunningVoice) {
12380                mVoiceWakeLock.acquire();
12381                updateSleepIfNeededLocked();
12382            }
12383        }
12384    }
12385
12386    private void updateEventDispatchingLocked() {
12387        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12388    }
12389
12390    @Override
12391    public void setLockScreenShown(boolean showing) {
12392        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12393                != PackageManager.PERMISSION_GRANTED) {
12394            throw new SecurityException("Requires permission "
12395                    + android.Manifest.permission.DEVICE_POWER);
12396        }
12397
12398        synchronized(this) {
12399            long ident = Binder.clearCallingIdentity();
12400            try {
12401                mKeyguardController.setKeyguardShown(showing);
12402            } finally {
12403                Binder.restoreCallingIdentity(ident);
12404            }
12405        }
12406    }
12407
12408    @Override
12409    public void notifyLockedProfile(@UserIdInt int userId) {
12410        try {
12411            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12412                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12413            }
12414        } catch (RemoteException ex) {
12415            throw new SecurityException("Fail to check is caller a privileged app", ex);
12416        }
12417
12418        synchronized (this) {
12419            final long ident = Binder.clearCallingIdentity();
12420            try {
12421                if (mUserController.shouldConfirmCredentials(userId)) {
12422                    if (mKeyguardController.isKeyguardLocked()) {
12423                        // Showing launcher to avoid user entering credential twice.
12424                        final int currentUserId = mUserController.getCurrentUserIdLocked();
12425                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12426                    }
12427                    mStackSupervisor.lockAllProfileTasks(userId);
12428                }
12429            } finally {
12430                Binder.restoreCallingIdentity(ident);
12431            }
12432        }
12433    }
12434
12435    @Override
12436    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12437        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12438        synchronized (this) {
12439            final long ident = Binder.clearCallingIdentity();
12440            try {
12441                mActivityStarter.startConfirmCredentialIntent(intent, options);
12442            } finally {
12443                Binder.restoreCallingIdentity(ident);
12444            }
12445        }
12446    }
12447
12448    @Override
12449    public void stopAppSwitches() {
12450        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12451                != PackageManager.PERMISSION_GRANTED) {
12452            throw new SecurityException("viewquires permission "
12453                    + android.Manifest.permission.STOP_APP_SWITCHES);
12454        }
12455
12456        synchronized(this) {
12457            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12458                    + APP_SWITCH_DELAY_TIME;
12459            mDidAppSwitch = false;
12460            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12461            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12462            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12463        }
12464    }
12465
12466    public void resumeAppSwitches() {
12467        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12468                != PackageManager.PERMISSION_GRANTED) {
12469            throw new SecurityException("Requires permission "
12470                    + android.Manifest.permission.STOP_APP_SWITCHES);
12471        }
12472
12473        synchronized(this) {
12474            // Note that we don't execute any pending app switches... we will
12475            // let those wait until either the timeout, or the next start
12476            // activity request.
12477            mAppSwitchesAllowedTime = 0;
12478        }
12479    }
12480
12481    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12482            int callingPid, int callingUid, String name) {
12483        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12484            return true;
12485        }
12486
12487        int perm = checkComponentPermission(
12488                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12489                sourceUid, -1, true);
12490        if (perm == PackageManager.PERMISSION_GRANTED) {
12491            return true;
12492        }
12493
12494        // If the actual IPC caller is different from the logical source, then
12495        // also see if they are allowed to control app switches.
12496        if (callingUid != -1 && callingUid != sourceUid) {
12497            perm = checkComponentPermission(
12498                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12499                    callingUid, -1, true);
12500            if (perm == PackageManager.PERMISSION_GRANTED) {
12501                return true;
12502            }
12503        }
12504
12505        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12506        return false;
12507    }
12508
12509    public void setDebugApp(String packageName, boolean waitForDebugger,
12510            boolean persistent) {
12511        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12512                "setDebugApp()");
12513
12514        long ident = Binder.clearCallingIdentity();
12515        try {
12516            // Note that this is not really thread safe if there are multiple
12517            // callers into it at the same time, but that's not a situation we
12518            // care about.
12519            if (persistent) {
12520                final ContentResolver resolver = mContext.getContentResolver();
12521                Settings.Global.putString(
12522                    resolver, Settings.Global.DEBUG_APP,
12523                    packageName);
12524                Settings.Global.putInt(
12525                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12526                    waitForDebugger ? 1 : 0);
12527            }
12528
12529            synchronized (this) {
12530                if (!persistent) {
12531                    mOrigDebugApp = mDebugApp;
12532                    mOrigWaitForDebugger = mWaitForDebugger;
12533                }
12534                mDebugApp = packageName;
12535                mWaitForDebugger = waitForDebugger;
12536                mDebugTransient = !persistent;
12537                if (packageName != null) {
12538                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12539                            false, UserHandle.USER_ALL, "set debug app");
12540                }
12541            }
12542        } finally {
12543            Binder.restoreCallingIdentity(ident);
12544        }
12545    }
12546
12547    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12548        synchronized (this) {
12549            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12550            if (!isDebuggable) {
12551                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12552                    throw new SecurityException("Process not debuggable: " + app.packageName);
12553                }
12554            }
12555
12556            mTrackAllocationApp = processName;
12557        }
12558    }
12559
12560    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12561        synchronized (this) {
12562            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12563            if (!isDebuggable) {
12564                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12565                    throw new SecurityException("Process not debuggable: " + app.packageName);
12566                }
12567            }
12568            mProfileApp = processName;
12569            mProfileFile = profilerInfo.profileFile;
12570            if (mProfileFd != null) {
12571                try {
12572                    mProfileFd.close();
12573                } catch (IOException e) {
12574                }
12575                mProfileFd = null;
12576            }
12577            mProfileFd = profilerInfo.profileFd;
12578            mSamplingInterval = profilerInfo.samplingInterval;
12579            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12580            mStreamingOutput = profilerInfo.streamingOutput;
12581            mProfileType = 0;
12582        }
12583    }
12584
12585    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12586        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12587        if (!isDebuggable) {
12588            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12589                throw new SecurityException("Process not debuggable: " + app.packageName);
12590            }
12591        }
12592        mNativeDebuggingApp = processName;
12593    }
12594
12595    @Override
12596    public void setAlwaysFinish(boolean enabled) {
12597        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12598                "setAlwaysFinish()");
12599
12600        long ident = Binder.clearCallingIdentity();
12601        try {
12602            Settings.Global.putInt(
12603                    mContext.getContentResolver(),
12604                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12605
12606            synchronized (this) {
12607                mAlwaysFinishActivities = enabled;
12608            }
12609        } finally {
12610            Binder.restoreCallingIdentity(ident);
12611        }
12612    }
12613
12614    @Override
12615    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12616        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12617                "setActivityController()");
12618        synchronized (this) {
12619            mController = controller;
12620            mControllerIsAMonkey = imAMonkey;
12621            Watchdog.getInstance().setActivityController(controller);
12622        }
12623    }
12624
12625    @Override
12626    public void setUserIsMonkey(boolean userIsMonkey) {
12627        synchronized (this) {
12628            synchronized (mPidsSelfLocked) {
12629                final int callingPid = Binder.getCallingPid();
12630                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12631                if (proc == null) {
12632                    throw new SecurityException("Unknown process: " + callingPid);
12633                }
12634                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12635                    throw new SecurityException("Only an instrumentation process "
12636                            + "with a UiAutomation can call setUserIsMonkey");
12637                }
12638            }
12639            mUserIsMonkey = userIsMonkey;
12640        }
12641    }
12642
12643    @Override
12644    public boolean isUserAMonkey() {
12645        synchronized (this) {
12646            // If there is a controller also implies the user is a monkey.
12647            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12648        }
12649    }
12650
12651    /**
12652     * @deprecated This method is only used by a few internal components and it will soon be
12653     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12654     * No new code should be calling it.
12655     */
12656    @Deprecated
12657    @Override
12658    public void requestBugReport(int bugreportType) {
12659        String extraOptions = null;
12660        switch (bugreportType) {
12661            case ActivityManager.BUGREPORT_OPTION_FULL:
12662                // Default options.
12663                break;
12664            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12665                extraOptions = "bugreportplus";
12666                break;
12667            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12668                extraOptions = "bugreportremote";
12669                break;
12670            case ActivityManager.BUGREPORT_OPTION_WEAR:
12671                extraOptions = "bugreportwear";
12672                break;
12673            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12674                extraOptions = "bugreporttelephony";
12675                break;
12676            default:
12677                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12678                        + bugreportType);
12679        }
12680        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12681        if (extraOptions != null) {
12682            SystemProperties.set("dumpstate.options", extraOptions);
12683        }
12684        SystemProperties.set("ctl.start", "bugreport");
12685    }
12686
12687    /**
12688     * @deprecated This method is only used by a few internal components and it will soon be
12689     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12690     * No new code should be calling it.
12691     */
12692    @Deprecated
12693    @Override
12694    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12695
12696        if (!TextUtils.isEmpty(shareTitle)) {
12697            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12698                String errorStr = "shareTitle should be less than " +
12699                        MAX_BUGREPORT_TITLE_SIZE + " characters";
12700                throw new IllegalArgumentException(errorStr);
12701            } else {
12702                if (!TextUtils.isEmpty(shareDescription)) {
12703                    int length;
12704                    try {
12705                        length = shareDescription.getBytes("UTF-8").length;
12706                    } catch (UnsupportedEncodingException e) {
12707                        String errorStr = "shareDescription: UnsupportedEncodingException";
12708                        throw new IllegalArgumentException(errorStr);
12709                    }
12710                    if (length > SystemProperties.PROP_VALUE_MAX) {
12711                        String errorStr = "shareTitle should be less than " +
12712                                SystemProperties.PROP_VALUE_MAX + " bytes";
12713                        throw new IllegalArgumentException(errorStr);
12714                    } else {
12715                        SystemProperties.set("dumpstate.options.description", shareDescription);
12716                    }
12717                }
12718                SystemProperties.set("dumpstate.options.title", shareTitle);
12719            }
12720        }
12721
12722        Slog.d(TAG, "Bugreport notification title " + shareTitle
12723                + " description " + shareDescription);
12724        requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12725    }
12726
12727    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12728        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12729    }
12730
12731    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12732        if (r != null && (r.instr != null || r.usingWrapper)) {
12733            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12734        }
12735        return KEY_DISPATCHING_TIMEOUT;
12736    }
12737
12738    @Override
12739    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12740        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12741                != PackageManager.PERMISSION_GRANTED) {
12742            throw new SecurityException("Requires permission "
12743                    + android.Manifest.permission.FILTER_EVENTS);
12744        }
12745        ProcessRecord proc;
12746        long timeout;
12747        synchronized (this) {
12748            synchronized (mPidsSelfLocked) {
12749                proc = mPidsSelfLocked.get(pid);
12750            }
12751            timeout = getInputDispatchingTimeoutLocked(proc);
12752        }
12753
12754        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12755            return -1;
12756        }
12757
12758        return timeout;
12759    }
12760
12761    /**
12762     * Handle input dispatching timeouts.
12763     * Returns whether input dispatching should be aborted or not.
12764     */
12765    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12766            final ActivityRecord activity, final ActivityRecord parent,
12767            final boolean aboveSystem, String reason) {
12768        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12769                != PackageManager.PERMISSION_GRANTED) {
12770            throw new SecurityException("Requires permission "
12771                    + android.Manifest.permission.FILTER_EVENTS);
12772        }
12773
12774        final String annotation;
12775        if (reason == null) {
12776            annotation = "Input dispatching timed out";
12777        } else {
12778            annotation = "Input dispatching timed out (" + reason + ")";
12779        }
12780
12781        if (proc != null) {
12782            synchronized (this) {
12783                if (proc.debugging) {
12784                    return false;
12785                }
12786
12787                if (mDidDexOpt) {
12788                    // Give more time since we were dexopting.
12789                    mDidDexOpt = false;
12790                    return false;
12791                }
12792
12793                if (proc.instr != null) {
12794                    Bundle info = new Bundle();
12795                    info.putString("shortMsg", "keyDispatchingTimedOut");
12796                    info.putString("longMsg", annotation);
12797                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12798                    return true;
12799                }
12800            }
12801            mHandler.post(new Runnable() {
12802                @Override
12803                public void run() {
12804                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12805                }
12806            });
12807        }
12808
12809        return true;
12810    }
12811
12812    @Override
12813    public Bundle getAssistContextExtras(int requestType) {
12814        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12815                null, null, true /* focused */, true /* newSessionId */,
12816                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12817        if (pae == null) {
12818            return null;
12819        }
12820        synchronized (pae) {
12821            while (!pae.haveResult) {
12822                try {
12823                    pae.wait();
12824                } catch (InterruptedException e) {
12825                }
12826            }
12827        }
12828        synchronized (this) {
12829            buildAssistBundleLocked(pae, pae.result);
12830            mPendingAssistExtras.remove(pae);
12831            mUiHandler.removeCallbacks(pae);
12832        }
12833        return pae.extras;
12834    }
12835
12836    @Override
12837    public boolean isAssistDataAllowedOnCurrentActivity() {
12838        int userId;
12839        synchronized (this) {
12840            final ActivityStack focusedStack = getFocusedStack();
12841            if (focusedStack == null || focusedStack.isAssistantStack()) {
12842                return false;
12843            }
12844
12845            final ActivityRecord activity = focusedStack.topActivity();
12846            if (activity == null) {
12847                return false;
12848            }
12849            userId = activity.userId;
12850        }
12851        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12852                Context.DEVICE_POLICY_SERVICE);
12853        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12854    }
12855
12856    @Override
12857    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12858        long ident = Binder.clearCallingIdentity();
12859        try {
12860            synchronized (this) {
12861                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12862                ActivityRecord top = getFocusedStack().topActivity();
12863                if (top != caller) {
12864                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12865                            + " is not current top " + top);
12866                    return false;
12867                }
12868                if (!top.nowVisible) {
12869                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12870                            + " is not visible");
12871                    return false;
12872                }
12873            }
12874            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
12875                    token);
12876        } finally {
12877            Binder.restoreCallingIdentity(ident);
12878        }
12879    }
12880
12881    @Override
12882    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12883            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
12884        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12885                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
12886                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
12887    }
12888
12889    @Override
12890    public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
12891            IBinder activityToken) {
12892        // NOTE: we could always use ActivityManager.ASSIST_CONTEXT_FULL and let ActivityThread
12893        // rely on the flags to decide whether the handleRequestAssistContextExtras() is for
12894        // autofill, but it's safer to explicitly use new AutoFill types, in case the Assist
12895        // requests use flags in the future as well (since their flags value might collide with the
12896        // autofill flag values).
12897        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
12898                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
12899                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT) != null;
12900    }
12901
12902    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12903            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12904            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12905        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12906                "enqueueAssistContext()");
12907
12908        synchronized (this) {
12909            ActivityRecord activity = getFocusedStack().topActivity();
12910            if (activity == null) {
12911                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12912                return null;
12913            }
12914            if (activity.app == null || activity.app.thread == null) {
12915                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12916                return null;
12917            }
12918            if (focused) {
12919                if (activityToken != null) {
12920                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12921                    if (activity != caller) {
12922                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12923                                + " is not current top " + activity);
12924                        return null;
12925                    }
12926                }
12927            } else {
12928                activity = ActivityRecord.forTokenLocked(activityToken);
12929                if (activity == null) {
12930                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12931                            + " couldn't be found");
12932                    return null;
12933                }
12934            }
12935
12936            PendingAssistExtras pae;
12937            Bundle extras = new Bundle();
12938            if (args != null) {
12939                extras.putAll(args);
12940            }
12941            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12942            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12943
12944            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12945                    userHandle);
12946            pae.isHome = activity.isHomeActivity();
12947
12948            // Increment the sessionId if necessary
12949            if (newSessionId) {
12950                mViSessionId++;
12951            }
12952            try {
12953                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
12954                        mViSessionId);
12955                mPendingAssistExtras.add(pae);
12956                mUiHandler.postDelayed(pae, timeout);
12957            } catch (RemoteException e) {
12958                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12959                return null;
12960            }
12961            return pae;
12962        }
12963    }
12964
12965    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12966        IResultReceiver receiver;
12967        synchronized (this) {
12968            mPendingAssistExtras.remove(pae);
12969            receiver = pae.receiver;
12970        }
12971        if (receiver != null) {
12972            // Caller wants result sent back to them.
12973            Bundle sendBundle = new Bundle();
12974            // At least return the receiver extras
12975            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12976                    pae.receiverExtras);
12977            try {
12978                pae.receiver.send(0, sendBundle);
12979            } catch (RemoteException e) {
12980            }
12981        }
12982    }
12983
12984    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12985        if (result != null) {
12986            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12987        }
12988        if (pae.hint != null) {
12989            pae.extras.putBoolean(pae.hint, true);
12990        }
12991    }
12992
12993    /** Called from an app when assist data is ready. */
12994    @Override
12995    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12996            AssistContent content, Uri referrer) {
12997        PendingAssistExtras pae = (PendingAssistExtras)token;
12998        synchronized (pae) {
12999            pae.result = extras;
13000            pae.structure = structure;
13001            pae.content = content;
13002            if (referrer != null) {
13003                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13004            }
13005            if (structure != null) {
13006                structure.setHomeActivity(pae.isHome);
13007            }
13008            pae.haveResult = true;
13009            pae.notifyAll();
13010            if (pae.intent == null && pae.receiver == null) {
13011                // Caller is just waiting for the result.
13012                return;
13013            }
13014        }
13015
13016        // We are now ready to launch the assist activity.
13017        IResultReceiver sendReceiver = null;
13018        Bundle sendBundle = null;
13019        synchronized (this) {
13020            buildAssistBundleLocked(pae, extras);
13021            boolean exists = mPendingAssistExtras.remove(pae);
13022            mUiHandler.removeCallbacks(pae);
13023            if (!exists) {
13024                // Timed out.
13025                return;
13026            }
13027            if ((sendReceiver=pae.receiver) != null) {
13028                // Caller wants result sent back to them.
13029                sendBundle = new Bundle();
13030                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13031                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13032                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13033                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13034                        pae.receiverExtras);
13035            }
13036        }
13037        if (sendReceiver != null) {
13038            try {
13039                sendReceiver.send(0, sendBundle);
13040            } catch (RemoteException e) {
13041            }
13042            return;
13043        }
13044
13045        long ident = Binder.clearCallingIdentity();
13046        try {
13047            pae.intent.replaceExtras(pae.extras);
13048            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13049                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
13050                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13051            closeSystemDialogs("assist");
13052            try {
13053                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13054            } catch (ActivityNotFoundException e) {
13055                Slog.w(TAG, "No activity to handle assist action.", e);
13056            }
13057        } finally {
13058            Binder.restoreCallingIdentity(ident);
13059        }
13060    }
13061
13062    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13063            Bundle args) {
13064        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13065                true /* focused */, true /* newSessionId */, userHandle, args,
13066                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
13067    }
13068
13069    public void registerProcessObserver(IProcessObserver observer) {
13070        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13071                "registerProcessObserver()");
13072        synchronized (this) {
13073            mProcessObservers.register(observer);
13074        }
13075    }
13076
13077    @Override
13078    public void unregisterProcessObserver(IProcessObserver observer) {
13079        synchronized (this) {
13080            mProcessObservers.unregister(observer);
13081        }
13082    }
13083
13084    @Override
13085    public int getUidProcessState(int uid, String callingPackage) {
13086        if (!hasUsageStatsPermission(callingPackage)) {
13087            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13088                    "getUidProcessState");
13089        }
13090
13091        synchronized (this) {
13092            UidRecord uidRec = mActiveUids.get(uid);
13093            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13094        }
13095    }
13096
13097    @Override
13098    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13099            String callingPackage) {
13100        if (!hasUsageStatsPermission(callingPackage)) {
13101            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13102                    "registerUidObserver");
13103        }
13104        synchronized (this) {
13105            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13106                    callingPackage, which, cutpoint));
13107        }
13108    }
13109
13110    @Override
13111    public void unregisterUidObserver(IUidObserver observer) {
13112        synchronized (this) {
13113            mUidObservers.unregister(observer);
13114        }
13115    }
13116
13117    @Override
13118    public boolean convertFromTranslucent(IBinder token) {
13119        final long origId = Binder.clearCallingIdentity();
13120        try {
13121            synchronized (this) {
13122                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13123                if (r == null) {
13124                    return false;
13125                }
13126                final boolean translucentChanged = r.changeWindowTranslucency(true);
13127                if (translucentChanged) {
13128                    r.getStack().releaseBackgroundResources(r);
13129                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13130                }
13131                mWindowManager.setAppFullscreen(token, true);
13132                return translucentChanged;
13133            }
13134        } finally {
13135            Binder.restoreCallingIdentity(origId);
13136        }
13137    }
13138
13139    @Override
13140    public boolean convertToTranslucent(IBinder token, Bundle options) {
13141        final long origId = Binder.clearCallingIdentity();
13142        try {
13143            synchronized (this) {
13144                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13145                if (r == null) {
13146                    return false;
13147                }
13148                final TaskRecord task = r.getTask();
13149                int index = task.mActivities.lastIndexOf(r);
13150                if (index > 0) {
13151                    ActivityRecord under = task.mActivities.get(index - 1);
13152                    under.returningOptions = ActivityOptions.fromBundle(options);
13153                }
13154                final boolean translucentChanged = r.changeWindowTranslucency(false);
13155                if (translucentChanged) {
13156                    r.getStack().convertActivityToTranslucent(r);
13157                }
13158                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13159                mWindowManager.setAppFullscreen(token, false);
13160                return translucentChanged;
13161            }
13162        } finally {
13163            Binder.restoreCallingIdentity(origId);
13164        }
13165    }
13166
13167    @Override
13168    public boolean requestVisibleBehind(IBinder token, boolean visible) {
13169        final long origId = Binder.clearCallingIdentity();
13170        try {
13171            synchronized (this) {
13172                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13173                if (r != null) {
13174                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13175                }
13176            }
13177            return false;
13178        } finally {
13179            Binder.restoreCallingIdentity(origId);
13180        }
13181    }
13182
13183    @Override
13184    public boolean isBackgroundVisibleBehind(IBinder token) {
13185        final long origId = Binder.clearCallingIdentity();
13186        try {
13187            synchronized (this) {
13188                final ActivityStack stack = ActivityRecord.getStackLocked(token);
13189                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13190                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13191                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13192                return visible;
13193            }
13194        } finally {
13195            Binder.restoreCallingIdentity(origId);
13196        }
13197    }
13198
13199    @Override
13200    public Bundle getActivityOptions(IBinder token) {
13201        final long origId = Binder.clearCallingIdentity();
13202        try {
13203            synchronized (this) {
13204                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13205                if (r != null) {
13206                    final ActivityOptions activityOptions = r.pendingOptions;
13207                    r.pendingOptions = null;
13208                    return activityOptions == null ? null : activityOptions.toBundle();
13209                }
13210                return null;
13211            }
13212        } finally {
13213            Binder.restoreCallingIdentity(origId);
13214        }
13215    }
13216
13217    @Override
13218    public void setImmersive(IBinder token, boolean immersive) {
13219        synchronized(this) {
13220            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13221            if (r == null) {
13222                throw new IllegalArgumentException();
13223            }
13224            r.immersive = immersive;
13225
13226            // update associated state if we're frontmost
13227            if (r == mStackSupervisor.getResumedActivityLocked()) {
13228                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13229                applyUpdateLockStateLocked(r);
13230            }
13231        }
13232    }
13233
13234    @Override
13235    public boolean isImmersive(IBinder token) {
13236        synchronized (this) {
13237            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13238            if (r == null) {
13239                throw new IllegalArgumentException();
13240            }
13241            return r.immersive;
13242        }
13243    }
13244
13245    @Override
13246    public void setVrThread(int tid) {
13247        enforceSystemHasVrFeature();
13248        synchronized (this) {
13249            synchronized (mPidsSelfLocked) {
13250                final int pid = Binder.getCallingPid();
13251                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13252                mVrController.setVrThreadLocked(tid, pid, proc);
13253            }
13254        }
13255    }
13256
13257    @Override
13258    public void setPersistentVrThread(int tid) {
13259        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13260            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13261                    + Binder.getCallingPid()
13262                    + ", uid=" + Binder.getCallingUid()
13263                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13264            Slog.w(TAG, msg);
13265            throw new SecurityException(msg);
13266        }
13267        enforceSystemHasVrFeature();
13268        synchronized (this) {
13269            synchronized (mPidsSelfLocked) {
13270                final int pid = Binder.getCallingPid();
13271                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13272                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13273            }
13274        }
13275    }
13276
13277    /**
13278     * Schedule the given thread a normal scheduling priority.
13279     *
13280     * @param newTid the tid of the thread to adjust the scheduling of.
13281     * @param suppressLogs {@code true} if any error logging should be disabled.
13282     *
13283     * @return {@code true} if this succeeded.
13284     */
13285    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13286        try {
13287            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13288            return true;
13289        } catch (IllegalArgumentException e) {
13290            if (!suppressLogs) {
13291                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13292            }
13293        }
13294        return false;
13295    }
13296
13297    /**
13298     * Schedule the given thread an FIFO scheduling priority.
13299     *
13300     * @param newTid the tid of the thread to adjust the scheduling of.
13301     * @param suppressLogs {@code true} if any error logging should be disabled.
13302     *
13303     * @return {@code true} if this succeeded.
13304     */
13305    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13306        try {
13307            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13308            return true;
13309        } catch (IllegalArgumentException e) {
13310            if (!suppressLogs) {
13311                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13312            }
13313        }
13314        return false;
13315    }
13316
13317    /**
13318     * Check that we have the features required for VR-related API calls, and throw an exception if
13319     * not.
13320     */
13321    private void enforceSystemHasVrFeature() {
13322        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13323            throw new UnsupportedOperationException("VR mode not supported on this device!");
13324        }
13325    }
13326
13327    @Override
13328    public void setRenderThread(int tid) {
13329        synchronized (this) {
13330            ProcessRecord proc;
13331            synchronized (mPidsSelfLocked) {
13332                int pid = Binder.getCallingPid();
13333                proc = mPidsSelfLocked.get(pid);
13334                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13335                    // ensure the tid belongs to the process
13336                    if (!isThreadInProcess(pid, tid)) {
13337                        throw new IllegalArgumentException(
13338                            "Render thread does not belong to process");
13339                    }
13340                    proc.renderThreadTid = tid;
13341                    if (DEBUG_OOM_ADJ) {
13342                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13343                    }
13344                    // promote to FIFO now
13345                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13346                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13347                        if (mUseFifoUiScheduling) {
13348                            setThreadScheduler(proc.renderThreadTid,
13349                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13350                        } else {
13351                            setThreadPriority(proc.renderThreadTid, -10);
13352                        }
13353                    }
13354                } else {
13355                    if (DEBUG_OOM_ADJ) {
13356                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13357                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13358                               mUseFifoUiScheduling);
13359                    }
13360                }
13361            }
13362        }
13363    }
13364
13365    @Override
13366    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13367        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13368            throw new UnsupportedOperationException("VR mode not supported on this device!");
13369        }
13370
13371        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13372
13373        ActivityRecord r;
13374        synchronized (this) {
13375            r = ActivityRecord.isInStackLocked(token);
13376        }
13377
13378        if (r == null) {
13379            throw new IllegalArgumentException();
13380        }
13381
13382        int err;
13383        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13384                VrManagerInternal.NO_ERROR) {
13385            return err;
13386        }
13387
13388        synchronized(this) {
13389            r.requestedVrComponent = (enabled) ? packageName : null;
13390
13391            // Update associated state if this activity is currently focused
13392            if (r == mStackSupervisor.getResumedActivityLocked()) {
13393                applyUpdateVrModeLocked(r);
13394            }
13395            return 0;
13396        }
13397    }
13398
13399    @Override
13400    public boolean isVrModePackageEnabled(ComponentName packageName) {
13401        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13402            throw new UnsupportedOperationException("VR mode not supported on this device!");
13403        }
13404
13405        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13406
13407        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13408                VrManagerInternal.NO_ERROR;
13409    }
13410
13411    public boolean isTopActivityImmersive() {
13412        enforceNotIsolatedCaller("startActivity");
13413        synchronized (this) {
13414            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13415            return (r != null) ? r.immersive : false;
13416        }
13417    }
13418
13419    /**
13420     * @return whether the system should disable UI modes incompatible with VR mode.
13421     */
13422    boolean shouldDisableNonVrUiLocked() {
13423        return mVrController.shouldDisableNonVrUiLocked();
13424    }
13425
13426    @Override
13427    public boolean isTopOfTask(IBinder token) {
13428        synchronized (this) {
13429            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13430            if (r == null) {
13431                throw new IllegalArgumentException();
13432            }
13433            return r.getTask().getTopActivity() == r;
13434        }
13435    }
13436
13437    @Override
13438    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13439        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13440            String msg = "Permission Denial: setHasTopUi() from pid="
13441                    + Binder.getCallingPid()
13442                    + ", uid=" + Binder.getCallingUid()
13443                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13444            Slog.w(TAG, msg);
13445            throw new SecurityException(msg);
13446        }
13447        final int pid = Binder.getCallingPid();
13448        final long origId = Binder.clearCallingIdentity();
13449        try {
13450            synchronized (this) {
13451                boolean changed = false;
13452                ProcessRecord pr;
13453                synchronized (mPidsSelfLocked) {
13454                    pr = mPidsSelfLocked.get(pid);
13455                    if (pr == null) {
13456                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13457                        return;
13458                    }
13459                    if (pr.hasTopUi != hasTopUi) {
13460                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13461                        pr.hasTopUi = hasTopUi;
13462                        changed = true;
13463                    }
13464                }
13465                if (changed) {
13466                    updateOomAdjLocked(pr);
13467                }
13468            }
13469        } finally {
13470            Binder.restoreCallingIdentity(origId);
13471        }
13472    }
13473
13474    public final void enterSafeMode() {
13475        synchronized(this) {
13476            // It only makes sense to do this before the system is ready
13477            // and started launching other packages.
13478            if (!mSystemReady) {
13479                try {
13480                    AppGlobals.getPackageManager().enterSafeMode();
13481                } catch (RemoteException e) {
13482                }
13483            }
13484
13485            mSafeMode = true;
13486        }
13487    }
13488
13489    public final void showSafeModeOverlay() {
13490        View v = LayoutInflater.from(mContext).inflate(
13491                com.android.internal.R.layout.safe_mode, null);
13492        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13493        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13494        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13495        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13496        lp.gravity = Gravity.BOTTOM | Gravity.START;
13497        lp.format = v.getBackground().getOpacity();
13498        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13499                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13500        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13501        ((WindowManager)mContext.getSystemService(
13502                Context.WINDOW_SERVICE)).addView(v, lp);
13503    }
13504
13505    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13506        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13507            return;
13508        }
13509        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13510        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13511        synchronized (stats) {
13512            if (mBatteryStatsService.isOnBattery()) {
13513                mBatteryStatsService.enforceCallingPermission();
13514                int MY_UID = Binder.getCallingUid();
13515                final int uid;
13516                if (sender == null) {
13517                    uid = sourceUid;
13518                } else {
13519                    uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13520                }
13521                BatteryStatsImpl.Uid.Pkg pkg =
13522                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13523                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13524                pkg.noteWakeupAlarmLocked(tag);
13525            }
13526        }
13527    }
13528
13529    public void noteAlarmStart(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 ? SYSTEM_UID : rec.uid;
13543            }
13544            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13545        }
13546    }
13547
13548    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13549        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13550            return;
13551        }
13552        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13553        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13554        synchronized (stats) {
13555            mBatteryStatsService.enforceCallingPermission();
13556            int MY_UID = Binder.getCallingUid();
13557            final int uid;
13558            if (sender == null) {
13559                uid = sourceUid;
13560            } else {
13561                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13562            }
13563            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13564        }
13565    }
13566
13567    public boolean killPids(int[] pids, String pReason, boolean secure) {
13568        if (Binder.getCallingUid() != SYSTEM_UID) {
13569            throw new SecurityException("killPids only available to the system");
13570        }
13571        String reason = (pReason == null) ? "Unknown" : pReason;
13572        // XXX Note: don't acquire main activity lock here, because the window
13573        // manager calls in with its locks held.
13574
13575        boolean killed = false;
13576        synchronized (mPidsSelfLocked) {
13577            int worstType = 0;
13578            for (int i=0; i<pids.length; i++) {
13579                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13580                if (proc != null) {
13581                    int type = proc.setAdj;
13582                    if (type > worstType) {
13583                        worstType = type;
13584                    }
13585                }
13586            }
13587
13588            // If the worst oom_adj is somewhere in the cached proc LRU range,
13589            // then constrain it so we will kill all cached procs.
13590            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13591                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13592                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13593            }
13594
13595            // If this is not a secure call, don't let it kill processes that
13596            // are important.
13597            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13598                worstType = ProcessList.SERVICE_ADJ;
13599            }
13600
13601            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13602            for (int i=0; i<pids.length; i++) {
13603                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13604                if (proc == null) {
13605                    continue;
13606                }
13607                int adj = proc.setAdj;
13608                if (adj >= worstType && !proc.killedByAm) {
13609                    proc.kill(reason, true);
13610                    killed = true;
13611                }
13612            }
13613        }
13614        return killed;
13615    }
13616
13617    @Override
13618    public void killUid(int appId, int userId, String reason) {
13619        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13620        synchronized (this) {
13621            final long identity = Binder.clearCallingIdentity();
13622            try {
13623                killPackageProcessesLocked(null, appId, userId,
13624                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13625                        reason != null ? reason : "kill uid");
13626            } finally {
13627                Binder.restoreCallingIdentity(identity);
13628            }
13629        }
13630    }
13631
13632    @Override
13633    public boolean killProcessesBelowForeground(String reason) {
13634        if (Binder.getCallingUid() != SYSTEM_UID) {
13635            throw new SecurityException("killProcessesBelowForeground() only available to system");
13636        }
13637
13638        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13639    }
13640
13641    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13642        if (Binder.getCallingUid() != SYSTEM_UID) {
13643            throw new SecurityException("killProcessesBelowAdj() only available to system");
13644        }
13645
13646        boolean killed = false;
13647        synchronized (mPidsSelfLocked) {
13648            final int size = mPidsSelfLocked.size();
13649            for (int i = 0; i < size; i++) {
13650                final int pid = mPidsSelfLocked.keyAt(i);
13651                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13652                if (proc == null) continue;
13653
13654                final int adj = proc.setAdj;
13655                if (adj > belowAdj && !proc.killedByAm) {
13656                    proc.kill(reason, true);
13657                    killed = true;
13658                }
13659            }
13660        }
13661        return killed;
13662    }
13663
13664    @Override
13665    public void hang(final IBinder who, boolean allowRestart) {
13666        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13667                != PackageManager.PERMISSION_GRANTED) {
13668            throw new SecurityException("Requires permission "
13669                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13670        }
13671
13672        final IBinder.DeathRecipient death = new DeathRecipient() {
13673            @Override
13674            public void binderDied() {
13675                synchronized (this) {
13676                    notifyAll();
13677                }
13678            }
13679        };
13680
13681        try {
13682            who.linkToDeath(death, 0);
13683        } catch (RemoteException e) {
13684            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13685            return;
13686        }
13687
13688        synchronized (this) {
13689            Watchdog.getInstance().setAllowRestart(allowRestart);
13690            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13691            synchronized (death) {
13692                while (who.isBinderAlive()) {
13693                    try {
13694                        death.wait();
13695                    } catch (InterruptedException e) {
13696                    }
13697                }
13698            }
13699            Watchdog.getInstance().setAllowRestart(true);
13700        }
13701    }
13702
13703    @Override
13704    public void restart() {
13705        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13706                != PackageManager.PERMISSION_GRANTED) {
13707            throw new SecurityException("Requires permission "
13708                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13709        }
13710
13711        Log.i(TAG, "Sending shutdown broadcast...");
13712
13713        BroadcastReceiver br = new BroadcastReceiver() {
13714            @Override public void onReceive(Context context, Intent intent) {
13715                // Now the broadcast is done, finish up the low-level shutdown.
13716                Log.i(TAG, "Shutting down activity manager...");
13717                shutdown(10000);
13718                Log.i(TAG, "Shutdown complete, restarting!");
13719                killProcess(myPid());
13720                System.exit(10);
13721            }
13722        };
13723
13724        // First send the high-level shut down broadcast.
13725        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13726        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13727        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13728        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13729        mContext.sendOrderedBroadcastAsUser(intent,
13730                UserHandle.ALL, null, br, mHandler, 0, null, null);
13731        */
13732        br.onReceive(mContext, intent);
13733    }
13734
13735    private long getLowRamTimeSinceIdle(long now) {
13736        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13737    }
13738
13739    @Override
13740    public void performIdleMaintenance() {
13741        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13742                != PackageManager.PERMISSION_GRANTED) {
13743            throw new SecurityException("Requires permission "
13744                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13745        }
13746
13747        synchronized (this) {
13748            final long now = SystemClock.uptimeMillis();
13749            final long timeSinceLastIdle = now - mLastIdleTime;
13750            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13751            mLastIdleTime = now;
13752            mLowRamTimeSinceLastIdle = 0;
13753            if (mLowRamStartTime != 0) {
13754                mLowRamStartTime = now;
13755            }
13756
13757            StringBuilder sb = new StringBuilder(128);
13758            sb.append("Idle maintenance over ");
13759            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13760            sb.append(" low RAM for ");
13761            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13762            Slog.i(TAG, sb.toString());
13763
13764            // If at least 1/3 of our time since the last idle period has been spent
13765            // with RAM low, then we want to kill processes.
13766            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13767
13768            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13769                ProcessRecord proc = mLruProcesses.get(i);
13770                if (proc.notCachedSinceIdle) {
13771                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13772                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13773                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13774                        if (doKilling && proc.initialIdlePss != 0
13775                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13776                            sb = new StringBuilder(128);
13777                            sb.append("Kill");
13778                            sb.append(proc.processName);
13779                            sb.append(" in idle maint: pss=");
13780                            sb.append(proc.lastPss);
13781                            sb.append(", swapPss=");
13782                            sb.append(proc.lastSwapPss);
13783                            sb.append(", initialPss=");
13784                            sb.append(proc.initialIdlePss);
13785                            sb.append(", period=");
13786                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13787                            sb.append(", lowRamPeriod=");
13788                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13789                            Slog.wtfQuiet(TAG, sb.toString());
13790                            proc.kill("idle maint (pss " + proc.lastPss
13791                                    + " from " + proc.initialIdlePss + ")", true);
13792                        }
13793                    }
13794                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13795                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13796                    proc.notCachedSinceIdle = true;
13797                    proc.initialIdlePss = 0;
13798                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13799                            mTestPssMode, isSleepingLocked(), now);
13800                }
13801            }
13802
13803            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13804            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13805        }
13806    }
13807
13808    @Override
13809    public void sendIdleJobTrigger() {
13810        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13811                != PackageManager.PERMISSION_GRANTED) {
13812            throw new SecurityException("Requires permission "
13813                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13814        }
13815
13816        final long ident = Binder.clearCallingIdentity();
13817        try {
13818            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13819                    .setPackage("android")
13820                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13821            broadcastIntent(null, intent, null, null, 0, null, null, null,
13822                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13823        } finally {
13824            Binder.restoreCallingIdentity(ident);
13825        }
13826    }
13827
13828    private void retrieveSettings() {
13829        final ContentResolver resolver = mContext.getContentResolver();
13830        final boolean freeformWindowManagement =
13831                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13832                        || Settings.Global.getInt(
13833                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13834        final boolean supportsPictureInPicture =
13835                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13836
13837        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13838        final boolean supportsSplitScreenMultiWindow =
13839                ActivityManager.supportsSplitScreenMultiWindow();
13840        final boolean supportsMultiDisplay = mContext.getPackageManager()
13841                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
13842        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13843        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13844        final boolean alwaysFinishActivities =
13845                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13846        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13847        final boolean forceResizable = Settings.Global.getInt(
13848                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13849        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
13850                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
13851        final boolean supportsLeanbackOnly =
13852                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13853
13854        // Transfer any global setting for forcing RTL layout, into a System Property
13855        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13856
13857        final Configuration configuration = new Configuration();
13858        Settings.System.getConfiguration(resolver, configuration);
13859        if (forceRtl) {
13860            // This will take care of setting the correct layout direction flags
13861            configuration.setLayoutDirection(configuration.locale);
13862        }
13863
13864        synchronized (this) {
13865            mDebugApp = mOrigDebugApp = debugApp;
13866            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13867            mAlwaysFinishActivities = alwaysFinishActivities;
13868            mSupportsLeanbackOnly = supportsLeanbackOnly;
13869            mForceResizableActivities = forceResizable;
13870            if (supportsMultiWindow || forceResizable) {
13871                mSupportsMultiWindow = true;
13872                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13873            } else {
13874                mSupportsMultiWindow = false;
13875                mSupportsFreeformWindowManagement = false;
13876            }
13877            mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13878            mSupportsPictureInPicture = supportsPictureInPicture;
13879            mSupportsMultiDisplay = supportsMultiDisplay;
13880            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13881            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13882            // This happens before any activities are started, so we can change global configuration
13883            // in-place.
13884            updateConfigurationLocked(configuration, null, true);
13885            final Configuration globalConfig = getGlobalConfiguration();
13886            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13887
13888            // Load resources only after the current configuration has been set.
13889            final Resources res = mContext.getResources();
13890            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13891            mThumbnailWidth = res.getDimensionPixelSize(
13892                    com.android.internal.R.dimen.thumbnail_width);
13893            mThumbnailHeight = res.getDimensionPixelSize(
13894                    com.android.internal.R.dimen.thumbnail_height);
13895            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13896                    com.android.internal.R.string.config_appsNotReportingCrashes));
13897            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13898                    com.android.internal.R.bool.config_customUserSwitchUi);
13899            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13900                mFullscreenThumbnailScale = (float) res
13901                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13902                    (float) globalConfig.screenWidthDp;
13903            } else {
13904                mFullscreenThumbnailScale = res.getFraction(
13905                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13906            }
13907            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
13908        }
13909    }
13910
13911    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
13912        traceLog.traceBegin("PhaseActivityManagerReady");
13913        synchronized(this) {
13914            if (mSystemReady) {
13915                // If we're done calling all the receivers, run the next "boot phase" passed in
13916                // by the SystemServer
13917                if (goingCallback != null) {
13918                    goingCallback.run();
13919                }
13920                return;
13921            }
13922
13923            mLocalDeviceIdleController
13924                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13925            mAssistUtils = new AssistUtils(mContext);
13926            mVrController.onSystemReady();
13927            // Make sure we have the current profile info, since it is needed for security checks.
13928            mUserController.onSystemReady();
13929            mRecentTasks.onSystemReadyLocked();
13930            mAppOpsService.systemReady();
13931            mSystemReady = true;
13932        }
13933
13934        ArrayList<ProcessRecord> procsToKill = null;
13935        synchronized(mPidsSelfLocked) {
13936            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13937                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13938                if (!isAllowedWhileBooting(proc.info)){
13939                    if (procsToKill == null) {
13940                        procsToKill = new ArrayList<ProcessRecord>();
13941                    }
13942                    procsToKill.add(proc);
13943                }
13944            }
13945        }
13946
13947        synchronized(this) {
13948            if (procsToKill != null) {
13949                for (int i=procsToKill.size()-1; i>=0; i--) {
13950                    ProcessRecord proc = procsToKill.get(i);
13951                    Slog.i(TAG, "Removing system update proc: " + proc);
13952                    removeProcessLocked(proc, true, false, "system update done");
13953                }
13954            }
13955
13956            // Now that we have cleaned up any update processes, we
13957            // are ready to start launching real processes and know that
13958            // we won't trample on them any more.
13959            mProcessesReady = true;
13960        }
13961
13962        Slog.i(TAG, "System now ready");
13963        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13964            SystemClock.uptimeMillis());
13965
13966        synchronized(this) {
13967            // Make sure we have no pre-ready processes sitting around.
13968
13969            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13970                ResolveInfo ri = mContext.getPackageManager()
13971                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13972                                STOCK_PM_FLAGS);
13973                CharSequence errorMsg = null;
13974                if (ri != null) {
13975                    ActivityInfo ai = ri.activityInfo;
13976                    ApplicationInfo app = ai.applicationInfo;
13977                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13978                        mTopAction = Intent.ACTION_FACTORY_TEST;
13979                        mTopData = null;
13980                        mTopComponent = new ComponentName(app.packageName,
13981                                ai.name);
13982                    } else {
13983                        errorMsg = mContext.getResources().getText(
13984                                com.android.internal.R.string.factorytest_not_system);
13985                    }
13986                } else {
13987                    errorMsg = mContext.getResources().getText(
13988                            com.android.internal.R.string.factorytest_no_action);
13989                }
13990                if (errorMsg != null) {
13991                    mTopAction = null;
13992                    mTopData = null;
13993                    mTopComponent = null;
13994                    Message msg = Message.obtain();
13995                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13996                    msg.getData().putCharSequence("msg", errorMsg);
13997                    mUiHandler.sendMessage(msg);
13998                }
13999            }
14000        }
14001
14002        retrieveSettings();
14003        final int currentUserId;
14004        synchronized (this) {
14005            currentUserId = mUserController.getCurrentUserIdLocked();
14006            readGrantedUriPermissionsLocked();
14007        }
14008
14009        if (goingCallback != null) goingCallback.run();
14010        traceLog.traceBegin("ActivityManagerStartApps");
14011        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14012                Integer.toString(currentUserId), currentUserId);
14013        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14014                Integer.toString(currentUserId), currentUserId);
14015        mSystemServiceManager.startUser(currentUserId);
14016
14017        synchronized (this) {
14018            // Only start up encryption-aware persistent apps; once user is
14019            // unlocked we'll come back around and start unaware apps
14020            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14021
14022            // Start up initial activity.
14023            mBooting = true;
14024            // Enable home activity for system user, so that the system can always boot. We don't
14025            // do this when the system user is not setup since the setup wizard should be the one
14026            // to handle home activity in this case.
14027            if (UserManager.isSplitSystemUser() &&
14028                    Settings.Secure.getInt(mContext.getContentResolver(),
14029                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14030                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14031                try {
14032                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14033                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14034                            UserHandle.USER_SYSTEM);
14035                } catch (RemoteException e) {
14036                    throw e.rethrowAsRuntimeException();
14037                }
14038            }
14039            startHomeActivityLocked(currentUserId, "systemReady");
14040
14041            try {
14042                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14043                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14044                            + " data partition or your device will be unstable.");
14045                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14046                }
14047            } catch (RemoteException e) {
14048            }
14049
14050            if (!Build.isBuildConsistent()) {
14051                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14052                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14053            }
14054
14055            long ident = Binder.clearCallingIdentity();
14056            try {
14057                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14058                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14059                        | Intent.FLAG_RECEIVER_FOREGROUND);
14060                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14061                broadcastIntentLocked(null, null, intent,
14062                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14063                        null, false, false, MY_PID, SYSTEM_UID,
14064                        currentUserId);
14065                intent = new Intent(Intent.ACTION_USER_STARTING);
14066                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14067                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14068                broadcastIntentLocked(null, null, intent,
14069                        null, new IIntentReceiver.Stub() {
14070                            @Override
14071                            public void performReceive(Intent intent, int resultCode, String data,
14072                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14073                                    throws RemoteException {
14074                            }
14075                        }, 0, null, null,
14076                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14077                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14078            } catch (Throwable t) {
14079                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14080            } finally {
14081                Binder.restoreCallingIdentity(ident);
14082            }
14083            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14084            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14085            traceLog.traceEnd(); // ActivityManagerStartApps
14086            traceLog.traceEnd(); // PhaseActivityManagerReady
14087        }
14088    }
14089
14090    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14091        synchronized (this) {
14092            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14093        }
14094    }
14095
14096    void skipCurrentReceiverLocked(ProcessRecord app) {
14097        for (BroadcastQueue queue : mBroadcastQueues) {
14098            queue.skipCurrentReceiverLocked(app);
14099        }
14100    }
14101
14102    /**
14103     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14104     * The application process will exit immediately after this call returns.
14105     * @param app object of the crashing app, null for the system server
14106     * @param crashInfo describing the exception
14107     */
14108    public void handleApplicationCrash(IBinder app,
14109            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14110        ProcessRecord r = findAppProcess(app, "Crash");
14111        final String processName = app == null ? "system_server"
14112                : (r == null ? "unknown" : r.processName);
14113
14114        handleApplicationCrashInner("crash", r, processName, crashInfo);
14115    }
14116
14117    /* Native crash reporting uses this inner version because it needs to be somewhat
14118     * decoupled from the AM-managed cleanup lifecycle
14119     */
14120    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14121            ApplicationErrorReport.CrashInfo crashInfo) {
14122        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14123                UserHandle.getUserId(Binder.getCallingUid()), processName,
14124                r == null ? -1 : r.info.flags,
14125                crashInfo.exceptionClassName,
14126                crashInfo.exceptionMessage,
14127                crashInfo.throwFileName,
14128                crashInfo.throwLineNumber);
14129
14130        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14131
14132        mAppErrors.crashApplication(r, crashInfo);
14133    }
14134
14135    public void handleApplicationStrictModeViolation(
14136            IBinder app,
14137            int violationMask,
14138            StrictMode.ViolationInfo info) {
14139        ProcessRecord r = findAppProcess(app, "StrictMode");
14140        if (r == null) {
14141            return;
14142        }
14143
14144        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14145            Integer stackFingerprint = info.hashCode();
14146            boolean logIt = true;
14147            synchronized (mAlreadyLoggedViolatedStacks) {
14148                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14149                    logIt = false;
14150                    // TODO: sub-sample into EventLog for these, with
14151                    // the info.durationMillis?  Then we'd get
14152                    // the relative pain numbers, without logging all
14153                    // the stack traces repeatedly.  We'd want to do
14154                    // likewise in the client code, which also does
14155                    // dup suppression, before the Binder call.
14156                } else {
14157                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14158                        mAlreadyLoggedViolatedStacks.clear();
14159                    }
14160                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14161                }
14162            }
14163            if (logIt) {
14164                logStrictModeViolationToDropBox(r, info);
14165            }
14166        }
14167
14168        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14169            AppErrorResult result = new AppErrorResult();
14170            synchronized (this) {
14171                final long origId = Binder.clearCallingIdentity();
14172
14173                Message msg = Message.obtain();
14174                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14175                HashMap<String, Object> data = new HashMap<String, Object>();
14176                data.put("result", result);
14177                data.put("app", r);
14178                data.put("violationMask", violationMask);
14179                data.put("info", info);
14180                msg.obj = data;
14181                mUiHandler.sendMessage(msg);
14182
14183                Binder.restoreCallingIdentity(origId);
14184            }
14185            int res = result.get();
14186            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14187        }
14188    }
14189
14190    // Depending on the policy in effect, there could be a bunch of
14191    // these in quick succession so we try to batch these together to
14192    // minimize disk writes, number of dropbox entries, and maximize
14193    // compression, by having more fewer, larger records.
14194    private void logStrictModeViolationToDropBox(
14195            ProcessRecord process,
14196            StrictMode.ViolationInfo info) {
14197        if (info == null) {
14198            return;
14199        }
14200        final boolean isSystemApp = process == null ||
14201                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14202                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14203        final String processName = process == null ? "unknown" : process.processName;
14204        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14205        final DropBoxManager dbox = (DropBoxManager)
14206                mContext.getSystemService(Context.DROPBOX_SERVICE);
14207
14208        // Exit early if the dropbox isn't configured to accept this report type.
14209        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14210
14211        boolean bufferWasEmpty;
14212        boolean needsFlush;
14213        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14214        synchronized (sb) {
14215            bufferWasEmpty = sb.length() == 0;
14216            appendDropBoxProcessHeaders(process, processName, sb);
14217            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14218            sb.append("System-App: ").append(isSystemApp).append("\n");
14219            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14220            if (info.violationNumThisLoop != 0) {
14221                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14222            }
14223            if (info.numAnimationsRunning != 0) {
14224                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14225            }
14226            if (info.broadcastIntentAction != null) {
14227                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14228            }
14229            if (info.durationMillis != -1) {
14230                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14231            }
14232            if (info.numInstances != -1) {
14233                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14234            }
14235            if (info.tags != null) {
14236                for (String tag : info.tags) {
14237                    sb.append("Span-Tag: ").append(tag).append("\n");
14238                }
14239            }
14240            sb.append("\n");
14241            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14242                sb.append(info.crashInfo.stackTrace);
14243                sb.append("\n");
14244            }
14245            if (info.message != null) {
14246                sb.append(info.message);
14247                sb.append("\n");
14248            }
14249
14250            // Only buffer up to ~64k.  Various logging bits truncate
14251            // things at 128k.
14252            needsFlush = (sb.length() > 64 * 1024);
14253        }
14254
14255        // Flush immediately if the buffer's grown too large, or this
14256        // is a non-system app.  Non-system apps are isolated with a
14257        // different tag & policy and not batched.
14258        //
14259        // Batching is useful during internal testing with
14260        // StrictMode settings turned up high.  Without batching,
14261        // thousands of separate files could be created on boot.
14262        if (!isSystemApp || needsFlush) {
14263            new Thread("Error dump: " + dropboxTag) {
14264                @Override
14265                public void run() {
14266                    String report;
14267                    synchronized (sb) {
14268                        report = sb.toString();
14269                        sb.delete(0, sb.length());
14270                        sb.trimToSize();
14271                    }
14272                    if (report.length() != 0) {
14273                        dbox.addText(dropboxTag, report);
14274                    }
14275                }
14276            }.start();
14277            return;
14278        }
14279
14280        // System app batching:
14281        if (!bufferWasEmpty) {
14282            // An existing dropbox-writing thread is outstanding, so
14283            // we don't need to start it up.  The existing thread will
14284            // catch the buffer appends we just did.
14285            return;
14286        }
14287
14288        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14289        // (After this point, we shouldn't access AMS internal data structures.)
14290        new Thread("Error dump: " + dropboxTag) {
14291            @Override
14292            public void run() {
14293                // 5 second sleep to let stacks arrive and be batched together
14294                try {
14295                    Thread.sleep(5000);  // 5 seconds
14296                } catch (InterruptedException e) {}
14297
14298                String errorReport;
14299                synchronized (mStrictModeBuffer) {
14300                    errorReport = mStrictModeBuffer.toString();
14301                    if (errorReport.length() == 0) {
14302                        return;
14303                    }
14304                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14305                    mStrictModeBuffer.trimToSize();
14306                }
14307                dbox.addText(dropboxTag, errorReport);
14308            }
14309        }.start();
14310    }
14311
14312    /**
14313     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14314     * @param app object of the crashing app, null for the system server
14315     * @param tag reported by the caller
14316     * @param system whether this wtf is coming from the system
14317     * @param crashInfo describing the context of the error
14318     * @return true if the process should exit immediately (WTF is fatal)
14319     */
14320    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14321            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14322        final int callingUid = Binder.getCallingUid();
14323        final int callingPid = Binder.getCallingPid();
14324
14325        if (system) {
14326            // If this is coming from the system, we could very well have low-level
14327            // system locks held, so we want to do this all asynchronously.  And we
14328            // never want this to become fatal, so there is that too.
14329            mHandler.post(new Runnable() {
14330                @Override public void run() {
14331                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14332                }
14333            });
14334            return false;
14335        }
14336
14337        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14338                crashInfo);
14339
14340        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14341                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14342        final boolean isSystem = (r == null) || r.persistent;
14343
14344        if (isFatal && !isSystem) {
14345            mAppErrors.crashApplication(r, crashInfo);
14346            return true;
14347        } else {
14348            return false;
14349        }
14350    }
14351
14352    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14353            final ApplicationErrorReport.CrashInfo crashInfo) {
14354        final ProcessRecord r = findAppProcess(app, "WTF");
14355        final String processName = app == null ? "system_server"
14356                : (r == null ? "unknown" : r.processName);
14357
14358        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14359                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14360
14361        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14362
14363        return r;
14364    }
14365
14366    /**
14367     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14368     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14369     */
14370    private ProcessRecord findAppProcess(IBinder app, String reason) {
14371        if (app == null) {
14372            return null;
14373        }
14374
14375        synchronized (this) {
14376            final int NP = mProcessNames.getMap().size();
14377            for (int ip=0; ip<NP; ip++) {
14378                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14379                final int NA = apps.size();
14380                for (int ia=0; ia<NA; ia++) {
14381                    ProcessRecord p = apps.valueAt(ia);
14382                    if (p.thread != null && p.thread.asBinder() == app) {
14383                        return p;
14384                    }
14385                }
14386            }
14387
14388            Slog.w(TAG, "Can't find mystery application for " + reason
14389                    + " from pid=" + Binder.getCallingPid()
14390                    + " uid=" + Binder.getCallingUid() + ": " + app);
14391            return null;
14392        }
14393    }
14394
14395    /**
14396     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14397     * to append various headers to the dropbox log text.
14398     */
14399    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14400            StringBuilder sb) {
14401        // Watchdog thread ends up invoking this function (with
14402        // a null ProcessRecord) to add the stack file to dropbox.
14403        // Do not acquire a lock on this (am) in such cases, as it
14404        // could cause a potential deadlock, if and when watchdog
14405        // is invoked due to unavailability of lock on am and it
14406        // would prevent watchdog from killing system_server.
14407        if (process == null) {
14408            sb.append("Process: ").append(processName).append("\n");
14409            return;
14410        }
14411        // Note: ProcessRecord 'process' is guarded by the service
14412        // instance.  (notably process.pkgList, which could otherwise change
14413        // concurrently during execution of this method)
14414        synchronized (this) {
14415            sb.append("Process: ").append(processName).append("\n");
14416            sb.append("PID: ").append(process.pid).append("\n");
14417            int flags = process.info.flags;
14418            IPackageManager pm = AppGlobals.getPackageManager();
14419            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14420            for (int ip=0; ip<process.pkgList.size(); ip++) {
14421                String pkg = process.pkgList.keyAt(ip);
14422                sb.append("Package: ").append(pkg);
14423                try {
14424                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14425                    if (pi != null) {
14426                        sb.append(" v").append(pi.versionCode);
14427                        if (pi.versionName != null) {
14428                            sb.append(" (").append(pi.versionName).append(")");
14429                        }
14430                    }
14431                } catch (RemoteException e) {
14432                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14433                }
14434                sb.append("\n");
14435            }
14436        }
14437    }
14438
14439    private static String processClass(ProcessRecord process) {
14440        if (process == null || process.pid == MY_PID) {
14441            return "system_server";
14442        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14443            return "system_app";
14444        } else {
14445            return "data_app";
14446        }
14447    }
14448
14449    private volatile long mWtfClusterStart;
14450    private volatile int mWtfClusterCount;
14451
14452    /**
14453     * Write a description of an error (crash, WTF, ANR) to the drop box.
14454     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14455     * @param process which caused the error, null means the system server
14456     * @param activity which triggered the error, null if unknown
14457     * @param parent activity related to the error, null if unknown
14458     * @param subject line related to the error, null if absent
14459     * @param report in long form describing the error, null if absent
14460     * @param dataFile text file to include in the report, null if none
14461     * @param crashInfo giving an application stack trace, null if absent
14462     */
14463    public void addErrorToDropBox(String eventType,
14464            ProcessRecord process, String processName, ActivityRecord activity,
14465            ActivityRecord parent, String subject,
14466            final String report, final File dataFile,
14467            final ApplicationErrorReport.CrashInfo crashInfo) {
14468        // NOTE -- this must never acquire the ActivityManagerService lock,
14469        // otherwise the watchdog may be prevented from resetting the system.
14470
14471        // Bail early if not published yet
14472        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14473        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14474
14475        // Exit early if the dropbox isn't configured to accept this report type.
14476        final String dropboxTag = processClass(process) + "_" + eventType;
14477        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14478
14479        // Rate-limit how often we're willing to do the heavy lifting below to
14480        // collect and record logs; currently 5 logs per 10 second period.
14481        final long now = SystemClock.elapsedRealtime();
14482        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14483            mWtfClusterStart = now;
14484            mWtfClusterCount = 1;
14485        } else {
14486            if (mWtfClusterCount++ >= 5) return;
14487        }
14488
14489        final StringBuilder sb = new StringBuilder(1024);
14490        appendDropBoxProcessHeaders(process, processName, sb);
14491        if (process != null) {
14492            sb.append("Foreground: ")
14493                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14494                    .append("\n");
14495        }
14496        if (activity != null) {
14497            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14498        }
14499        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14500            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14501        }
14502        if (parent != null && parent != activity) {
14503            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14504        }
14505        if (subject != null) {
14506            sb.append("Subject: ").append(subject).append("\n");
14507        }
14508        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14509        if (Debug.isDebuggerConnected()) {
14510            sb.append("Debugger: Connected\n");
14511        }
14512        sb.append("\n");
14513
14514        // Do the rest in a worker thread to avoid blocking the caller on I/O
14515        // (After this point, we shouldn't access AMS internal data structures.)
14516        Thread worker = new Thread("Error dump: " + dropboxTag) {
14517            @Override
14518            public void run() {
14519                if (report != null) {
14520                    sb.append(report);
14521                }
14522
14523                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14524                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14525                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14526                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14527
14528                if (dataFile != null && maxDataFileSize > 0) {
14529                    try {
14530                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14531                                    "\n\n[[TRUNCATED]]"));
14532                    } catch (IOException e) {
14533                        Slog.e(TAG, "Error reading " + dataFile, e);
14534                    }
14535                }
14536                if (crashInfo != null && crashInfo.stackTrace != null) {
14537                    sb.append(crashInfo.stackTrace);
14538                }
14539
14540                if (lines > 0) {
14541                    sb.append("\n");
14542
14543                    // Merge several logcat streams, and take the last N lines
14544                    InputStreamReader input = null;
14545                    try {
14546                        java.lang.Process logcat = new ProcessBuilder(
14547                                "/system/bin/timeout", "-k", "15s", "10s",
14548                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14549                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14550                                        .redirectErrorStream(true).start();
14551
14552                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14553                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14554                        input = new InputStreamReader(logcat.getInputStream());
14555
14556                        int num;
14557                        char[] buf = new char[8192];
14558                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14559                    } catch (IOException e) {
14560                        Slog.e(TAG, "Error running logcat", e);
14561                    } finally {
14562                        if (input != null) try { input.close(); } catch (IOException e) {}
14563                    }
14564                }
14565
14566                dbox.addText(dropboxTag, sb.toString());
14567            }
14568        };
14569
14570        if (process == null) {
14571            // If process is null, we are being called from some internal code
14572            // and may be about to die -- run this synchronously.
14573            worker.run();
14574        } else {
14575            worker.start();
14576        }
14577    }
14578
14579    @Override
14580    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14581        enforceNotIsolatedCaller("getProcessesInErrorState");
14582        // assume our apps are happy - lazy create the list
14583        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14584
14585        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14586                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14587        int userId = UserHandle.getUserId(Binder.getCallingUid());
14588
14589        synchronized (this) {
14590
14591            // iterate across all processes
14592            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14593                ProcessRecord app = mLruProcesses.get(i);
14594                if (!allUsers && app.userId != userId) {
14595                    continue;
14596                }
14597                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14598                    // This one's in trouble, so we'll generate a report for it
14599                    // crashes are higher priority (in case there's a crash *and* an anr)
14600                    ActivityManager.ProcessErrorStateInfo report = null;
14601                    if (app.crashing) {
14602                        report = app.crashingReport;
14603                    } else if (app.notResponding) {
14604                        report = app.notRespondingReport;
14605                    }
14606
14607                    if (report != null) {
14608                        if (errList == null) {
14609                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14610                        }
14611                        errList.add(report);
14612                    } else {
14613                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14614                                " crashing = " + app.crashing +
14615                                " notResponding = " + app.notResponding);
14616                    }
14617                }
14618            }
14619        }
14620
14621        return errList;
14622    }
14623
14624    static int procStateToImportance(int procState, int memAdj,
14625            ActivityManager.RunningAppProcessInfo currApp) {
14626        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
14627        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14628            currApp.lru = memAdj;
14629        } else {
14630            currApp.lru = 0;
14631        }
14632        return imp;
14633    }
14634
14635    private void fillInProcMemInfo(ProcessRecord app,
14636            ActivityManager.RunningAppProcessInfo outInfo) {
14637        outInfo.pid = app.pid;
14638        outInfo.uid = app.info.uid;
14639        if (mHeavyWeightProcess == app) {
14640            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14641        }
14642        if (app.persistent) {
14643            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14644        }
14645        if (app.activities.size() > 0) {
14646            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14647        }
14648        outInfo.lastTrimLevel = app.trimMemoryLevel;
14649        int adj = app.curAdj;
14650        int procState = app.curProcState;
14651        outInfo.importance = procStateToImportance(procState, adj, outInfo);
14652        outInfo.importanceReasonCode = app.adjTypeCode;
14653        outInfo.processState = app.curProcState;
14654    }
14655
14656    @Override
14657    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14658        enforceNotIsolatedCaller("getRunningAppProcesses");
14659
14660        final int callingUid = Binder.getCallingUid();
14661
14662        // Lazy instantiation of list
14663        List<ActivityManager.RunningAppProcessInfo> runList = null;
14664        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14665                callingUid) == PackageManager.PERMISSION_GRANTED;
14666        final int userId = UserHandle.getUserId(callingUid);
14667        final boolean allUids = isGetTasksAllowed(
14668                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14669
14670        synchronized (this) {
14671            // Iterate across all processes
14672            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14673                ProcessRecord app = mLruProcesses.get(i);
14674                if ((!allUsers && app.userId != userId)
14675                        || (!allUids && app.uid != callingUid)) {
14676                    continue;
14677                }
14678                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14679                    // Generate process state info for running application
14680                    ActivityManager.RunningAppProcessInfo currApp =
14681                        new ActivityManager.RunningAppProcessInfo(app.processName,
14682                                app.pid, app.getPackageList());
14683                    fillInProcMemInfo(app, currApp);
14684                    if (app.adjSource instanceof ProcessRecord) {
14685                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14686                        currApp.importanceReasonImportance =
14687                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14688                                        app.adjSourceProcState);
14689                    } else if (app.adjSource instanceof ActivityRecord) {
14690                        ActivityRecord r = (ActivityRecord)app.adjSource;
14691                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14692                    }
14693                    if (app.adjTarget instanceof ComponentName) {
14694                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14695                    }
14696                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14697                    //        + " lru=" + currApp.lru);
14698                    if (runList == null) {
14699                        runList = new ArrayList<>();
14700                    }
14701                    runList.add(currApp);
14702                }
14703            }
14704        }
14705        return runList;
14706    }
14707
14708    @Override
14709    public List<ApplicationInfo> getRunningExternalApplications() {
14710        enforceNotIsolatedCaller("getRunningExternalApplications");
14711        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14712        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14713        if (runningApps != null && runningApps.size() > 0) {
14714            Set<String> extList = new HashSet<String>();
14715            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14716                if (app.pkgList != null) {
14717                    for (String pkg : app.pkgList) {
14718                        extList.add(pkg);
14719                    }
14720                }
14721            }
14722            IPackageManager pm = AppGlobals.getPackageManager();
14723            for (String pkg : extList) {
14724                try {
14725                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14726                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14727                        retList.add(info);
14728                    }
14729                } catch (RemoteException e) {
14730                }
14731            }
14732        }
14733        return retList;
14734    }
14735
14736    @Override
14737    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14738        enforceNotIsolatedCaller("getMyMemoryState");
14739        synchronized (this) {
14740            ProcessRecord proc;
14741            synchronized (mPidsSelfLocked) {
14742                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14743            }
14744            fillInProcMemInfo(proc, outInfo);
14745        }
14746    }
14747
14748    @Override
14749    public int getMemoryTrimLevel() {
14750        enforceNotIsolatedCaller("getMyMemoryState");
14751        synchronized (this) {
14752            return mLastMemoryLevel;
14753        }
14754    }
14755
14756    @Override
14757    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14758            FileDescriptor err, String[] args, ShellCallback callback,
14759            ResultReceiver resultReceiver) {
14760        (new ActivityManagerShellCommand(this, false)).exec(
14761                this, in, out, err, args, callback, resultReceiver);
14762    }
14763
14764    @Override
14765    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14766        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14767
14768        boolean dumpAll = false;
14769        boolean dumpClient = false;
14770        boolean dumpCheckin = false;
14771        boolean dumpCheckinFormat = false;
14772        boolean dumpVisibleStacksOnly = false;
14773        boolean dumpFocusedStackOnly = false;
14774        String dumpPackage = null;
14775
14776        int opti = 0;
14777        while (opti < args.length) {
14778            String opt = args[opti];
14779            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14780                break;
14781            }
14782            opti++;
14783            if ("-a".equals(opt)) {
14784                dumpAll = true;
14785            } else if ("-c".equals(opt)) {
14786                dumpClient = true;
14787            } else if ("-v".equals(opt)) {
14788                dumpVisibleStacksOnly = true;
14789            } else if ("-f".equals(opt)) {
14790                dumpFocusedStackOnly = true;
14791            } else if ("-p".equals(opt)) {
14792                if (opti < args.length) {
14793                    dumpPackage = args[opti];
14794                    opti++;
14795                } else {
14796                    pw.println("Error: -p option requires package argument");
14797                    return;
14798                }
14799                dumpClient = true;
14800            } else if ("--checkin".equals(opt)) {
14801                dumpCheckin = dumpCheckinFormat = true;
14802            } else if ("-C".equals(opt)) {
14803                dumpCheckinFormat = true;
14804            } else if ("-h".equals(opt)) {
14805                ActivityManagerShellCommand.dumpHelp(pw, true);
14806                return;
14807            } else {
14808                pw.println("Unknown argument: " + opt + "; use -h for help");
14809            }
14810        }
14811
14812        long origId = Binder.clearCallingIdentity();
14813        boolean more = false;
14814        // Is the caller requesting to dump a particular piece of data?
14815        if (opti < args.length) {
14816            String cmd = args[opti];
14817            opti++;
14818            if ("activities".equals(cmd) || "a".equals(cmd)) {
14819                synchronized (this) {
14820                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14821                }
14822            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14823                synchronized (this) {
14824                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14825                }
14826            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14827                String[] newArgs;
14828                String name;
14829                if (opti >= args.length) {
14830                    name = null;
14831                    newArgs = EMPTY_STRING_ARRAY;
14832                } else {
14833                    dumpPackage = args[opti];
14834                    opti++;
14835                    newArgs = new String[args.length - opti];
14836                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14837                            args.length - opti);
14838                }
14839                synchronized (this) {
14840                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14841                }
14842            } else if ("broadcast-stats".equals(cmd)) {
14843                String[] newArgs;
14844                String name;
14845                if (opti >= args.length) {
14846                    name = null;
14847                    newArgs = EMPTY_STRING_ARRAY;
14848                } else {
14849                    dumpPackage = args[opti];
14850                    opti++;
14851                    newArgs = new String[args.length - opti];
14852                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14853                            args.length - opti);
14854                }
14855                synchronized (this) {
14856                    if (dumpCheckinFormat) {
14857                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14858                                dumpPackage);
14859                    } else {
14860                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14861                    }
14862                }
14863            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14864                String[] newArgs;
14865                String name;
14866                if (opti >= args.length) {
14867                    name = null;
14868                    newArgs = EMPTY_STRING_ARRAY;
14869                } else {
14870                    dumpPackage = args[opti];
14871                    opti++;
14872                    newArgs = new String[args.length - opti];
14873                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14874                            args.length - opti);
14875                }
14876                synchronized (this) {
14877                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14878                }
14879            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14880                String[] newArgs;
14881                String name;
14882                if (opti >= args.length) {
14883                    name = null;
14884                    newArgs = EMPTY_STRING_ARRAY;
14885                } else {
14886                    dumpPackage = args[opti];
14887                    opti++;
14888                    newArgs = new String[args.length - opti];
14889                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14890                            args.length - opti);
14891                }
14892                synchronized (this) {
14893                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14894                }
14895            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14896                synchronized (this) {
14897                    dumpOomLocked(fd, pw, args, opti, true);
14898                }
14899            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14900                synchronized (this) {
14901                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14902                }
14903            } else if ("provider".equals(cmd)) {
14904                String[] newArgs;
14905                String name;
14906                if (opti >= args.length) {
14907                    name = null;
14908                    newArgs = EMPTY_STRING_ARRAY;
14909                } else {
14910                    name = args[opti];
14911                    opti++;
14912                    newArgs = new String[args.length - opti];
14913                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14914                }
14915                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14916                    pw.println("No providers match: " + name);
14917                    pw.println("Use -h for help.");
14918                }
14919            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14920                synchronized (this) {
14921                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14922                }
14923            } else if ("service".equals(cmd)) {
14924                String[] newArgs;
14925                String name;
14926                if (opti >= args.length) {
14927                    name = null;
14928                    newArgs = EMPTY_STRING_ARRAY;
14929                } else {
14930                    name = args[opti];
14931                    opti++;
14932                    newArgs = new String[args.length - opti];
14933                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14934                            args.length - opti);
14935                }
14936                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14937                    pw.println("No services match: " + name);
14938                    pw.println("Use -h for help.");
14939                }
14940            } else if ("package".equals(cmd)) {
14941                String[] newArgs;
14942                if (opti >= args.length) {
14943                    pw.println("package: no package name specified");
14944                    pw.println("Use -h for help.");
14945                } else {
14946                    dumpPackage = args[opti];
14947                    opti++;
14948                    newArgs = new String[args.length - opti];
14949                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14950                            args.length - opti);
14951                    args = newArgs;
14952                    opti = 0;
14953                    more = true;
14954                }
14955            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14956                synchronized (this) {
14957                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14958                }
14959            } else if ("settings".equals(cmd)) {
14960                synchronized (this) {
14961                    mConstants.dump(pw);
14962                }
14963            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14964                if (dumpClient) {
14965                    ActiveServices.ServiceDumper dumper;
14966                    synchronized (this) {
14967                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14968                                dumpPackage);
14969                    }
14970                    dumper.dumpWithClient();
14971                } else {
14972                    synchronized (this) {
14973                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14974                                dumpPackage).dumpLocked();
14975                    }
14976                }
14977            } else if ("locks".equals(cmd)) {
14978                LockGuard.dump(fd, pw, args);
14979            } else {
14980                // Dumping a single activity?
14981                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
14982                        dumpFocusedStackOnly)) {
14983                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14984                    int res = shell.exec(this, null, fd, null, args, null,
14985                            new ResultReceiver(null));
14986                    if (res < 0) {
14987                        pw.println("Bad activity command, or no activities match: " + cmd);
14988                        pw.println("Use -h for help.");
14989                    }
14990                }
14991            }
14992            if (!more) {
14993                Binder.restoreCallingIdentity(origId);
14994                return;
14995            }
14996        }
14997
14998        // No piece of data specified, dump everything.
14999        if (dumpCheckinFormat) {
15000            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15001        } else if (dumpClient) {
15002            ActiveServices.ServiceDumper sdumper;
15003            synchronized (this) {
15004                mConstants.dump(pw);
15005                pw.println();
15006                if (dumpAll) {
15007                    pw.println("-------------------------------------------------------------------------------");
15008                }
15009                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15010                pw.println();
15011                if (dumpAll) {
15012                    pw.println("-------------------------------------------------------------------------------");
15013                }
15014                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15015                pw.println();
15016                if (dumpAll) {
15017                    pw.println("-------------------------------------------------------------------------------");
15018                }
15019                if (dumpAll || dumpPackage != null) {
15020                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15021                    pw.println();
15022                    if (dumpAll) {
15023                        pw.println("-------------------------------------------------------------------------------");
15024                    }
15025                }
15026                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15027                pw.println();
15028                if (dumpAll) {
15029                    pw.println("-------------------------------------------------------------------------------");
15030                }
15031                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15032                pw.println();
15033                if (dumpAll) {
15034                    pw.println("-------------------------------------------------------------------------------");
15035                }
15036                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15037                        dumpPackage);
15038            }
15039            sdumper.dumpWithClient();
15040            pw.println();
15041            synchronized (this) {
15042                if (dumpAll) {
15043                    pw.println("-------------------------------------------------------------------------------");
15044                }
15045                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15046                pw.println();
15047                if (dumpAll) {
15048                    pw.println("-------------------------------------------------------------------------------");
15049                }
15050                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15051                if (mAssociations.size() > 0) {
15052                    pw.println();
15053                    if (dumpAll) {
15054                        pw.println("-------------------------------------------------------------------------------");
15055                    }
15056                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15057                }
15058                pw.println();
15059                if (dumpAll) {
15060                    pw.println("-------------------------------------------------------------------------------");
15061                }
15062                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15063            }
15064
15065        } else {
15066            synchronized (this) {
15067                mConstants.dump(pw);
15068                pw.println();
15069                if (dumpAll) {
15070                    pw.println("-------------------------------------------------------------------------------");
15071                }
15072                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15073                pw.println();
15074                if (dumpAll) {
15075                    pw.println("-------------------------------------------------------------------------------");
15076                }
15077                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15078                pw.println();
15079                if (dumpAll) {
15080                    pw.println("-------------------------------------------------------------------------------");
15081                }
15082                if (dumpAll || dumpPackage != null) {
15083                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15084                    pw.println();
15085                    if (dumpAll) {
15086                        pw.println("-------------------------------------------------------------------------------");
15087                    }
15088                }
15089                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15090                pw.println();
15091                if (dumpAll) {
15092                    pw.println("-------------------------------------------------------------------------------");
15093                }
15094                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15095                pw.println();
15096                if (dumpAll) {
15097                    pw.println("-------------------------------------------------------------------------------");
15098                }
15099                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15100                        .dumpLocked();
15101                pw.println();
15102                if (dumpAll) {
15103                    pw.println("-------------------------------------------------------------------------------");
15104                }
15105                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15106                pw.println();
15107                if (dumpAll) {
15108                    pw.println("-------------------------------------------------------------------------------");
15109                }
15110                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15111                if (mAssociations.size() > 0) {
15112                    pw.println();
15113                    if (dumpAll) {
15114                        pw.println("-------------------------------------------------------------------------------");
15115                    }
15116                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15117                }
15118                pw.println();
15119                if (dumpAll) {
15120                    pw.println("-------------------------------------------------------------------------------");
15121                }
15122                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15123            }
15124        }
15125        Binder.restoreCallingIdentity(origId);
15126    }
15127
15128    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15129            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15130        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15131
15132        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15133                dumpPackage);
15134        boolean needSep = printedAnything;
15135
15136        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15137                mStackSupervisor.getResumedActivityLocked(),
15138                dumpPackage, needSep, "  ResumedActivity: ");
15139        if (printed) {
15140            printedAnything = true;
15141            needSep = false;
15142        }
15143
15144        if (dumpPackage == null) {
15145            if (needSep) {
15146                pw.println();
15147            }
15148            needSep = true;
15149            printedAnything = true;
15150            mStackSupervisor.dump(pw, "  ");
15151        }
15152
15153        if (!printedAnything) {
15154            pw.println("  (nothing)");
15155        }
15156    }
15157
15158    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15159            int opti, boolean dumpAll, String dumpPackage) {
15160        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15161
15162        boolean printedAnything = false;
15163
15164        if (mRecentTasks != null && mRecentTasks.size() > 0) {
15165            boolean printedHeader = false;
15166
15167            final int N = mRecentTasks.size();
15168            for (int i=0; i<N; i++) {
15169                TaskRecord tr = mRecentTasks.get(i);
15170                if (dumpPackage != null) {
15171                    if (tr.realActivity == null ||
15172                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
15173                        continue;
15174                    }
15175                }
15176                if (!printedHeader) {
15177                    pw.println("  Recent tasks:");
15178                    printedHeader = true;
15179                    printedAnything = true;
15180                }
15181                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15182                        pw.println(tr);
15183                if (dumpAll) {
15184                    mRecentTasks.get(i).dump(pw, "    ");
15185                }
15186            }
15187        }
15188
15189        if (!printedAnything) {
15190            pw.println("  (nothing)");
15191        }
15192    }
15193
15194    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15195            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15196        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15197
15198        int dumpUid = 0;
15199        if (dumpPackage != null) {
15200            IPackageManager pm = AppGlobals.getPackageManager();
15201            try {
15202                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15203            } catch (RemoteException e) {
15204            }
15205        }
15206
15207        boolean printedAnything = false;
15208
15209        final long now = SystemClock.uptimeMillis();
15210
15211        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15212            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15213                    = mAssociations.valueAt(i1);
15214            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15215                SparseArray<ArrayMap<String, Association>> sourceUids
15216                        = targetComponents.valueAt(i2);
15217                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15218                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15219                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15220                        Association ass = sourceProcesses.valueAt(i4);
15221                        if (dumpPackage != null) {
15222                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15223                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15224                                continue;
15225                            }
15226                        }
15227                        printedAnything = true;
15228                        pw.print("  ");
15229                        pw.print(ass.mTargetProcess);
15230                        pw.print("/");
15231                        UserHandle.formatUid(pw, ass.mTargetUid);
15232                        pw.print(" <- ");
15233                        pw.print(ass.mSourceProcess);
15234                        pw.print("/");
15235                        UserHandle.formatUid(pw, ass.mSourceUid);
15236                        pw.println();
15237                        pw.print("    via ");
15238                        pw.print(ass.mTargetComponent.flattenToShortString());
15239                        pw.println();
15240                        pw.print("    ");
15241                        long dur = ass.mTime;
15242                        if (ass.mNesting > 0) {
15243                            dur += now - ass.mStartTime;
15244                        }
15245                        TimeUtils.formatDuration(dur, pw);
15246                        pw.print(" (");
15247                        pw.print(ass.mCount);
15248                        pw.print(" times)");
15249                        pw.print("  ");
15250                        for (int i=0; i<ass.mStateTimes.length; i++) {
15251                            long amt = ass.mStateTimes[i];
15252                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15253                                amt += now - ass.mLastStateUptime;
15254                            }
15255                            if (amt != 0) {
15256                                pw.print(" ");
15257                                pw.print(ProcessList.makeProcStateString(
15258                                            i + ActivityManager.MIN_PROCESS_STATE));
15259                                pw.print("=");
15260                                TimeUtils.formatDuration(amt, pw);
15261                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15262                                    pw.print("*");
15263                                }
15264                            }
15265                        }
15266                        pw.println();
15267                        if (ass.mNesting > 0) {
15268                            pw.print("    Currently active: ");
15269                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15270                            pw.println();
15271                        }
15272                    }
15273                }
15274            }
15275
15276        }
15277
15278        if (!printedAnything) {
15279            pw.println("  (nothing)");
15280        }
15281    }
15282
15283    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15284            String header, boolean needSep) {
15285        boolean printed = false;
15286        int whichAppId = -1;
15287        if (dumpPackage != null) {
15288            try {
15289                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15290                        dumpPackage, 0);
15291                whichAppId = UserHandle.getAppId(info.uid);
15292            } catch (NameNotFoundException e) {
15293                e.printStackTrace();
15294            }
15295        }
15296        for (int i=0; i<uids.size(); i++) {
15297            UidRecord uidRec = uids.valueAt(i);
15298            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15299                continue;
15300            }
15301            if (!printed) {
15302                printed = true;
15303                if (needSep) {
15304                    pw.println();
15305                }
15306                pw.print("  ");
15307                pw.println(header);
15308                needSep = true;
15309            }
15310            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15311            pw.print(": "); pw.println(uidRec);
15312        }
15313        return printed;
15314    }
15315
15316    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15317            int opti, boolean dumpAll, String dumpPackage) {
15318        boolean needSep = false;
15319        boolean printedAnything = false;
15320        int numPers = 0;
15321
15322        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15323
15324        if (dumpAll) {
15325            final int NP = mProcessNames.getMap().size();
15326            for (int ip=0; ip<NP; ip++) {
15327                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15328                final int NA = procs.size();
15329                for (int ia=0; ia<NA; ia++) {
15330                    ProcessRecord r = procs.valueAt(ia);
15331                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15332                        continue;
15333                    }
15334                    if (!needSep) {
15335                        pw.println("  All known processes:");
15336                        needSep = true;
15337                        printedAnything = true;
15338                    }
15339                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15340                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15341                        pw.print(" "); pw.println(r);
15342                    r.dump(pw, "    ");
15343                    if (r.persistent) {
15344                        numPers++;
15345                    }
15346                }
15347            }
15348        }
15349
15350        if (mIsolatedProcesses.size() > 0) {
15351            boolean printed = false;
15352            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15353                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15354                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15355                    continue;
15356                }
15357                if (!printed) {
15358                    if (needSep) {
15359                        pw.println();
15360                    }
15361                    pw.println("  Isolated process list (sorted by uid):");
15362                    printedAnything = true;
15363                    printed = true;
15364                    needSep = true;
15365                }
15366                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15367                pw.println(r);
15368            }
15369        }
15370
15371        if (mActiveInstrumentation.size() > 0) {
15372            boolean printed = false;
15373            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15374                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15375                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15376                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15377                    continue;
15378                }
15379                if (!printed) {
15380                    if (needSep) {
15381                        pw.println();
15382                    }
15383                    pw.println("  Active instrumentation:");
15384                    printedAnything = true;
15385                    printed = true;
15386                    needSep = true;
15387                }
15388                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15389                pw.println(ai);
15390                ai.dump(pw, "      ");
15391            }
15392        }
15393
15394        if (mActiveUids.size() > 0) {
15395            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15396                printedAnything = needSep = true;
15397            }
15398        }
15399        if (dumpAll) {
15400            if (mValidateUids.size() > 0) {
15401                if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15402                    printedAnything = needSep = true;
15403                }
15404            }
15405        }
15406
15407        if (mLruProcesses.size() > 0) {
15408            if (needSep) {
15409                pw.println();
15410            }
15411            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15412                    pw.print(" total, non-act at ");
15413                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15414                    pw.print(", non-svc at ");
15415                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15416                    pw.println("):");
15417            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15418            needSep = true;
15419            printedAnything = true;
15420        }
15421
15422        if (dumpAll || dumpPackage != null) {
15423            synchronized (mPidsSelfLocked) {
15424                boolean printed = false;
15425                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15426                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15427                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15428                        continue;
15429                    }
15430                    if (!printed) {
15431                        if (needSep) pw.println();
15432                        needSep = true;
15433                        pw.println("  PID mappings:");
15434                        printed = true;
15435                        printedAnything = true;
15436                    }
15437                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15438                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15439                }
15440            }
15441        }
15442
15443        if (mForegroundProcesses.size() > 0) {
15444            synchronized (mPidsSelfLocked) {
15445                boolean printed = false;
15446                for (int i=0; i<mForegroundProcesses.size(); i++) {
15447                    ProcessRecord r = mPidsSelfLocked.get(
15448                            mForegroundProcesses.valueAt(i).pid);
15449                    if (dumpPackage != null && (r == null
15450                            || !r.pkgList.containsKey(dumpPackage))) {
15451                        continue;
15452                    }
15453                    if (!printed) {
15454                        if (needSep) pw.println();
15455                        needSep = true;
15456                        pw.println("  Foreground Processes:");
15457                        printed = true;
15458                        printedAnything = true;
15459                    }
15460                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
15461                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
15462                }
15463            }
15464        }
15465
15466        if (mPersistentStartingProcesses.size() > 0) {
15467            if (needSep) pw.println();
15468            needSep = true;
15469            printedAnything = true;
15470            pw.println("  Persisent processes that are starting:");
15471            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15472                    "Starting Norm", "Restarting PERS", dumpPackage);
15473        }
15474
15475        if (mRemovedProcesses.size() > 0) {
15476            if (needSep) pw.println();
15477            needSep = true;
15478            printedAnything = true;
15479            pw.println("  Processes that are being removed:");
15480            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15481                    "Removed Norm", "Removed PERS", dumpPackage);
15482        }
15483
15484        if (mProcessesOnHold.size() > 0) {
15485            if (needSep) pw.println();
15486            needSep = true;
15487            printedAnything = true;
15488            pw.println("  Processes that are on old until the system is ready:");
15489            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15490                    "OnHold Norm", "OnHold PERS", dumpPackage);
15491        }
15492
15493        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15494
15495        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15496        if (needSep) {
15497            printedAnything = true;
15498        }
15499
15500        if (dumpPackage == null) {
15501            pw.println();
15502            needSep = false;
15503            mUserController.dump(pw, dumpAll);
15504        }
15505        if (mHomeProcess != null && (dumpPackage == null
15506                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15507            if (needSep) {
15508                pw.println();
15509                needSep = false;
15510            }
15511            pw.println("  mHomeProcess: " + mHomeProcess);
15512        }
15513        if (mPreviousProcess != null && (dumpPackage == null
15514                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15515            if (needSep) {
15516                pw.println();
15517                needSep = false;
15518            }
15519            pw.println("  mPreviousProcess: " + mPreviousProcess);
15520        }
15521        if (dumpAll) {
15522            StringBuilder sb = new StringBuilder(128);
15523            sb.append("  mPreviousProcessVisibleTime: ");
15524            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15525            pw.println(sb);
15526        }
15527        if (mHeavyWeightProcess != null && (dumpPackage == null
15528                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15529            if (needSep) {
15530                pw.println();
15531                needSep = false;
15532            }
15533            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15534        }
15535        if (dumpPackage == null) {
15536            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15537            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15538        }
15539        if (dumpAll) {
15540            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15541            if (mCompatModePackages.getPackages().size() > 0) {
15542                boolean printed = false;
15543                for (Map.Entry<String, Integer> entry
15544                        : mCompatModePackages.getPackages().entrySet()) {
15545                    String pkg = entry.getKey();
15546                    int mode = entry.getValue();
15547                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15548                        continue;
15549                    }
15550                    if (!printed) {
15551                        pw.println("  mScreenCompatPackages:");
15552                        printed = true;
15553                    }
15554                    pw.print("    "); pw.print(pkg); pw.print(": ");
15555                            pw.print(mode); pw.println();
15556                }
15557            }
15558            final int NI = mUidObservers.getRegisteredCallbackCount();
15559            boolean printed = false;
15560            for (int i=0; i<NI; i++) {
15561                final UidObserverRegistration reg = (UidObserverRegistration)
15562                        mUidObservers.getRegisteredCallbackCookie(i);
15563                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15564                    if (!printed) {
15565                        pw.println("  mUidObservers:");
15566                        printed = true;
15567                    }
15568                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15569                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15570                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15571                        pw.print(" IDLE");
15572                    }
15573                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15574                        pw.print(" ACT" );
15575                    }
15576                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15577                        pw.print(" GONE");
15578                    }
15579                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15580                        pw.print(" STATE");
15581                        pw.print(" (cut="); pw.print(reg.cutpoint);
15582                        pw.print(")");
15583                    }
15584                    pw.println();
15585                    if (reg.lastProcStates != null) {
15586                        final int NJ = reg.lastProcStates.size();
15587                        for (int j=0; j<NJ; j++) {
15588                            pw.print("      Last ");
15589                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15590                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15591                        }
15592                    }
15593                }
15594            }
15595            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15596            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15597            if (mPendingTempWhitelist.size() > 0) {
15598                pw.println("  mPendingTempWhitelist:");
15599                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15600                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15601                    pw.print("    ");
15602                    UserHandle.formatUid(pw, ptw.targetUid);
15603                    pw.print(": ");
15604                    TimeUtils.formatDuration(ptw.duration, pw);
15605                    pw.print(" ");
15606                    pw.println(ptw.tag);
15607                }
15608            }
15609        }
15610        if (dumpPackage == null) {
15611            pw.println("  mWakefulness="
15612                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15613            pw.println("  mSleepTokens=" + mSleepTokens);
15614            pw.println("  mSleeping=" + mSleeping);
15615            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15616            if (mRunningVoice != null) {
15617                pw.println("  mRunningVoice=" + mRunningVoice);
15618                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15619            }
15620        }
15621        pw.println("  mVrController=" + mVrController);
15622        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15623                || mOrigWaitForDebugger) {
15624            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15625                    || dumpPackage.equals(mOrigDebugApp)) {
15626                if (needSep) {
15627                    pw.println();
15628                    needSep = false;
15629                }
15630                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15631                        + " mDebugTransient=" + mDebugTransient
15632                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15633            }
15634        }
15635        if (mCurAppTimeTracker != null) {
15636            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15637        }
15638        if (mMemWatchProcesses.getMap().size() > 0) {
15639            pw.println("  Mem watch processes:");
15640            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15641                    = mMemWatchProcesses.getMap();
15642            for (int i=0; i<procs.size(); i++) {
15643                final String proc = procs.keyAt(i);
15644                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15645                for (int j=0; j<uids.size(); j++) {
15646                    if (needSep) {
15647                        pw.println();
15648                        needSep = false;
15649                    }
15650                    StringBuilder sb = new StringBuilder();
15651                    sb.append("    ").append(proc).append('/');
15652                    UserHandle.formatUid(sb, uids.keyAt(j));
15653                    Pair<Long, String> val = uids.valueAt(j);
15654                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15655                    if (val.second != null) {
15656                        sb.append(", report to ").append(val.second);
15657                    }
15658                    pw.println(sb.toString());
15659                }
15660            }
15661            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15662            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15663            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15664                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15665        }
15666        if (mTrackAllocationApp != null) {
15667            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15668                if (needSep) {
15669                    pw.println();
15670                    needSep = false;
15671                }
15672                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15673            }
15674        }
15675        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15676                || mProfileFd != null) {
15677            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15678                if (needSep) {
15679                    pw.println();
15680                    needSep = false;
15681                }
15682                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15683                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15684                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15685                        + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15686                pw.println("  mProfileType=" + mProfileType);
15687            }
15688        }
15689        if (mNativeDebuggingApp != null) {
15690            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15691                if (needSep) {
15692                    pw.println();
15693                    needSep = false;
15694                }
15695                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15696            }
15697        }
15698        if (dumpPackage == null) {
15699            if (mAlwaysFinishActivities) {
15700                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15701            }
15702            if (mController != null) {
15703                pw.println("  mController=" + mController
15704                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15705            }
15706            if (dumpAll) {
15707                pw.println("  Total persistent processes: " + numPers);
15708                pw.println("  mProcessesReady=" + mProcessesReady
15709                        + " mSystemReady=" + mSystemReady
15710                        + " mBooted=" + mBooted
15711                        + " mFactoryTest=" + mFactoryTest);
15712                pw.println("  mBooting=" + mBooting
15713                        + " mCallFinishBooting=" + mCallFinishBooting
15714                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15715                pw.print("  mLastPowerCheckRealtime=");
15716                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15717                        pw.println("");
15718                pw.print("  mLastPowerCheckUptime=");
15719                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15720                        pw.println("");
15721                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15722                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15723                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15724                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15725                        + " (" + mLruProcesses.size() + " total)"
15726                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15727                        + " mNumServiceProcs=" + mNumServiceProcs
15728                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15729                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15730                        + " mLastMemoryLevel=" + mLastMemoryLevel
15731                        + " mLastNumProcesses=" + mLastNumProcesses);
15732                long now = SystemClock.uptimeMillis();
15733                pw.print("  mLastIdleTime=");
15734                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15735                        pw.print(" mLowRamSinceLastIdle=");
15736                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15737                        pw.println();
15738            }
15739        }
15740
15741        if (!printedAnything) {
15742            pw.println("  (nothing)");
15743        }
15744    }
15745
15746    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15747            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15748        if (mProcessesToGc.size() > 0) {
15749            boolean printed = false;
15750            long now = SystemClock.uptimeMillis();
15751            for (int i=0; i<mProcessesToGc.size(); i++) {
15752                ProcessRecord proc = mProcessesToGc.get(i);
15753                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15754                    continue;
15755                }
15756                if (!printed) {
15757                    if (needSep) pw.println();
15758                    needSep = true;
15759                    pw.println("  Processes that are waiting to GC:");
15760                    printed = true;
15761                }
15762                pw.print("    Process "); pw.println(proc);
15763                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15764                        pw.print(", last gced=");
15765                        pw.print(now-proc.lastRequestedGc);
15766                        pw.print(" ms ago, last lowMem=");
15767                        pw.print(now-proc.lastLowMemory);
15768                        pw.println(" ms ago");
15769
15770            }
15771        }
15772        return needSep;
15773    }
15774
15775    void printOomLevel(PrintWriter pw, String name, int adj) {
15776        pw.print("    ");
15777        if (adj >= 0) {
15778            pw.print(' ');
15779            if (adj < 10) pw.print(' ');
15780        } else {
15781            if (adj > -10) pw.print(' ');
15782        }
15783        pw.print(adj);
15784        pw.print(": ");
15785        pw.print(name);
15786        pw.print(" (");
15787        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15788        pw.println(")");
15789    }
15790
15791    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15792            int opti, boolean dumpAll) {
15793        boolean needSep = false;
15794
15795        if (mLruProcesses.size() > 0) {
15796            if (needSep) pw.println();
15797            needSep = true;
15798            pw.println("  OOM levels:");
15799            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15800            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15801            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15802            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15803            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15804            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15805            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15806            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15807            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15808            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15809            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15810            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15811            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15812            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15813
15814            if (needSep) pw.println();
15815            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15816                    pw.print(" total, non-act at ");
15817                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15818                    pw.print(", non-svc at ");
15819                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15820                    pw.println("):");
15821            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15822            needSep = true;
15823        }
15824
15825        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15826
15827        pw.println();
15828        pw.println("  mHomeProcess: " + mHomeProcess);
15829        pw.println("  mPreviousProcess: " + mPreviousProcess);
15830        if (mHeavyWeightProcess != null) {
15831            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15832        }
15833
15834        return true;
15835    }
15836
15837    /**
15838     * There are three ways to call this:
15839     *  - no provider specified: dump all the providers
15840     *  - a flattened component name that matched an existing provider was specified as the
15841     *    first arg: dump that one provider
15842     *  - the first arg isn't the flattened component name of an existing provider:
15843     *    dump all providers whose component contains the first arg as a substring
15844     */
15845    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15846            int opti, boolean dumpAll) {
15847        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15848    }
15849
15850    static class ItemMatcher {
15851        ArrayList<ComponentName> components;
15852        ArrayList<String> strings;
15853        ArrayList<Integer> objects;
15854        boolean all;
15855
15856        ItemMatcher() {
15857            all = true;
15858        }
15859
15860        void build(String name) {
15861            ComponentName componentName = ComponentName.unflattenFromString(name);
15862            if (componentName != null) {
15863                if (components == null) {
15864                    components = new ArrayList<ComponentName>();
15865                }
15866                components.add(componentName);
15867                all = false;
15868            } else {
15869                int objectId = 0;
15870                // Not a '/' separated full component name; maybe an object ID?
15871                try {
15872                    objectId = Integer.parseInt(name, 16);
15873                    if (objects == null) {
15874                        objects = new ArrayList<Integer>();
15875                    }
15876                    objects.add(objectId);
15877                    all = false;
15878                } catch (RuntimeException e) {
15879                    // Not an integer; just do string match.
15880                    if (strings == null) {
15881                        strings = new ArrayList<String>();
15882                    }
15883                    strings.add(name);
15884                    all = false;
15885                }
15886            }
15887        }
15888
15889        int build(String[] args, int opti) {
15890            for (; opti<args.length; opti++) {
15891                String name = args[opti];
15892                if ("--".equals(name)) {
15893                    return opti+1;
15894                }
15895                build(name);
15896            }
15897            return opti;
15898        }
15899
15900        boolean match(Object object, ComponentName comp) {
15901            if (all) {
15902                return true;
15903            }
15904            if (components != null) {
15905                for (int i=0; i<components.size(); i++) {
15906                    if (components.get(i).equals(comp)) {
15907                        return true;
15908                    }
15909                }
15910            }
15911            if (objects != null) {
15912                for (int i=0; i<objects.size(); i++) {
15913                    if (System.identityHashCode(object) == objects.get(i)) {
15914                        return true;
15915                    }
15916                }
15917            }
15918            if (strings != null) {
15919                String flat = comp.flattenToString();
15920                for (int i=0; i<strings.size(); i++) {
15921                    if (flat.contains(strings.get(i))) {
15922                        return true;
15923                    }
15924                }
15925            }
15926            return false;
15927        }
15928    }
15929
15930    /**
15931     * There are three things that cmd can be:
15932     *  - a flattened component name that matches an existing activity
15933     *  - the cmd arg isn't the flattened component name of an existing activity:
15934     *    dump all activity whose component contains the cmd as a substring
15935     *  - A hex number of the ActivityRecord object instance.
15936     *
15937     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
15938     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
15939     */
15940    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15941            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
15942        ArrayList<ActivityRecord> activities;
15943
15944        synchronized (this) {
15945            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
15946                    dumpFocusedStackOnly);
15947        }
15948
15949        if (activities.size() <= 0) {
15950            return false;
15951        }
15952
15953        String[] newArgs = new String[args.length - opti];
15954        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15955
15956        TaskRecord lastTask = null;
15957        boolean needSep = false;
15958        for (int i=activities.size()-1; i>=0; i--) {
15959            ActivityRecord r = activities.get(i);
15960            if (needSep) {
15961                pw.println();
15962            }
15963            needSep = true;
15964            synchronized (this) {
15965                final TaskRecord task = r.getTask();
15966                if (lastTask != task) {
15967                    lastTask = task;
15968                    pw.print("TASK "); pw.print(lastTask.affinity);
15969                            pw.print(" id="); pw.print(lastTask.taskId);
15970                            pw.print(" userId="); pw.println(lastTask.userId);
15971                    if (dumpAll) {
15972                        lastTask.dump(pw, "  ");
15973                    }
15974                }
15975            }
15976            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15977        }
15978        return true;
15979    }
15980
15981    /**
15982     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15983     * there is a thread associated with the activity.
15984     */
15985    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15986            final ActivityRecord r, String[] args, boolean dumpAll) {
15987        String innerPrefix = prefix + "  ";
15988        synchronized (this) {
15989            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15990                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15991                    pw.print(" pid=");
15992                    if (r.app != null) pw.println(r.app.pid);
15993                    else pw.println("(not running)");
15994            if (dumpAll) {
15995                r.dump(pw, innerPrefix);
15996            }
15997        }
15998        if (r.app != null && r.app.thread != null) {
15999            // flush anything that is already in the PrintWriter since the thread is going
16000            // to write to the file descriptor directly
16001            pw.flush();
16002            try {
16003                TransferPipe tp = new TransferPipe();
16004                try {
16005                    r.app.thread.dumpActivity(tp.getWriteFd(),
16006                            r.appToken, innerPrefix, args);
16007                    tp.go(fd);
16008                } finally {
16009                    tp.kill();
16010                }
16011            } catch (IOException e) {
16012                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16013            } catch (RemoteException e) {
16014                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16015            }
16016        }
16017    }
16018
16019    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16020            int opti, boolean dumpAll, String dumpPackage) {
16021        boolean needSep = false;
16022        boolean onlyHistory = false;
16023        boolean printedAnything = false;
16024
16025        if ("history".equals(dumpPackage)) {
16026            if (opti < args.length && "-s".equals(args[opti])) {
16027                dumpAll = false;
16028            }
16029            onlyHistory = true;
16030            dumpPackage = null;
16031        }
16032
16033        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16034        if (!onlyHistory && dumpAll) {
16035            if (mRegisteredReceivers.size() > 0) {
16036                boolean printed = false;
16037                Iterator it = mRegisteredReceivers.values().iterator();
16038                while (it.hasNext()) {
16039                    ReceiverList r = (ReceiverList)it.next();
16040                    if (dumpPackage != null && (r.app == null ||
16041                            !dumpPackage.equals(r.app.info.packageName))) {
16042                        continue;
16043                    }
16044                    if (!printed) {
16045                        pw.println("  Registered Receivers:");
16046                        needSep = true;
16047                        printed = true;
16048                        printedAnything = true;
16049                    }
16050                    pw.print("  * "); pw.println(r);
16051                    r.dump(pw, "    ");
16052                }
16053            }
16054
16055            if (mReceiverResolver.dump(pw, needSep ?
16056                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16057                    "    ", dumpPackage, false, false)) {
16058                needSep = true;
16059                printedAnything = true;
16060            }
16061        }
16062
16063        for (BroadcastQueue q : mBroadcastQueues) {
16064            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16065            printedAnything |= needSep;
16066        }
16067
16068        needSep = true;
16069
16070        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16071            for (int user=0; user<mStickyBroadcasts.size(); user++) {
16072                if (needSep) {
16073                    pw.println();
16074                }
16075                needSep = true;
16076                printedAnything = true;
16077                pw.print("  Sticky broadcasts for user ");
16078                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16079                StringBuilder sb = new StringBuilder(128);
16080                for (Map.Entry<String, ArrayList<Intent>> ent
16081                        : mStickyBroadcasts.valueAt(user).entrySet()) {
16082                    pw.print("  * Sticky action "); pw.print(ent.getKey());
16083                    if (dumpAll) {
16084                        pw.println(":");
16085                        ArrayList<Intent> intents = ent.getValue();
16086                        final int N = intents.size();
16087                        for (int i=0; i<N; i++) {
16088                            sb.setLength(0);
16089                            sb.append("    Intent: ");
16090                            intents.get(i).toShortString(sb, false, true, false, false);
16091                            pw.println(sb.toString());
16092                            Bundle bundle = intents.get(i).getExtras();
16093                            if (bundle != null) {
16094                                pw.print("      ");
16095                                pw.println(bundle.toString());
16096                            }
16097                        }
16098                    } else {
16099                        pw.println("");
16100                    }
16101                }
16102            }
16103        }
16104
16105        if (!onlyHistory && dumpAll) {
16106            pw.println();
16107            for (BroadcastQueue queue : mBroadcastQueues) {
16108                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16109                        + queue.mBroadcastsScheduled);
16110            }
16111            pw.println("  mHandler:");
16112            mHandler.dump(new PrintWriterPrinter(pw), "    ");
16113            needSep = true;
16114            printedAnything = true;
16115        }
16116
16117        if (!printedAnything) {
16118            pw.println("  (nothing)");
16119        }
16120    }
16121
16122    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16123            int opti, boolean dumpAll, String dumpPackage) {
16124        if (mCurBroadcastStats == null) {
16125            return;
16126        }
16127
16128        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16129        final long now = SystemClock.elapsedRealtime();
16130        if (mLastBroadcastStats != null) {
16131            pw.print("  Last stats (from ");
16132            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16133            pw.print(" to ");
16134            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16135            pw.print(", ");
16136            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16137                    - mLastBroadcastStats.mStartUptime, pw);
16138            pw.println(" uptime):");
16139            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16140                pw.println("    (nothing)");
16141            }
16142            pw.println();
16143        }
16144        pw.print("  Current stats (from ");
16145        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16146        pw.print(" to now, ");
16147        TimeUtils.formatDuration(SystemClock.uptimeMillis()
16148                - mCurBroadcastStats.mStartUptime, pw);
16149        pw.println(" uptime):");
16150        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16151            pw.println("    (nothing)");
16152        }
16153    }
16154
16155    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16156            int opti, boolean fullCheckin, String dumpPackage) {
16157        if (mCurBroadcastStats == null) {
16158            return;
16159        }
16160
16161        if (mLastBroadcastStats != null) {
16162            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16163            if (fullCheckin) {
16164                mLastBroadcastStats = null;
16165                return;
16166            }
16167        }
16168        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16169        if (fullCheckin) {
16170            mCurBroadcastStats = null;
16171        }
16172    }
16173
16174    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16175            int opti, boolean dumpAll, String dumpPackage) {
16176        boolean needSep;
16177        boolean printedAnything = false;
16178
16179        ItemMatcher matcher = new ItemMatcher();
16180        matcher.build(args, opti);
16181
16182        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16183
16184        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16185        printedAnything |= needSep;
16186
16187        if (mLaunchingProviders.size() > 0) {
16188            boolean printed = false;
16189            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16190                ContentProviderRecord r = mLaunchingProviders.get(i);
16191                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16192                    continue;
16193                }
16194                if (!printed) {
16195                    if (needSep) pw.println();
16196                    needSep = true;
16197                    pw.println("  Launching content providers:");
16198                    printed = true;
16199                    printedAnything = true;
16200                }
16201                pw.print("  Launching #"); pw.print(i); pw.print(": ");
16202                        pw.println(r);
16203            }
16204        }
16205
16206        if (!printedAnything) {
16207            pw.println("  (nothing)");
16208        }
16209    }
16210
16211    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16212            int opti, boolean dumpAll, String dumpPackage) {
16213        boolean needSep = false;
16214        boolean printedAnything = false;
16215
16216        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16217
16218        if (mGrantedUriPermissions.size() > 0) {
16219            boolean printed = false;
16220            int dumpUid = -2;
16221            if (dumpPackage != null) {
16222                try {
16223                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16224                            MATCH_ANY_USER, 0);
16225                } catch (NameNotFoundException e) {
16226                    dumpUid = -1;
16227                }
16228            }
16229            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16230                int uid = mGrantedUriPermissions.keyAt(i);
16231                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16232                    continue;
16233                }
16234                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16235                if (!printed) {
16236                    if (needSep) pw.println();
16237                    needSep = true;
16238                    pw.println("  Granted Uri Permissions:");
16239                    printed = true;
16240                    printedAnything = true;
16241                }
16242                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16243                for (UriPermission perm : perms.values()) {
16244                    pw.print("    "); pw.println(perm);
16245                    if (dumpAll) {
16246                        perm.dump(pw, "      ");
16247                    }
16248                }
16249            }
16250        }
16251
16252        if (!printedAnything) {
16253            pw.println("  (nothing)");
16254        }
16255    }
16256
16257    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16258            int opti, boolean dumpAll, String dumpPackage) {
16259        boolean printed = false;
16260
16261        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16262
16263        if (mIntentSenderRecords.size() > 0) {
16264            // Organize these by package name, so they are easier to read.
16265            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16266            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16267            final Iterator<WeakReference<PendingIntentRecord>> it
16268                    = mIntentSenderRecords.values().iterator();
16269            while (it.hasNext()) {
16270                WeakReference<PendingIntentRecord> ref = it.next();
16271                PendingIntentRecord rec = ref != null ? ref.get() : null;
16272                if (rec == null) {
16273                    weakRefs.add(ref);
16274                    continue;
16275                }
16276                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16277                    continue;
16278                }
16279                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16280                if (list == null) {
16281                    list = new ArrayList<>();
16282                    byPackage.put(rec.key.packageName, list);
16283                }
16284                list.add(rec);
16285            }
16286            for (int i = 0; i < byPackage.size(); i++) {
16287                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16288                printed = true;
16289                pw.print("  * "); pw.print(byPackage.keyAt(i));
16290                pw.print(": "); pw.print(intents.size()); pw.println(" items");
16291                for (int j = 0; j < intents.size(); j++) {
16292                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16293                    if (dumpAll) {
16294                        intents.get(j).dump(pw, "      ");
16295                    }
16296                }
16297            }
16298            if (weakRefs.size() > 0) {
16299                printed = true;
16300                pw.println("  * WEAK REFS:");
16301                for (int i = 0; i < weakRefs.size(); i++) {
16302                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16303                }
16304            }
16305        }
16306
16307        if (!printed) {
16308            pw.println("  (nothing)");
16309        }
16310    }
16311
16312    private static final int dumpProcessList(PrintWriter pw,
16313            ActivityManagerService service, List list,
16314            String prefix, String normalLabel, String persistentLabel,
16315            String dumpPackage) {
16316        int numPers = 0;
16317        final int N = list.size()-1;
16318        for (int i=N; i>=0; i--) {
16319            ProcessRecord r = (ProcessRecord)list.get(i);
16320            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16321                continue;
16322            }
16323            pw.println(String.format("%s%s #%2d: %s",
16324                    prefix, (r.persistent ? persistentLabel : normalLabel),
16325                    i, r.toString()));
16326            if (r.persistent) {
16327                numPers++;
16328            }
16329        }
16330        return numPers;
16331    }
16332
16333    private static final boolean dumpProcessOomList(PrintWriter pw,
16334            ActivityManagerService service, List<ProcessRecord> origList,
16335            String prefix, String normalLabel, String persistentLabel,
16336            boolean inclDetails, String dumpPackage) {
16337
16338        ArrayList<Pair<ProcessRecord, Integer>> list
16339                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16340        for (int i=0; i<origList.size(); i++) {
16341            ProcessRecord r = origList.get(i);
16342            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16343                continue;
16344            }
16345            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16346        }
16347
16348        if (list.size() <= 0) {
16349            return false;
16350        }
16351
16352        Comparator<Pair<ProcessRecord, Integer>> comparator
16353                = new Comparator<Pair<ProcessRecord, Integer>>() {
16354            @Override
16355            public int compare(Pair<ProcessRecord, Integer> object1,
16356                    Pair<ProcessRecord, Integer> object2) {
16357                if (object1.first.setAdj != object2.first.setAdj) {
16358                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16359                }
16360                if (object1.first.setProcState != object2.first.setProcState) {
16361                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16362                }
16363                if (object1.second.intValue() != object2.second.intValue()) {
16364                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16365                }
16366                return 0;
16367            }
16368        };
16369
16370        Collections.sort(list, comparator);
16371
16372        final long curRealtime = SystemClock.elapsedRealtime();
16373        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16374        final long curUptime = SystemClock.uptimeMillis();
16375        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16376
16377        for (int i=list.size()-1; i>=0; i--) {
16378            ProcessRecord r = list.get(i).first;
16379            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16380            char schedGroup;
16381            switch (r.setSchedGroup) {
16382                case ProcessList.SCHED_GROUP_BACKGROUND:
16383                    schedGroup = 'B';
16384                    break;
16385                case ProcessList.SCHED_GROUP_DEFAULT:
16386                    schedGroup = 'F';
16387                    break;
16388                case ProcessList.SCHED_GROUP_TOP_APP:
16389                    schedGroup = 'T';
16390                    break;
16391                default:
16392                    schedGroup = '?';
16393                    break;
16394            }
16395            char foreground;
16396            if (r.foregroundActivities) {
16397                foreground = 'A';
16398            } else if (r.foregroundServices) {
16399                foreground = 'S';
16400            } else {
16401                foreground = ' ';
16402            }
16403            String procState = ProcessList.makeProcStateString(r.curProcState);
16404            pw.print(prefix);
16405            pw.print(r.persistent ? persistentLabel : normalLabel);
16406            pw.print(" #");
16407            int num = (origList.size()-1)-list.get(i).second;
16408            if (num < 10) pw.print(' ');
16409            pw.print(num);
16410            pw.print(": ");
16411            pw.print(oomAdj);
16412            pw.print(' ');
16413            pw.print(schedGroup);
16414            pw.print('/');
16415            pw.print(foreground);
16416            pw.print('/');
16417            pw.print(procState);
16418            pw.print(" trm:");
16419            if (r.trimMemoryLevel < 10) pw.print(' ');
16420            pw.print(r.trimMemoryLevel);
16421            pw.print(' ');
16422            pw.print(r.toShortString());
16423            pw.print(" (");
16424            pw.print(r.adjType);
16425            pw.println(')');
16426            if (r.adjSource != null || r.adjTarget != null) {
16427                pw.print(prefix);
16428                pw.print("    ");
16429                if (r.adjTarget instanceof ComponentName) {
16430                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16431                } else if (r.adjTarget != null) {
16432                    pw.print(r.adjTarget.toString());
16433                } else {
16434                    pw.print("{null}");
16435                }
16436                pw.print("<=");
16437                if (r.adjSource instanceof ProcessRecord) {
16438                    pw.print("Proc{");
16439                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16440                    pw.println("}");
16441                } else if (r.adjSource != null) {
16442                    pw.println(r.adjSource.toString());
16443                } else {
16444                    pw.println("{null}");
16445                }
16446            }
16447            if (inclDetails) {
16448                pw.print(prefix);
16449                pw.print("    ");
16450                pw.print("oom: max="); pw.print(r.maxAdj);
16451                pw.print(" curRaw="); pw.print(r.curRawAdj);
16452                pw.print(" setRaw="); pw.print(r.setRawAdj);
16453                pw.print(" cur="); pw.print(r.curAdj);
16454                pw.print(" set="); pw.println(r.setAdj);
16455                pw.print(prefix);
16456                pw.print("    ");
16457                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16458                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16459                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16460                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16461                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16462                pw.println();
16463                pw.print(prefix);
16464                pw.print("    ");
16465                pw.print("cached="); pw.print(r.cached);
16466                pw.print(" empty="); pw.print(r.empty);
16467                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16468
16469                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16470                    if (r.lastWakeTime != 0) {
16471                        long wtime;
16472                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16473                        synchronized (stats) {
16474                            wtime = stats.getProcessWakeTime(r.info.uid,
16475                                    r.pid, curRealtime);
16476                        }
16477                        long timeUsed = wtime - r.lastWakeTime;
16478                        pw.print(prefix);
16479                        pw.print("    ");
16480                        pw.print("keep awake over ");
16481                        TimeUtils.formatDuration(realtimeSince, pw);
16482                        pw.print(" used ");
16483                        TimeUtils.formatDuration(timeUsed, pw);
16484                        pw.print(" (");
16485                        pw.print((timeUsed*100)/realtimeSince);
16486                        pw.println("%)");
16487                    }
16488                    if (r.lastCpuTime != 0) {
16489                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16490                        pw.print(prefix);
16491                        pw.print("    ");
16492                        pw.print("run cpu over ");
16493                        TimeUtils.formatDuration(uptimeSince, pw);
16494                        pw.print(" used ");
16495                        TimeUtils.formatDuration(timeUsed, pw);
16496                        pw.print(" (");
16497                        pw.print((timeUsed*100)/uptimeSince);
16498                        pw.println("%)");
16499                    }
16500                }
16501            }
16502        }
16503        return true;
16504    }
16505
16506    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16507            String[] args) {
16508        ArrayList<ProcessRecord> procs;
16509        synchronized (this) {
16510            if (args != null && args.length > start
16511                    && args[start].charAt(0) != '-') {
16512                procs = new ArrayList<ProcessRecord>();
16513                int pid = -1;
16514                try {
16515                    pid = Integer.parseInt(args[start]);
16516                } catch (NumberFormatException e) {
16517                }
16518                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16519                    ProcessRecord proc = mLruProcesses.get(i);
16520                    if (proc.pid == pid) {
16521                        procs.add(proc);
16522                    } else if (allPkgs && proc.pkgList != null
16523                            && proc.pkgList.containsKey(args[start])) {
16524                        procs.add(proc);
16525                    } else if (proc.processName.equals(args[start])) {
16526                        procs.add(proc);
16527                    }
16528                }
16529                if (procs.size() <= 0) {
16530                    return null;
16531                }
16532            } else {
16533                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16534            }
16535        }
16536        return procs;
16537    }
16538
16539    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16540            PrintWriter pw, String[] args) {
16541        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16542        if (procs == null) {
16543            pw.println("No process found for: " + args[0]);
16544            return;
16545        }
16546
16547        long uptime = SystemClock.uptimeMillis();
16548        long realtime = SystemClock.elapsedRealtime();
16549        pw.println("Applications Graphics Acceleration Info:");
16550        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16551
16552        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16553            ProcessRecord r = procs.get(i);
16554            if (r.thread != null) {
16555                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16556                pw.flush();
16557                try {
16558                    TransferPipe tp = new TransferPipe();
16559                    try {
16560                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16561                        tp.go(fd);
16562                    } finally {
16563                        tp.kill();
16564                    }
16565                } catch (IOException e) {
16566                    pw.println("Failure while dumping the app: " + r);
16567                    pw.flush();
16568                } catch (RemoteException e) {
16569                    pw.println("Got a RemoteException while dumping the app " + r);
16570                    pw.flush();
16571                }
16572            }
16573        }
16574    }
16575
16576    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16577        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16578        if (procs == null) {
16579            pw.println("No process found for: " + args[0]);
16580            return;
16581        }
16582
16583        pw.println("Applications Database Info:");
16584
16585        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16586            ProcessRecord r = procs.get(i);
16587            if (r.thread != null) {
16588                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16589                pw.flush();
16590                try {
16591                    TransferPipe tp = new TransferPipe();
16592                    try {
16593                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16594                        tp.go(fd);
16595                    } finally {
16596                        tp.kill();
16597                    }
16598                } catch (IOException e) {
16599                    pw.println("Failure while dumping the app: " + r);
16600                    pw.flush();
16601                } catch (RemoteException e) {
16602                    pw.println("Got a RemoteException while dumping the app " + r);
16603                    pw.flush();
16604                }
16605            }
16606        }
16607    }
16608
16609    final static class MemItem {
16610        final boolean isProc;
16611        final String label;
16612        final String shortLabel;
16613        final long pss;
16614        final long swapPss;
16615        final int id;
16616        final boolean hasActivities;
16617        ArrayList<MemItem> subitems;
16618
16619        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16620                boolean _hasActivities) {
16621            isProc = true;
16622            label = _label;
16623            shortLabel = _shortLabel;
16624            pss = _pss;
16625            swapPss = _swapPss;
16626            id = _id;
16627            hasActivities = _hasActivities;
16628        }
16629
16630        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16631            isProc = false;
16632            label = _label;
16633            shortLabel = _shortLabel;
16634            pss = _pss;
16635            swapPss = _swapPss;
16636            id = _id;
16637            hasActivities = false;
16638        }
16639    }
16640
16641    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16642            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16643        if (sort && !isCompact) {
16644            Collections.sort(items, new Comparator<MemItem>() {
16645                @Override
16646                public int compare(MemItem lhs, MemItem rhs) {
16647                    if (lhs.pss < rhs.pss) {
16648                        return 1;
16649                    } else if (lhs.pss > rhs.pss) {
16650                        return -1;
16651                    }
16652                    return 0;
16653                }
16654            });
16655        }
16656
16657        for (int i=0; i<items.size(); i++) {
16658            MemItem mi = items.get(i);
16659            if (!isCompact) {
16660                if (dumpSwapPss) {
16661                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16662                            mi.label, stringifyKBSize(mi.swapPss));
16663                } else {
16664                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16665                }
16666            } else if (mi.isProc) {
16667                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16668                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16669                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16670                pw.println(mi.hasActivities ? ",a" : ",e");
16671            } else {
16672                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16673                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16674            }
16675            if (mi.subitems != null) {
16676                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16677                        true, isCompact, dumpSwapPss);
16678            }
16679        }
16680    }
16681
16682    // These are in KB.
16683    static final long[] DUMP_MEM_BUCKETS = new long[] {
16684        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16685        120*1024, 160*1024, 200*1024,
16686        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16687        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16688    };
16689
16690    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16691            boolean stackLike) {
16692        int start = label.lastIndexOf('.');
16693        if (start >= 0) start++;
16694        else start = 0;
16695        int end = label.length();
16696        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16697            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16698                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16699                out.append(bucket);
16700                out.append(stackLike ? "MB." : "MB ");
16701                out.append(label, start, end);
16702                return;
16703            }
16704        }
16705        out.append(memKB/1024);
16706        out.append(stackLike ? "MB." : "MB ");
16707        out.append(label, start, end);
16708    }
16709
16710    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16711            ProcessList.NATIVE_ADJ,
16712            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16713            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16714            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16715            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16716            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16717            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16718    };
16719    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16720            "Native",
16721            "System", "Persistent", "Persistent Service", "Foreground",
16722            "Visible", "Perceptible",
16723            "Heavy Weight", "Backup",
16724            "A Services", "Home",
16725            "Previous", "B Services", "Cached"
16726    };
16727    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16728            "native",
16729            "sys", "pers", "persvc", "fore",
16730            "vis", "percept",
16731            "heavy", "backup",
16732            "servicea", "home",
16733            "prev", "serviceb", "cached"
16734    };
16735
16736    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16737            long realtime, boolean isCheckinRequest, boolean isCompact) {
16738        if (isCompact) {
16739            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16740        }
16741        if (isCheckinRequest || isCompact) {
16742            // short checkin version
16743            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16744        } else {
16745            pw.println("Applications Memory Usage (in Kilobytes):");
16746            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16747        }
16748    }
16749
16750    private static final int KSM_SHARED = 0;
16751    private static final int KSM_SHARING = 1;
16752    private static final int KSM_UNSHARED = 2;
16753    private static final int KSM_VOLATILE = 3;
16754
16755    private final long[] getKsmInfo() {
16756        long[] longOut = new long[4];
16757        final int[] SINGLE_LONG_FORMAT = new int[] {
16758            PROC_SPACE_TERM| PROC_OUT_LONG
16759        };
16760        long[] longTmp = new long[1];
16761        readProcFile("/sys/kernel/mm/ksm/pages_shared",
16762                SINGLE_LONG_FORMAT, null, longTmp, null);
16763        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16764        longTmp[0] = 0;
16765        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16766                SINGLE_LONG_FORMAT, null, longTmp, null);
16767        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16768        longTmp[0] = 0;
16769        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16770                SINGLE_LONG_FORMAT, null, longTmp, null);
16771        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16772        longTmp[0] = 0;
16773        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16774                SINGLE_LONG_FORMAT, null, longTmp, null);
16775        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16776        return longOut;
16777    }
16778
16779    private static String stringifySize(long size, int order) {
16780        Locale locale = Locale.US;
16781        switch (order) {
16782            case 1:
16783                return String.format(locale, "%,13d", size);
16784            case 1024:
16785                return String.format(locale, "%,9dK", size / 1024);
16786            case 1024 * 1024:
16787                return String.format(locale, "%,5dM", size / 1024 / 1024);
16788            case 1024 * 1024 * 1024:
16789                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16790            default:
16791                throw new IllegalArgumentException("Invalid size order");
16792        }
16793    }
16794
16795    private static String stringifyKBSize(long size) {
16796        return stringifySize(size * 1024, 1024);
16797    }
16798
16799    // Update this version number in case you change the 'compact' format
16800    private static final int MEMINFO_COMPACT_VERSION = 1;
16801
16802    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16803            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16804        boolean dumpDetails = false;
16805        boolean dumpFullDetails = false;
16806        boolean dumpDalvik = false;
16807        boolean dumpSummaryOnly = false;
16808        boolean dumpUnreachable = false;
16809        boolean oomOnly = false;
16810        boolean isCompact = false;
16811        boolean localOnly = false;
16812        boolean packages = false;
16813        boolean isCheckinRequest = false;
16814        boolean dumpSwapPss = false;
16815
16816        int opti = 0;
16817        while (opti < args.length) {
16818            String opt = args[opti];
16819            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16820                break;
16821            }
16822            opti++;
16823            if ("-a".equals(opt)) {
16824                dumpDetails = true;
16825                dumpFullDetails = true;
16826                dumpDalvik = true;
16827                dumpSwapPss = true;
16828            } else if ("-d".equals(opt)) {
16829                dumpDalvik = true;
16830            } else if ("-c".equals(opt)) {
16831                isCompact = true;
16832            } else if ("-s".equals(opt)) {
16833                dumpDetails = true;
16834                dumpSummaryOnly = true;
16835            } else if ("-S".equals(opt)) {
16836                dumpSwapPss = true;
16837            } else if ("--unreachable".equals(opt)) {
16838                dumpUnreachable = true;
16839            } else if ("--oom".equals(opt)) {
16840                oomOnly = true;
16841            } else if ("--local".equals(opt)) {
16842                localOnly = true;
16843            } else if ("--package".equals(opt)) {
16844                packages = true;
16845            } else if ("--checkin".equals(opt)) {
16846                isCheckinRequest = true;
16847
16848            } else if ("-h".equals(opt)) {
16849                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16850                pw.println("  -a: include all available information for each process.");
16851                pw.println("  -d: include dalvik details.");
16852                pw.println("  -c: dump in a compact machine-parseable representation.");
16853                pw.println("  -s: dump only summary of application memory usage.");
16854                pw.println("  -S: dump also SwapPss.");
16855                pw.println("  --oom: only show processes organized by oom adj.");
16856                pw.println("  --local: only collect details locally, don't call process.");
16857                pw.println("  --package: interpret process arg as package, dumping all");
16858                pw.println("             processes that have loaded that package.");
16859                pw.println("  --checkin: dump data for a checkin");
16860                pw.println("If [process] is specified it can be the name or ");
16861                pw.println("pid of a specific process to dump.");
16862                return;
16863            } else {
16864                pw.println("Unknown argument: " + opt + "; use -h for help");
16865            }
16866        }
16867
16868        long uptime = SystemClock.uptimeMillis();
16869        long realtime = SystemClock.elapsedRealtime();
16870        final long[] tmpLong = new long[1];
16871
16872        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16873        if (procs == null) {
16874            // No Java processes.  Maybe they want to print a native process.
16875            if (args != null && args.length > opti
16876                    && args[opti].charAt(0) != '-') {
16877                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16878                        = new ArrayList<ProcessCpuTracker.Stats>();
16879                updateCpuStatsNow();
16880                int findPid = -1;
16881                try {
16882                    findPid = Integer.parseInt(args[opti]);
16883                } catch (NumberFormatException e) {
16884                }
16885                synchronized (mProcessCpuTracker) {
16886                    final int N = mProcessCpuTracker.countStats();
16887                    for (int i=0; i<N; i++) {
16888                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16889                        if (st.pid == findPid || (st.baseName != null
16890                                && st.baseName.equals(args[opti]))) {
16891                            nativeProcs.add(st);
16892                        }
16893                    }
16894                }
16895                if (nativeProcs.size() > 0) {
16896                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16897                            isCompact);
16898                    Debug.MemoryInfo mi = null;
16899                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16900                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16901                        final int pid = r.pid;
16902                        if (!isCheckinRequest && dumpDetails) {
16903                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16904                        }
16905                        if (mi == null) {
16906                            mi = new Debug.MemoryInfo();
16907                        }
16908                        if (dumpDetails || (!brief && !oomOnly)) {
16909                            Debug.getMemoryInfo(pid, mi);
16910                        } else {
16911                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16912                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16913                        }
16914                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16915                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16916                        if (isCheckinRequest) {
16917                            pw.println();
16918                        }
16919                    }
16920                    return;
16921                }
16922            }
16923            pw.println("No process found for: " + args[opti]);
16924            return;
16925        }
16926
16927        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16928            dumpDetails = true;
16929        }
16930
16931        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16932
16933        String[] innerArgs = new String[args.length-opti];
16934        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16935
16936        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16937        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16938        long nativePss = 0;
16939        long nativeSwapPss = 0;
16940        long dalvikPss = 0;
16941        long dalvikSwapPss = 0;
16942        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16943                EmptyArray.LONG;
16944        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16945                EmptyArray.LONG;
16946        long otherPss = 0;
16947        long otherSwapPss = 0;
16948        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16949        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16950
16951        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16952        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16953        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16954                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16955
16956        long totalPss = 0;
16957        long totalSwapPss = 0;
16958        long cachedPss = 0;
16959        long cachedSwapPss = 0;
16960        boolean hasSwapPss = false;
16961
16962        Debug.MemoryInfo mi = null;
16963        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16964            final ProcessRecord r = procs.get(i);
16965            final IApplicationThread thread;
16966            final int pid;
16967            final int oomAdj;
16968            final boolean hasActivities;
16969            synchronized (this) {
16970                thread = r.thread;
16971                pid = r.pid;
16972                oomAdj = r.getSetAdjWithServices();
16973                hasActivities = r.activities.size() > 0;
16974            }
16975            if (thread != null) {
16976                if (!isCheckinRequest && dumpDetails) {
16977                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16978                }
16979                if (mi == null) {
16980                    mi = new Debug.MemoryInfo();
16981                }
16982                if (dumpDetails || (!brief && !oomOnly)) {
16983                    Debug.getMemoryInfo(pid, mi);
16984                    hasSwapPss = mi.hasSwappedOutPss;
16985                } else {
16986                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16987                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16988                }
16989                if (dumpDetails) {
16990                    if (localOnly) {
16991                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16992                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16993                        if (isCheckinRequest) {
16994                            pw.println();
16995                        }
16996                    } else {
16997                        pw.flush();
16998                        try {
16999                            TransferPipe tp = new TransferPipe();
17000                            try {
17001                                thread.dumpMemInfo(tp.getWriteFd(),
17002                                        mi, isCheckinRequest, dumpFullDetails,
17003                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17004                                tp.go(fd);
17005                            } finally {
17006                                tp.kill();
17007                            }
17008                        } catch (IOException e) {
17009                            if (!isCheckinRequest) {
17010                                pw.println("Got IoException!");
17011                                pw.flush();
17012                            }
17013                        } catch (RemoteException e) {
17014                            if (!isCheckinRequest) {
17015                                pw.println("Got RemoteException!");
17016                                pw.flush();
17017                            }
17018                        }
17019                    }
17020                }
17021
17022                final long myTotalPss = mi.getTotalPss();
17023                final long myTotalUss = mi.getTotalUss();
17024                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17025
17026                synchronized (this) {
17027                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17028                        // Record this for posterity if the process has been stable.
17029                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17030                    }
17031                }
17032
17033                if (!isCheckinRequest && mi != null) {
17034                    totalPss += myTotalPss;
17035                    totalSwapPss += myTotalSwapPss;
17036                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17037                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17038                            myTotalSwapPss, pid, hasActivities);
17039                    procMems.add(pssItem);
17040                    procMemsMap.put(pid, pssItem);
17041
17042                    nativePss += mi.nativePss;
17043                    nativeSwapPss += mi.nativeSwappedOutPss;
17044                    dalvikPss += mi.dalvikPss;
17045                    dalvikSwapPss += mi.dalvikSwappedOutPss;
17046                    for (int j=0; j<dalvikSubitemPss.length; j++) {
17047                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17048                        dalvikSubitemSwapPss[j] +=
17049                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17050                    }
17051                    otherPss += mi.otherPss;
17052                    otherSwapPss += mi.otherSwappedOutPss;
17053                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17054                        long mem = mi.getOtherPss(j);
17055                        miscPss[j] += mem;
17056                        otherPss -= mem;
17057                        mem = mi.getOtherSwappedOutPss(j);
17058                        miscSwapPss[j] += mem;
17059                        otherSwapPss -= mem;
17060                    }
17061
17062                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17063                        cachedPss += myTotalPss;
17064                        cachedSwapPss += myTotalSwapPss;
17065                    }
17066
17067                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17068                        if (oomIndex == (oomPss.length - 1)
17069                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17070                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17071                            oomPss[oomIndex] += myTotalPss;
17072                            oomSwapPss[oomIndex] += myTotalSwapPss;
17073                            if (oomProcs[oomIndex] == null) {
17074                                oomProcs[oomIndex] = new ArrayList<MemItem>();
17075                            }
17076                            oomProcs[oomIndex].add(pssItem);
17077                            break;
17078                        }
17079                    }
17080                }
17081            }
17082        }
17083
17084        long nativeProcTotalPss = 0;
17085
17086        if (!isCheckinRequest && procs.size() > 1 && !packages) {
17087            // If we are showing aggregations, also look for native processes to
17088            // include so that our aggregations are more accurate.
17089            updateCpuStatsNow();
17090            mi = null;
17091            synchronized (mProcessCpuTracker) {
17092                final int N = mProcessCpuTracker.countStats();
17093                for (int i=0; i<N; i++) {
17094                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17095                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17096                        if (mi == null) {
17097                            mi = new Debug.MemoryInfo();
17098                        }
17099                        if (!brief && !oomOnly) {
17100                            Debug.getMemoryInfo(st.pid, mi);
17101                        } else {
17102                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17103                            mi.nativePrivateDirty = (int)tmpLong[0];
17104                        }
17105
17106                        final long myTotalPss = mi.getTotalPss();
17107                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17108                        totalPss += myTotalPss;
17109                        nativeProcTotalPss += myTotalPss;
17110
17111                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17112                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17113                        procMems.add(pssItem);
17114
17115                        nativePss += mi.nativePss;
17116                        nativeSwapPss += mi.nativeSwappedOutPss;
17117                        dalvikPss += mi.dalvikPss;
17118                        dalvikSwapPss += mi.dalvikSwappedOutPss;
17119                        for (int j=0; j<dalvikSubitemPss.length; j++) {
17120                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17121                            dalvikSubitemSwapPss[j] +=
17122                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17123                        }
17124                        otherPss += mi.otherPss;
17125                        otherSwapPss += mi.otherSwappedOutPss;
17126                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17127                            long mem = mi.getOtherPss(j);
17128                            miscPss[j] += mem;
17129                            otherPss -= mem;
17130                            mem = mi.getOtherSwappedOutPss(j);
17131                            miscSwapPss[j] += mem;
17132                            otherSwapPss -= mem;
17133                        }
17134                        oomPss[0] += myTotalPss;
17135                        oomSwapPss[0] += myTotalSwapPss;
17136                        if (oomProcs[0] == null) {
17137                            oomProcs[0] = new ArrayList<MemItem>();
17138                        }
17139                        oomProcs[0].add(pssItem);
17140                    }
17141                }
17142            }
17143
17144            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17145
17146            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17147            final MemItem dalvikItem =
17148                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17149            if (dalvikSubitemPss.length > 0) {
17150                dalvikItem.subitems = new ArrayList<MemItem>();
17151                for (int j=0; j<dalvikSubitemPss.length; j++) {
17152                    final String name = Debug.MemoryInfo.getOtherLabel(
17153                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
17154                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17155                                    dalvikSubitemSwapPss[j], j));
17156                }
17157            }
17158            catMems.add(dalvikItem);
17159            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17160            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17161                String label = Debug.MemoryInfo.getOtherLabel(j);
17162                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17163            }
17164
17165            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17166            for (int j=0; j<oomPss.length; j++) {
17167                if (oomPss[j] != 0) {
17168                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17169                            : DUMP_MEM_OOM_LABEL[j];
17170                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17171                            DUMP_MEM_OOM_ADJ[j]);
17172                    item.subitems = oomProcs[j];
17173                    oomMems.add(item);
17174                }
17175            }
17176
17177            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17178            if (!brief && !oomOnly && !isCompact) {
17179                pw.println();
17180                pw.println("Total PSS by process:");
17181                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17182                pw.println();
17183            }
17184            if (!isCompact) {
17185                pw.println("Total PSS by OOM adjustment:");
17186            }
17187            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17188            if (!brief && !oomOnly) {
17189                PrintWriter out = categoryPw != null ? categoryPw : pw;
17190                if (!isCompact) {
17191                    out.println();
17192                    out.println("Total PSS by category:");
17193                }
17194                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17195            }
17196            if (!isCompact) {
17197                pw.println();
17198            }
17199            MemInfoReader memInfo = new MemInfoReader();
17200            memInfo.readMemInfo();
17201            if (nativeProcTotalPss > 0) {
17202                synchronized (this) {
17203                    final long cachedKb = memInfo.getCachedSizeKb();
17204                    final long freeKb = memInfo.getFreeSizeKb();
17205                    final long zramKb = memInfo.getZramTotalSizeKb();
17206                    final long kernelKb = memInfo.getKernelUsedSizeKb();
17207                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17208                            kernelKb*1024, nativeProcTotalPss*1024);
17209                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17210                            nativeProcTotalPss);
17211                }
17212            }
17213            if (!brief) {
17214                if (!isCompact) {
17215                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17216                    pw.print(" (status ");
17217                    switch (mLastMemoryLevel) {
17218                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17219                            pw.println("normal)");
17220                            break;
17221                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17222                            pw.println("moderate)");
17223                            break;
17224                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
17225                            pw.println("low)");
17226                            break;
17227                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17228                            pw.println("critical)");
17229                            break;
17230                        default:
17231                            pw.print(mLastMemoryLevel);
17232                            pw.println(")");
17233                            break;
17234                    }
17235                    pw.print(" Free RAM: ");
17236                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17237                            + memInfo.getFreeSizeKb()));
17238                    pw.print(" (");
17239                    pw.print(stringifyKBSize(cachedPss));
17240                    pw.print(" cached pss + ");
17241                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17242                    pw.print(" cached kernel + ");
17243                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17244                    pw.println(" free)");
17245                } else {
17246                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17247                    pw.print(cachedPss + memInfo.getCachedSizeKb()
17248                            + memInfo.getFreeSizeKb()); pw.print(",");
17249                    pw.println(totalPss - cachedPss);
17250                }
17251            }
17252            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17253                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17254                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17255            if (!isCompact) {
17256                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17257                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17258                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17259                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17260                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17261            } else {
17262                pw.print("lostram,"); pw.println(lostRAM);
17263            }
17264            if (!brief) {
17265                if (memInfo.getZramTotalSizeKb() != 0) {
17266                    if (!isCompact) {
17267                        pw.print("     ZRAM: ");
17268                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17269                                pw.print(" physical used for ");
17270                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17271                                        - memInfo.getSwapFreeSizeKb()));
17272                                pw.print(" in swap (");
17273                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17274                                pw.println(" total swap)");
17275                    } else {
17276                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17277                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17278                                pw.println(memInfo.getSwapFreeSizeKb());
17279                    }
17280                }
17281                final long[] ksm = getKsmInfo();
17282                if (!isCompact) {
17283                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17284                            || ksm[KSM_VOLATILE] != 0) {
17285                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17286                                pw.print(" saved from shared ");
17287                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17288                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17289                                pw.print(" unshared; ");
17290                                pw.print(stringifyKBSize(
17291                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
17292                    }
17293                    pw.print("   Tuning: ");
17294                    pw.print(ActivityManager.staticGetMemoryClass());
17295                    pw.print(" (large ");
17296                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17297                    pw.print("), oom ");
17298                    pw.print(stringifySize(
17299                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17300                    pw.print(", restore limit ");
17301                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17302                    if (ActivityManager.isLowRamDeviceStatic()) {
17303                        pw.print(" (low-ram)");
17304                    }
17305                    if (ActivityManager.isHighEndGfx()) {
17306                        pw.print(" (high-end-gfx)");
17307                    }
17308                    pw.println();
17309                } else {
17310                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17311                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17312                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17313                    pw.print("tuning,");
17314                    pw.print(ActivityManager.staticGetMemoryClass());
17315                    pw.print(',');
17316                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17317                    pw.print(',');
17318                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17319                    if (ActivityManager.isLowRamDeviceStatic()) {
17320                        pw.print(",low-ram");
17321                    }
17322                    if (ActivityManager.isHighEndGfx()) {
17323                        pw.print(",high-end-gfx");
17324                    }
17325                    pw.println();
17326                }
17327            }
17328        }
17329    }
17330
17331    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17332            long memtrack, String name) {
17333        sb.append("  ");
17334        sb.append(ProcessList.makeOomAdjString(oomAdj));
17335        sb.append(' ');
17336        sb.append(ProcessList.makeProcStateString(procState));
17337        sb.append(' ');
17338        ProcessList.appendRamKb(sb, pss);
17339        sb.append(": ");
17340        sb.append(name);
17341        if (memtrack > 0) {
17342            sb.append(" (");
17343            sb.append(stringifyKBSize(memtrack));
17344            sb.append(" memtrack)");
17345        }
17346    }
17347
17348    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17349        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17350        sb.append(" (pid ");
17351        sb.append(mi.pid);
17352        sb.append(") ");
17353        sb.append(mi.adjType);
17354        sb.append('\n');
17355        if (mi.adjReason != null) {
17356            sb.append("                      ");
17357            sb.append(mi.adjReason);
17358            sb.append('\n');
17359        }
17360    }
17361
17362    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17363        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17364        for (int i=0, N=memInfos.size(); i<N; i++) {
17365            ProcessMemInfo mi = memInfos.get(i);
17366            infoMap.put(mi.pid, mi);
17367        }
17368        updateCpuStatsNow();
17369        long[] memtrackTmp = new long[1];
17370        final List<ProcessCpuTracker.Stats> stats;
17371        // Get a list of Stats that have vsize > 0
17372        synchronized (mProcessCpuTracker) {
17373            stats = mProcessCpuTracker.getStats((st) -> {
17374                return st.vsize > 0;
17375            });
17376        }
17377        final int statsCount = stats.size();
17378        for (int i = 0; i < statsCount; i++) {
17379            ProcessCpuTracker.Stats st = stats.get(i);
17380            long pss = Debug.getPss(st.pid, null, memtrackTmp);
17381            if (pss > 0) {
17382                if (infoMap.indexOfKey(st.pid) < 0) {
17383                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17384                            ProcessList.NATIVE_ADJ, -1, "native", null);
17385                    mi.pss = pss;
17386                    mi.memtrack = memtrackTmp[0];
17387                    memInfos.add(mi);
17388                }
17389            }
17390        }
17391
17392        long totalPss = 0;
17393        long totalMemtrack = 0;
17394        for (int i=0, N=memInfos.size(); i<N; i++) {
17395            ProcessMemInfo mi = memInfos.get(i);
17396            if (mi.pss == 0) {
17397                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17398                mi.memtrack = memtrackTmp[0];
17399            }
17400            totalPss += mi.pss;
17401            totalMemtrack += mi.memtrack;
17402        }
17403        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17404            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17405                if (lhs.oomAdj != rhs.oomAdj) {
17406                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17407                }
17408                if (lhs.pss != rhs.pss) {
17409                    return lhs.pss < rhs.pss ? 1 : -1;
17410                }
17411                return 0;
17412            }
17413        });
17414
17415        StringBuilder tag = new StringBuilder(128);
17416        StringBuilder stack = new StringBuilder(128);
17417        tag.append("Low on memory -- ");
17418        appendMemBucket(tag, totalPss, "total", false);
17419        appendMemBucket(stack, totalPss, "total", true);
17420
17421        StringBuilder fullNativeBuilder = new StringBuilder(1024);
17422        StringBuilder shortNativeBuilder = new StringBuilder(1024);
17423        StringBuilder fullJavaBuilder = new StringBuilder(1024);
17424
17425        boolean firstLine = true;
17426        int lastOomAdj = Integer.MIN_VALUE;
17427        long extraNativeRam = 0;
17428        long extraNativeMemtrack = 0;
17429        long cachedPss = 0;
17430        for (int i=0, N=memInfos.size(); i<N; i++) {
17431            ProcessMemInfo mi = memInfos.get(i);
17432
17433            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17434                cachedPss += mi.pss;
17435            }
17436
17437            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17438                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17439                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17440                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17441                if (lastOomAdj != mi.oomAdj) {
17442                    lastOomAdj = mi.oomAdj;
17443                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17444                        tag.append(" / ");
17445                    }
17446                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17447                        if (firstLine) {
17448                            stack.append(":");
17449                            firstLine = false;
17450                        }
17451                        stack.append("\n\t at ");
17452                    } else {
17453                        stack.append("$");
17454                    }
17455                } else {
17456                    tag.append(" ");
17457                    stack.append("$");
17458                }
17459                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17460                    appendMemBucket(tag, mi.pss, mi.name, false);
17461                }
17462                appendMemBucket(stack, mi.pss, mi.name, true);
17463                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17464                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17465                    stack.append("(");
17466                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17467                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17468                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17469                            stack.append(":");
17470                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17471                        }
17472                    }
17473                    stack.append(")");
17474                }
17475            }
17476
17477            appendMemInfo(fullNativeBuilder, mi);
17478            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17479                // The short form only has native processes that are >= 512K.
17480                if (mi.pss >= 512) {
17481                    appendMemInfo(shortNativeBuilder, mi);
17482                } else {
17483                    extraNativeRam += mi.pss;
17484                    extraNativeMemtrack += mi.memtrack;
17485                }
17486            } else {
17487                // Short form has all other details, but if we have collected RAM
17488                // from smaller native processes let's dump a summary of that.
17489                if (extraNativeRam > 0) {
17490                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17491                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17492                    shortNativeBuilder.append('\n');
17493                    extraNativeRam = 0;
17494                }
17495                appendMemInfo(fullJavaBuilder, mi);
17496            }
17497        }
17498
17499        fullJavaBuilder.append("           ");
17500        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17501        fullJavaBuilder.append(": TOTAL");
17502        if (totalMemtrack > 0) {
17503            fullJavaBuilder.append(" (");
17504            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17505            fullJavaBuilder.append(" memtrack)");
17506        } else {
17507        }
17508        fullJavaBuilder.append("\n");
17509
17510        MemInfoReader memInfo = new MemInfoReader();
17511        memInfo.readMemInfo();
17512        final long[] infos = memInfo.getRawInfo();
17513
17514        StringBuilder memInfoBuilder = new StringBuilder(1024);
17515        Debug.getMemInfo(infos);
17516        memInfoBuilder.append("  MemInfo: ");
17517        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17518        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17519        memInfoBuilder.append(stringifyKBSize(
17520                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17521        memInfoBuilder.append(stringifyKBSize(
17522                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17523        memInfoBuilder.append(stringifyKBSize(
17524                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17525        memInfoBuilder.append("           ");
17526        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17527        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17528        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17529        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17530        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17531            memInfoBuilder.append("  ZRAM: ");
17532            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17533            memInfoBuilder.append(" RAM, ");
17534            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17535            memInfoBuilder.append(" swap total, ");
17536            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17537            memInfoBuilder.append(" swap free\n");
17538        }
17539        final long[] ksm = getKsmInfo();
17540        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17541                || ksm[KSM_VOLATILE] != 0) {
17542            memInfoBuilder.append("  KSM: ");
17543            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17544            memInfoBuilder.append(" saved from shared ");
17545            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17546            memInfoBuilder.append("\n       ");
17547            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17548            memInfoBuilder.append(" unshared; ");
17549            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17550            memInfoBuilder.append(" volatile\n");
17551        }
17552        memInfoBuilder.append("  Free RAM: ");
17553        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17554                + memInfo.getFreeSizeKb()));
17555        memInfoBuilder.append("\n");
17556        memInfoBuilder.append("  Used RAM: ");
17557        memInfoBuilder.append(stringifyKBSize(
17558                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17559        memInfoBuilder.append("\n");
17560        memInfoBuilder.append("  Lost RAM: ");
17561        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17562                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17563                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17564        memInfoBuilder.append("\n");
17565        Slog.i(TAG, "Low on memory:");
17566        Slog.i(TAG, shortNativeBuilder.toString());
17567        Slog.i(TAG, fullJavaBuilder.toString());
17568        Slog.i(TAG, memInfoBuilder.toString());
17569
17570        StringBuilder dropBuilder = new StringBuilder(1024);
17571        /*
17572        StringWriter oomSw = new StringWriter();
17573        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17574        StringWriter catSw = new StringWriter();
17575        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17576        String[] emptyArgs = new String[] { };
17577        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17578        oomPw.flush();
17579        String oomString = oomSw.toString();
17580        */
17581        dropBuilder.append("Low on memory:");
17582        dropBuilder.append(stack);
17583        dropBuilder.append('\n');
17584        dropBuilder.append(fullNativeBuilder);
17585        dropBuilder.append(fullJavaBuilder);
17586        dropBuilder.append('\n');
17587        dropBuilder.append(memInfoBuilder);
17588        dropBuilder.append('\n');
17589        /*
17590        dropBuilder.append(oomString);
17591        dropBuilder.append('\n');
17592        */
17593        StringWriter catSw = new StringWriter();
17594        synchronized (ActivityManagerService.this) {
17595            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17596            String[] emptyArgs = new String[] { };
17597            catPw.println();
17598            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17599            catPw.println();
17600            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17601                    false, null).dumpLocked();
17602            catPw.println();
17603            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17604            catPw.flush();
17605        }
17606        dropBuilder.append(catSw.toString());
17607        addErrorToDropBox("lowmem", null, "system_server", null,
17608                null, tag.toString(), dropBuilder.toString(), null, null);
17609        //Slog.i(TAG, "Sent to dropbox:");
17610        //Slog.i(TAG, dropBuilder.toString());
17611        synchronized (ActivityManagerService.this) {
17612            long now = SystemClock.uptimeMillis();
17613            if (mLastMemUsageReportTime < now) {
17614                mLastMemUsageReportTime = now;
17615            }
17616        }
17617    }
17618
17619    /**
17620     * Searches array of arguments for the specified string
17621     * @param args array of argument strings
17622     * @param value value to search for
17623     * @return true if the value is contained in the array
17624     */
17625    private static boolean scanArgs(String[] args, String value) {
17626        if (args != null) {
17627            for (String arg : args) {
17628                if (value.equals(arg)) {
17629                    return true;
17630                }
17631            }
17632        }
17633        return false;
17634    }
17635
17636    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17637            ContentProviderRecord cpr, boolean always) {
17638        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17639
17640        if (!inLaunching || always) {
17641            synchronized (cpr) {
17642                cpr.launchingApp = null;
17643                cpr.notifyAll();
17644            }
17645            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17646            String names[] = cpr.info.authority.split(";");
17647            for (int j = 0; j < names.length; j++) {
17648                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17649            }
17650        }
17651
17652        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17653            ContentProviderConnection conn = cpr.connections.get(i);
17654            if (conn.waiting) {
17655                // If this connection is waiting for the provider, then we don't
17656                // need to mess with its process unless we are always removing
17657                // or for some reason the provider is not currently launching.
17658                if (inLaunching && !always) {
17659                    continue;
17660                }
17661            }
17662            ProcessRecord capp = conn.client;
17663            conn.dead = true;
17664            if (conn.stableCount > 0) {
17665                if (!capp.persistent && capp.thread != null
17666                        && capp.pid != 0
17667                        && capp.pid != MY_PID) {
17668                    capp.kill("depends on provider "
17669                            + cpr.name.flattenToShortString()
17670                            + " in dying proc " + (proc != null ? proc.processName : "??")
17671                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17672                }
17673            } else if (capp.thread != null && conn.provider.provider != null) {
17674                try {
17675                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17676                } catch (RemoteException e) {
17677                }
17678                // In the protocol here, we don't expect the client to correctly
17679                // clean up this connection, we'll just remove it.
17680                cpr.connections.remove(i);
17681                if (conn.client.conProviders.remove(conn)) {
17682                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17683                }
17684            }
17685        }
17686
17687        if (inLaunching && always) {
17688            mLaunchingProviders.remove(cpr);
17689        }
17690        return inLaunching;
17691    }
17692
17693    /**
17694     * Main code for cleaning up a process when it has gone away.  This is
17695     * called both as a result of the process dying, or directly when stopping
17696     * a process when running in single process mode.
17697     *
17698     * @return Returns true if the given process has been restarted, so the
17699     * app that was passed in must remain on the process lists.
17700     */
17701    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17702            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17703        if (index >= 0) {
17704            removeLruProcessLocked(app);
17705            ProcessList.remove(app.pid);
17706        }
17707
17708        mProcessesToGc.remove(app);
17709        mPendingPssProcesses.remove(app);
17710
17711        // Dismiss any open dialogs.
17712        if (app.crashDialog != null && !app.forceCrashReport) {
17713            app.crashDialog.dismiss();
17714            app.crashDialog = null;
17715        }
17716        if (app.anrDialog != null) {
17717            app.anrDialog.dismiss();
17718            app.anrDialog = null;
17719        }
17720        if (app.waitDialog != null) {
17721            app.waitDialog.dismiss();
17722            app.waitDialog = null;
17723        }
17724
17725        app.crashing = false;
17726        app.notResponding = false;
17727
17728        app.resetPackageList(mProcessStats);
17729        app.unlinkDeathRecipient();
17730        app.makeInactive(mProcessStats);
17731        app.waitingToKill = null;
17732        app.forcingToForeground = null;
17733        updateProcessForegroundLocked(app, false, false);
17734        app.foregroundActivities = false;
17735        app.hasShownUi = false;
17736        app.treatLikeActivity = false;
17737        app.hasAboveClient = false;
17738        app.hasClientActivities = false;
17739
17740        mServices.killServicesLocked(app, allowRestart);
17741
17742        boolean restart = false;
17743
17744        // Remove published content providers.
17745        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17746            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17747            final boolean always = app.bad || !allowRestart;
17748            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17749            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17750                // We left the provider in the launching list, need to
17751                // restart it.
17752                restart = true;
17753            }
17754
17755            cpr.provider = null;
17756            cpr.proc = null;
17757        }
17758        app.pubProviders.clear();
17759
17760        // Take care of any launching providers waiting for this process.
17761        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17762            restart = true;
17763        }
17764
17765        // Unregister from connected content providers.
17766        if (!app.conProviders.isEmpty()) {
17767            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17768                ContentProviderConnection conn = app.conProviders.get(i);
17769                conn.provider.connections.remove(conn);
17770                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17771                        conn.provider.name);
17772            }
17773            app.conProviders.clear();
17774        }
17775
17776        // At this point there may be remaining entries in mLaunchingProviders
17777        // where we were the only one waiting, so they are no longer of use.
17778        // Look for these and clean up if found.
17779        // XXX Commented out for now.  Trying to figure out a way to reproduce
17780        // the actual situation to identify what is actually going on.
17781        if (false) {
17782            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17783                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17784                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17785                    synchronized (cpr) {
17786                        cpr.launchingApp = null;
17787                        cpr.notifyAll();
17788                    }
17789                }
17790            }
17791        }
17792
17793        skipCurrentReceiverLocked(app);
17794
17795        // Unregister any receivers.
17796        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17797            removeReceiverLocked(app.receivers.valueAt(i));
17798        }
17799        app.receivers.clear();
17800
17801        // If the app is undergoing backup, tell the backup manager about it
17802        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17803            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17804                    + mBackupTarget.appInfo + " died during backup");
17805            mHandler.post(new Runnable() {
17806                @Override
17807                public void run(){
17808                    try {
17809                        IBackupManager bm = IBackupManager.Stub.asInterface(
17810                                ServiceManager.getService(Context.BACKUP_SERVICE));
17811                        bm.agentDisconnected(app.info.packageName);
17812                    } catch (RemoteException e) {
17813                        // can't happen; backup manager is local
17814                    }
17815                }
17816            });
17817        }
17818
17819        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17820            ProcessChangeItem item = mPendingProcessChanges.get(i);
17821            if (item.pid == app.pid) {
17822                mPendingProcessChanges.remove(i);
17823                mAvailProcessChanges.add(item);
17824            }
17825        }
17826        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17827                null).sendToTarget();
17828
17829        // If the caller is restarting this app, then leave it in its
17830        // current lists and let the caller take care of it.
17831        if (restarting) {
17832            return false;
17833        }
17834
17835        if (!app.persistent || app.isolated) {
17836            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17837                    "Removing non-persistent process during cleanup: " + app);
17838            if (!replacingPid) {
17839                removeProcessNameLocked(app.processName, app.uid, app);
17840            }
17841            if (mHeavyWeightProcess == app) {
17842                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17843                        mHeavyWeightProcess.userId, 0));
17844                mHeavyWeightProcess = null;
17845            }
17846        } else if (!app.removed) {
17847            // This app is persistent, so we need to keep its record around.
17848            // If it is not already on the pending app list, add it there
17849            // and start a new process for it.
17850            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17851                mPersistentStartingProcesses.add(app);
17852                restart = true;
17853            }
17854        }
17855        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17856                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17857        mProcessesOnHold.remove(app);
17858
17859        if (app == mHomeProcess) {
17860            mHomeProcess = null;
17861        }
17862        if (app == mPreviousProcess) {
17863            mPreviousProcess = null;
17864        }
17865
17866        if (restart && !app.isolated) {
17867            // We have components that still need to be running in the
17868            // process, so re-launch it.
17869            if (index < 0) {
17870                ProcessList.remove(app.pid);
17871            }
17872            addProcessNameLocked(app);
17873            startProcessLocked(app, "restart", app.processName);
17874            return true;
17875        } else if (app.pid > 0 && app.pid != MY_PID) {
17876            // Goodbye!
17877            boolean removed;
17878            synchronized (mPidsSelfLocked) {
17879                mPidsSelfLocked.remove(app.pid);
17880                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17881            }
17882            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17883            if (app.isolated) {
17884                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17885            }
17886            app.setPid(0);
17887        }
17888        return false;
17889    }
17890
17891    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17892        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17893            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17894            if (cpr.launchingApp == app) {
17895                return true;
17896            }
17897        }
17898        return false;
17899    }
17900
17901    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17902        // Look through the content providers we are waiting to have launched,
17903        // and if any run in this process then either schedule a restart of
17904        // the process or kill the client waiting for it if this process has
17905        // gone bad.
17906        boolean restart = false;
17907        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17908            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17909            if (cpr.launchingApp == app) {
17910                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17911                    restart = true;
17912                } else {
17913                    removeDyingProviderLocked(app, cpr, true);
17914                }
17915            }
17916        }
17917        return restart;
17918    }
17919
17920    // =========================================================
17921    // SERVICES
17922    // =========================================================
17923
17924    @Override
17925    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17926            int flags) {
17927        enforceNotIsolatedCaller("getServices");
17928
17929        final int callingUid = Binder.getCallingUid();
17930        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
17931            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
17932        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
17933            callingUid);
17934        synchronized (this) {
17935            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
17936                allowed, canInteractAcrossUsers);
17937        }
17938    }
17939
17940    @Override
17941    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17942        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17943        synchronized (this) {
17944            return mServices.getRunningServiceControlPanelLocked(name);
17945        }
17946    }
17947
17948    @Override
17949    public ComponentName startService(IApplicationThread caller, Intent service,
17950            String resolvedType, boolean requireForeground, String callingPackage, int userId)
17951            throws TransactionTooLargeException {
17952        enforceNotIsolatedCaller("startService");
17953        // Refuse possible leaked file descriptors
17954        if (service != null && service.hasFileDescriptors() == true) {
17955            throw new IllegalArgumentException("File descriptors passed in Intent");
17956        }
17957
17958        if (callingPackage == null) {
17959            throw new IllegalArgumentException("callingPackage cannot be null");
17960        }
17961
17962        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17963                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
17964        synchronized(this) {
17965            final int callingPid = Binder.getCallingPid();
17966            final int callingUid = Binder.getCallingUid();
17967            final long origId = Binder.clearCallingIdentity();
17968            ComponentName res;
17969            try {
17970                res = mServices.startServiceLocked(caller, service,
17971                        resolvedType, callingPid, callingUid,
17972                        requireForeground, callingPackage, userId);
17973            } finally {
17974                Binder.restoreCallingIdentity(origId);
17975            }
17976            return res;
17977        }
17978    }
17979
17980    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17981            boolean fgRequired, String callingPackage, int userId)
17982            throws TransactionTooLargeException {
17983        synchronized(this) {
17984            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17985                    "startServiceInPackage: " + service + " type=" + resolvedType);
17986            final long origId = Binder.clearCallingIdentity();
17987            ComponentName res;
17988            try {
17989                res = mServices.startServiceLocked(null, service,
17990                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
17991            } finally {
17992                Binder.restoreCallingIdentity(origId);
17993            }
17994            return res;
17995        }
17996    }
17997
17998    @Override
17999    public int stopService(IApplicationThread caller, Intent service,
18000            String resolvedType, int userId) {
18001        enforceNotIsolatedCaller("stopService");
18002        // Refuse possible leaked file descriptors
18003        if (service != null && service.hasFileDescriptors() == true) {
18004            throw new IllegalArgumentException("File descriptors passed in Intent");
18005        }
18006
18007        synchronized(this) {
18008            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18009        }
18010    }
18011
18012    @Override
18013    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18014        enforceNotIsolatedCaller("peekService");
18015        // Refuse possible leaked file descriptors
18016        if (service != null && service.hasFileDescriptors() == true) {
18017            throw new IllegalArgumentException("File descriptors passed in Intent");
18018        }
18019
18020        if (callingPackage == null) {
18021            throw new IllegalArgumentException("callingPackage cannot be null");
18022        }
18023
18024        synchronized(this) {
18025            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18026        }
18027    }
18028
18029    @Override
18030    public boolean stopServiceToken(ComponentName className, IBinder token,
18031            int startId) {
18032        synchronized(this) {
18033            return mServices.stopServiceTokenLocked(className, token, startId);
18034        }
18035    }
18036
18037    @Override
18038    public void setServiceForeground(ComponentName className, IBinder token,
18039            int id, Notification notification, int flags) {
18040        synchronized(this) {
18041            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18042        }
18043    }
18044
18045    @Override
18046    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18047            boolean requireFull, String name, String callerPackage) {
18048        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18049                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18050    }
18051
18052    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18053            String className, int flags) {
18054        boolean result = false;
18055        // For apps that don't have pre-defined UIDs, check for permission
18056        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18057            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18058                if (ActivityManager.checkUidPermission(
18059                        INTERACT_ACROSS_USERS,
18060                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18061                    ComponentName comp = new ComponentName(aInfo.packageName, className);
18062                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
18063                            + " requests FLAG_SINGLE_USER, but app does not hold "
18064                            + INTERACT_ACROSS_USERS;
18065                    Slog.w(TAG, msg);
18066                    throw new SecurityException(msg);
18067                }
18068                // Permission passed
18069                result = true;
18070            }
18071        } else if ("system".equals(componentProcessName)) {
18072            result = true;
18073        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18074            // Phone app and persistent apps are allowed to export singleuser providers.
18075            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18076                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18077        }
18078        if (DEBUG_MU) Slog.v(TAG_MU,
18079                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18080                + Integer.toHexString(flags) + ") = " + result);
18081        return result;
18082    }
18083
18084    /**
18085     * Checks to see if the caller is in the same app as the singleton
18086     * component, or the component is in a special app. It allows special apps
18087     * to export singleton components but prevents exporting singleton
18088     * components for regular apps.
18089     */
18090    boolean isValidSingletonCall(int callingUid, int componentUid) {
18091        int componentAppId = UserHandle.getAppId(componentUid);
18092        return UserHandle.isSameApp(callingUid, componentUid)
18093                || componentAppId == SYSTEM_UID
18094                || componentAppId == PHONE_UID
18095                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18096                        == PackageManager.PERMISSION_GRANTED;
18097    }
18098
18099    public int bindService(IApplicationThread caller, IBinder token, Intent service,
18100            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18101            int userId) throws TransactionTooLargeException {
18102        enforceNotIsolatedCaller("bindService");
18103
18104        // Refuse possible leaked file descriptors
18105        if (service != null && service.hasFileDescriptors() == true) {
18106            throw new IllegalArgumentException("File descriptors passed in Intent");
18107        }
18108
18109        if (callingPackage == null) {
18110            throw new IllegalArgumentException("callingPackage cannot be null");
18111        }
18112
18113        synchronized(this) {
18114            return mServices.bindServiceLocked(caller, token, service,
18115                    resolvedType, connection, flags, callingPackage, userId);
18116        }
18117    }
18118
18119    public boolean unbindService(IServiceConnection connection) {
18120        synchronized (this) {
18121            return mServices.unbindServiceLocked(connection);
18122        }
18123    }
18124
18125    public void publishService(IBinder token, Intent intent, IBinder service) {
18126        // Refuse possible leaked file descriptors
18127        if (intent != null && intent.hasFileDescriptors() == true) {
18128            throw new IllegalArgumentException("File descriptors passed in Intent");
18129        }
18130
18131        synchronized(this) {
18132            if (!(token instanceof ServiceRecord)) {
18133                throw new IllegalArgumentException("Invalid service token");
18134            }
18135            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18136        }
18137    }
18138
18139    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18140        // Refuse possible leaked file descriptors
18141        if (intent != null && intent.hasFileDescriptors() == true) {
18142            throw new IllegalArgumentException("File descriptors passed in Intent");
18143        }
18144
18145        synchronized(this) {
18146            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18147        }
18148    }
18149
18150    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18151        synchronized(this) {
18152            if (!(token instanceof ServiceRecord)) {
18153                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18154                throw new IllegalArgumentException("Invalid service token");
18155            }
18156            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18157        }
18158    }
18159
18160    // =========================================================
18161    // BACKUP AND RESTORE
18162    // =========================================================
18163
18164    // Cause the target app to be launched if necessary and its backup agent
18165    // instantiated.  The backup agent will invoke backupAgentCreated() on the
18166    // activity manager to announce its creation.
18167    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18168        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18169        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18170
18171        IPackageManager pm = AppGlobals.getPackageManager();
18172        ApplicationInfo app = null;
18173        try {
18174            app = pm.getApplicationInfo(packageName, 0, userId);
18175        } catch (RemoteException e) {
18176            // can't happen; package manager is process-local
18177        }
18178        if (app == null) {
18179            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18180            return false;
18181        }
18182
18183        synchronized(this) {
18184            // !!! TODO: currently no check here that we're already bound
18185            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18186            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18187            synchronized (stats) {
18188                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18189            }
18190
18191            // Backup agent is now in use, its package can't be stopped.
18192            try {
18193                AppGlobals.getPackageManager().setPackageStoppedState(
18194                        app.packageName, false, UserHandle.getUserId(app.uid));
18195            } catch (RemoteException e) {
18196            } catch (IllegalArgumentException e) {
18197                Slog.w(TAG, "Failed trying to unstop package "
18198                        + app.packageName + ": " + e);
18199            }
18200
18201            BackupRecord r = new BackupRecord(ss, app, backupMode);
18202            ComponentName hostingName =
18203                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18204                            ? new ComponentName(app.packageName, app.backupAgentName)
18205                            : new ComponentName("android", "FullBackupAgent");
18206            // startProcessLocked() returns existing proc's record if it's already running
18207            ProcessRecord proc = startProcessLocked(app.processName, app,
18208                    false, 0, "backup", hostingName, false, false, false);
18209            if (proc == null) {
18210                Slog.e(TAG, "Unable to start backup agent process " + r);
18211                return false;
18212            }
18213
18214            // If the app is a regular app (uid >= 10000) and not the system server or phone
18215            // process, etc, then mark it as being in full backup so that certain calls to the
18216            // process can be blocked. This is not reset to false anywhere because we kill the
18217            // process after the full backup is done and the ProcessRecord will vaporize anyway.
18218            if (UserHandle.isApp(app.uid) &&
18219                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18220                proc.inFullBackup = true;
18221            }
18222            r.app = proc;
18223            mBackupTarget = r;
18224            mBackupAppName = app.packageName;
18225
18226            // Try not to kill the process during backup
18227            updateOomAdjLocked(proc);
18228
18229            // If the process is already attached, schedule the creation of the backup agent now.
18230            // If it is not yet live, this will be done when it attaches to the framework.
18231            if (proc.thread != null) {
18232                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18233                try {
18234                    proc.thread.scheduleCreateBackupAgent(app,
18235                            compatibilityInfoForPackageLocked(app), backupMode);
18236                } catch (RemoteException e) {
18237                    // Will time out on the backup manager side
18238                }
18239            } else {
18240                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18241            }
18242            // Invariants: at this point, the target app process exists and the application
18243            // is either already running or in the process of coming up.  mBackupTarget and
18244            // mBackupAppName describe the app, so that when it binds back to the AM we
18245            // know that it's scheduled for a backup-agent operation.
18246        }
18247
18248        return true;
18249    }
18250
18251    @Override
18252    public void clearPendingBackup() {
18253        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18254        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18255
18256        synchronized (this) {
18257            mBackupTarget = null;
18258            mBackupAppName = null;
18259        }
18260    }
18261
18262    // A backup agent has just come up
18263    public void backupAgentCreated(String agentPackageName, IBinder agent) {
18264        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18265                + " = " + agent);
18266
18267        synchronized(this) {
18268            if (!agentPackageName.equals(mBackupAppName)) {
18269                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18270                return;
18271            }
18272        }
18273
18274        long oldIdent = Binder.clearCallingIdentity();
18275        try {
18276            IBackupManager bm = IBackupManager.Stub.asInterface(
18277                    ServiceManager.getService(Context.BACKUP_SERVICE));
18278            bm.agentConnected(agentPackageName, agent);
18279        } catch (RemoteException e) {
18280            // can't happen; the backup manager service is local
18281        } catch (Exception e) {
18282            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18283            e.printStackTrace();
18284        } finally {
18285            Binder.restoreCallingIdentity(oldIdent);
18286        }
18287    }
18288
18289    // done with this agent
18290    public void unbindBackupAgent(ApplicationInfo appInfo) {
18291        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18292        if (appInfo == null) {
18293            Slog.w(TAG, "unbind backup agent for null app");
18294            return;
18295        }
18296
18297        synchronized(this) {
18298            try {
18299                if (mBackupAppName == null) {
18300                    Slog.w(TAG, "Unbinding backup agent with no active backup");
18301                    return;
18302                }
18303
18304                if (!mBackupAppName.equals(appInfo.packageName)) {
18305                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18306                    return;
18307                }
18308
18309                // Not backing this app up any more; reset its OOM adjustment
18310                final ProcessRecord proc = mBackupTarget.app;
18311                updateOomAdjLocked(proc);
18312                proc.inFullBackup = false;
18313
18314                // If the app crashed during backup, 'thread' will be null here
18315                if (proc.thread != null) {
18316                    try {
18317                        proc.thread.scheduleDestroyBackupAgent(appInfo,
18318                                compatibilityInfoForPackageLocked(appInfo));
18319                    } catch (Exception e) {
18320                        Slog.e(TAG, "Exception when unbinding backup agent:");
18321                        e.printStackTrace();
18322                    }
18323                }
18324            } finally {
18325                mBackupTarget = null;
18326                mBackupAppName = null;
18327            }
18328        }
18329    }
18330    // =========================================================
18331    // BROADCASTS
18332    // =========================================================
18333
18334    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18335        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18336            return false;
18337        }
18338        // Easy case -- we have the app's ProcessRecord.
18339        if (record != null) {
18340            return record.info.isInstantApp();
18341        }
18342        // Otherwise check with PackageManager.
18343        if (callerPackage == null) {
18344            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18345            throw new IllegalArgumentException("Calling application did not provide package name");
18346        }
18347        mAppOpsService.checkPackage(uid, callerPackage);
18348        try {
18349            IPackageManager pm = AppGlobals.getPackageManager();
18350            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18351        } catch (RemoteException e) {
18352            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18353            return true;
18354        }
18355    }
18356
18357    boolean isPendingBroadcastProcessLocked(int pid) {
18358        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18359                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18360    }
18361
18362    void skipPendingBroadcastLocked(int pid) {
18363            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18364            for (BroadcastQueue queue : mBroadcastQueues) {
18365                queue.skipPendingBroadcastLocked(pid);
18366            }
18367    }
18368
18369    // The app just attached; send any pending broadcasts that it should receive
18370    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18371        boolean didSomething = false;
18372        for (BroadcastQueue queue : mBroadcastQueues) {
18373            didSomething |= queue.sendPendingBroadcastsLocked(app);
18374        }
18375        return didSomething;
18376    }
18377
18378    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18379            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18380            int flags) {
18381        enforceNotIsolatedCaller("registerReceiver");
18382        ArrayList<Intent> stickyIntents = null;
18383        ProcessRecord callerApp = null;
18384        final boolean visibleToInstantApps
18385                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18386        int callingUid;
18387        int callingPid;
18388        boolean instantApp;
18389        synchronized(this) {
18390            if (caller != null) {
18391                callerApp = getRecordForAppLocked(caller);
18392                if (callerApp == null) {
18393                    throw new SecurityException(
18394                            "Unable to find app for caller " + caller
18395                            + " (pid=" + Binder.getCallingPid()
18396                            + ") when registering receiver " + receiver);
18397                }
18398                if (callerApp.info.uid != SYSTEM_UID &&
18399                        !callerApp.pkgList.containsKey(callerPackage) &&
18400                        !"android".equals(callerPackage)) {
18401                    throw new SecurityException("Given caller package " + callerPackage
18402                            + " is not running in process " + callerApp);
18403                }
18404                callingUid = callerApp.info.uid;
18405                callingPid = callerApp.pid;
18406            } else {
18407                callerPackage = null;
18408                callingUid = Binder.getCallingUid();
18409                callingPid = Binder.getCallingPid();
18410            }
18411
18412            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18413            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18414                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18415
18416            Iterator<String> actions = filter.actionsIterator();
18417            if (actions == null) {
18418                ArrayList<String> noAction = new ArrayList<String>(1);
18419                noAction.add(null);
18420                actions = noAction.iterator();
18421            }
18422
18423            // Collect stickies of users
18424            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18425            while (actions.hasNext()) {
18426                String action = actions.next();
18427                for (int id : userIds) {
18428                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18429                    if (stickies != null) {
18430                        ArrayList<Intent> intents = stickies.get(action);
18431                        if (intents != null) {
18432                            if (stickyIntents == null) {
18433                                stickyIntents = new ArrayList<Intent>();
18434                            }
18435                            stickyIntents.addAll(intents);
18436                        }
18437                    }
18438                }
18439            }
18440        }
18441
18442        ArrayList<Intent> allSticky = null;
18443        if (stickyIntents != null) {
18444            final ContentResolver resolver = mContext.getContentResolver();
18445            // Look for any matching sticky broadcasts...
18446            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18447                Intent intent = stickyIntents.get(i);
18448                // Don't provided intents that aren't available to instant apps.
18449                if (instantApp &&
18450                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18451                    continue;
18452                }
18453                // If intent has scheme "content", it will need to acccess
18454                // provider that needs to lock mProviderMap in ActivityThread
18455                // and also it may need to wait application response, so we
18456                // cannot lock ActivityManagerService here.
18457                if (filter.match(resolver, intent, true, TAG) >= 0) {
18458                    if (allSticky == null) {
18459                        allSticky = new ArrayList<Intent>();
18460                    }
18461                    allSticky.add(intent);
18462                }
18463            }
18464        }
18465
18466        // The first sticky in the list is returned directly back to the client.
18467        Intent sticky = allSticky != null ? allSticky.get(0) : null;
18468        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18469        if (receiver == null) {
18470            return sticky;
18471        }
18472
18473        synchronized (this) {
18474            if (callerApp != null && (callerApp.thread == null
18475                    || callerApp.thread.asBinder() != caller.asBinder())) {
18476                // Original caller already died
18477                return null;
18478            }
18479            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18480            if (rl == null) {
18481                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18482                        userId, receiver);
18483                if (rl.app != null) {
18484                    rl.app.receivers.add(rl);
18485                } else {
18486                    try {
18487                        receiver.asBinder().linkToDeath(rl, 0);
18488                    } catch (RemoteException e) {
18489                        return sticky;
18490                    }
18491                    rl.linkedToDeath = true;
18492                }
18493                mRegisteredReceivers.put(receiver.asBinder(), rl);
18494            } else if (rl.uid != callingUid) {
18495                throw new IllegalArgumentException(
18496                        "Receiver requested to register for uid " + callingUid
18497                        + " was previously registered for uid " + rl.uid
18498                        + " callerPackage is " + callerPackage);
18499            } else if (rl.pid != callingPid) {
18500                throw new IllegalArgumentException(
18501                        "Receiver requested to register for pid " + callingPid
18502                        + " was previously registered for pid " + rl.pid
18503                        + " callerPackage is " + callerPackage);
18504            } else if (rl.userId != userId) {
18505                throw new IllegalArgumentException(
18506                        "Receiver requested to register for user " + userId
18507                        + " was previously registered for user " + rl.userId
18508                        + " callerPackage is " + callerPackage);
18509            }
18510            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18511                    permission, callingUid, userId, instantApp, visibleToInstantApps);
18512            rl.add(bf);
18513            if (!bf.debugCheck()) {
18514                Slog.w(TAG, "==> For Dynamic broadcast");
18515            }
18516            mReceiverResolver.addFilter(bf);
18517
18518            // Enqueue broadcasts for all existing stickies that match
18519            // this filter.
18520            if (allSticky != null) {
18521                ArrayList receivers = new ArrayList();
18522                receivers.add(bf);
18523
18524                final int stickyCount = allSticky.size();
18525                for (int i = 0; i < stickyCount; i++) {
18526                    Intent intent = allSticky.get(i);
18527                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18528                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18529                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18530                            null, 0, null, null, false, true, true, -1);
18531                    queue.enqueueParallelBroadcastLocked(r);
18532                    queue.scheduleBroadcastsLocked();
18533                }
18534            }
18535
18536            return sticky;
18537        }
18538    }
18539
18540    public void unregisterReceiver(IIntentReceiver receiver) {
18541        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18542
18543        final long origId = Binder.clearCallingIdentity();
18544        try {
18545            boolean doTrim = false;
18546
18547            synchronized(this) {
18548                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18549                if (rl != null) {
18550                    final BroadcastRecord r = rl.curBroadcast;
18551                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18552                        final boolean doNext = r.queue.finishReceiverLocked(
18553                                r, r.resultCode, r.resultData, r.resultExtras,
18554                                r.resultAbort, false);
18555                        if (doNext) {
18556                            doTrim = true;
18557                            r.queue.processNextBroadcast(false);
18558                        }
18559                    }
18560
18561                    if (rl.app != null) {
18562                        rl.app.receivers.remove(rl);
18563                    }
18564                    removeReceiverLocked(rl);
18565                    if (rl.linkedToDeath) {
18566                        rl.linkedToDeath = false;
18567                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18568                    }
18569                }
18570            }
18571
18572            // If we actually concluded any broadcasts, we might now be able
18573            // to trim the recipients' apps from our working set
18574            if (doTrim) {
18575                trimApplications();
18576                return;
18577            }
18578
18579        } finally {
18580            Binder.restoreCallingIdentity(origId);
18581        }
18582    }
18583
18584    void removeReceiverLocked(ReceiverList rl) {
18585        mRegisteredReceivers.remove(rl.receiver.asBinder());
18586        for (int i = rl.size() - 1; i >= 0; i--) {
18587            mReceiverResolver.removeFilter(rl.get(i));
18588        }
18589    }
18590
18591    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18592        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18593            ProcessRecord r = mLruProcesses.get(i);
18594            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18595                try {
18596                    r.thread.dispatchPackageBroadcast(cmd, packages);
18597                } catch (RemoteException ex) {
18598                }
18599            }
18600        }
18601    }
18602
18603    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18604            int callingUid, int[] users) {
18605        // TODO: come back and remove this assumption to triage all broadcasts
18606        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18607
18608        List<ResolveInfo> receivers = null;
18609        try {
18610            HashSet<ComponentName> singleUserReceivers = null;
18611            boolean scannedFirstReceivers = false;
18612            for (int user : users) {
18613                // Skip users that have Shell restrictions, with exception of always permitted
18614                // Shell broadcasts
18615                if (callingUid == SHELL_UID
18616                        && mUserController.hasUserRestriction(
18617                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18618                        && !isPermittedShellBroadcast(intent)) {
18619                    continue;
18620                }
18621                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18622                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18623                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18624                    // If this is not the system user, we need to check for
18625                    // any receivers that should be filtered out.
18626                    for (int i=0; i<newReceivers.size(); i++) {
18627                        ResolveInfo ri = newReceivers.get(i);
18628                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18629                            newReceivers.remove(i);
18630                            i--;
18631                        }
18632                    }
18633                }
18634                if (newReceivers != null && newReceivers.size() == 0) {
18635                    newReceivers = null;
18636                }
18637                if (receivers == null) {
18638                    receivers = newReceivers;
18639                } else if (newReceivers != null) {
18640                    // We need to concatenate the additional receivers
18641                    // found with what we have do far.  This would be easy,
18642                    // but we also need to de-dup any receivers that are
18643                    // singleUser.
18644                    if (!scannedFirstReceivers) {
18645                        // Collect any single user receivers we had already retrieved.
18646                        scannedFirstReceivers = true;
18647                        for (int i=0; i<receivers.size(); i++) {
18648                            ResolveInfo ri = receivers.get(i);
18649                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18650                                ComponentName cn = new ComponentName(
18651                                        ri.activityInfo.packageName, ri.activityInfo.name);
18652                                if (singleUserReceivers == null) {
18653                                    singleUserReceivers = new HashSet<ComponentName>();
18654                                }
18655                                singleUserReceivers.add(cn);
18656                            }
18657                        }
18658                    }
18659                    // Add the new results to the existing results, tracking
18660                    // and de-dupping single user receivers.
18661                    for (int i=0; i<newReceivers.size(); i++) {
18662                        ResolveInfo ri = newReceivers.get(i);
18663                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18664                            ComponentName cn = new ComponentName(
18665                                    ri.activityInfo.packageName, ri.activityInfo.name);
18666                            if (singleUserReceivers == null) {
18667                                singleUserReceivers = new HashSet<ComponentName>();
18668                            }
18669                            if (!singleUserReceivers.contains(cn)) {
18670                                singleUserReceivers.add(cn);
18671                                receivers.add(ri);
18672                            }
18673                        } else {
18674                            receivers.add(ri);
18675                        }
18676                    }
18677                }
18678            }
18679        } catch (RemoteException ex) {
18680            // pm is in same process, this will never happen.
18681        }
18682        return receivers;
18683    }
18684
18685    private boolean isPermittedShellBroadcast(Intent intent) {
18686        // remote bugreport should always be allowed to be taken
18687        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18688    }
18689
18690    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18691            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18692        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18693            // Don't yell about broadcasts sent via shell
18694            return;
18695        }
18696
18697        final String action = intent.getAction();
18698        if (isProtectedBroadcast
18699                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18700                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18701                || Intent.ACTION_MEDIA_BUTTON.equals(action)
18702                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18703                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18704                || Intent.ACTION_MASTER_CLEAR.equals(action)
18705                || Intent.ACTION_FACTORY_RESET.equals(action)
18706                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18707                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18708                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18709                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18710                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18711                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18712                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18713            // Broadcast is either protected, or it's a public action that
18714            // we've relaxed, so it's fine for system internals to send.
18715            return;
18716        }
18717
18718        // This broadcast may be a problem...  but there are often system components that
18719        // want to send an internal broadcast to themselves, which is annoying to have to
18720        // explicitly list each action as a protected broadcast, so we will check for that
18721        // one safe case and allow it: an explicit broadcast, only being received by something
18722        // that has protected itself.
18723        if (receivers != null && receivers.size() > 0
18724                && (intent.getPackage() != null || intent.getComponent() != null)) {
18725            boolean allProtected = true;
18726            for (int i = receivers.size()-1; i >= 0; i--) {
18727                Object target = receivers.get(i);
18728                if (target instanceof ResolveInfo) {
18729                    ResolveInfo ri = (ResolveInfo)target;
18730                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18731                        allProtected = false;
18732                        break;
18733                    }
18734                } else {
18735                    BroadcastFilter bf = (BroadcastFilter)target;
18736                    if (bf.requiredPermission == null) {
18737                        allProtected = false;
18738                        break;
18739                    }
18740                }
18741            }
18742            if (allProtected) {
18743                // All safe!
18744                return;
18745            }
18746        }
18747
18748        // The vast majority of broadcasts sent from system internals
18749        // should be protected to avoid security holes, so yell loudly
18750        // to ensure we examine these cases.
18751        if (callerApp != null) {
18752            Log.wtf(TAG, "Sending non-protected broadcast " + action
18753                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
18754                    new Throwable());
18755        } else {
18756            Log.wtf(TAG, "Sending non-protected broadcast " + action
18757                            + " from system uid " + UserHandle.formatUid(callingUid)
18758                            + " pkg " + callerPackage,
18759                    new Throwable());
18760        }
18761    }
18762
18763    final int broadcastIntentLocked(ProcessRecord callerApp,
18764            String callerPackage, Intent intent, String resolvedType,
18765            IIntentReceiver resultTo, int resultCode, String resultData,
18766            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
18767            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
18768        intent = new Intent(intent);
18769
18770        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
18771        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
18772        if (callerInstantApp) {
18773            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
18774        }
18775
18776        // By default broadcasts do not go to stopped apps.
18777        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
18778
18779        // If we have not finished booting, don't allow this to launch new processes.
18780        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
18781            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18782        }
18783
18784        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
18785                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
18786                + " ordered=" + ordered + " userid=" + userId);
18787        if ((resultTo != null) && !ordered) {
18788            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
18789        }
18790
18791        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18792                ALLOW_NON_FULL, "broadcast", callerPackage);
18793
18794        // Make sure that the user who is receiving this broadcast is running.
18795        // If not, we will just skip it. Make an exception for shutdown broadcasts
18796        // and upgrade steps.
18797
18798        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
18799            if ((callingUid != SYSTEM_UID
18800                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
18801                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
18802                Slog.w(TAG, "Skipping broadcast of " + intent
18803                        + ": user " + userId + " is stopped");
18804                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
18805            }
18806        }
18807
18808        BroadcastOptions brOptions = null;
18809        if (bOptions != null) {
18810            brOptions = new BroadcastOptions(bOptions);
18811            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
18812                // See if the caller is allowed to do this.  Note we are checking against
18813                // the actual real caller (not whoever provided the operation as say a
18814                // PendingIntent), because that who is actually supplied the arguments.
18815                if (checkComponentPermission(
18816                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
18817                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
18818                        != PackageManager.PERMISSION_GRANTED) {
18819                    String msg = "Permission Denial: " + intent.getAction()
18820                            + " broadcast from " + callerPackage + " (pid=" + callingPid
18821                            + ", uid=" + callingUid + ")"
18822                            + " requires "
18823                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
18824                    Slog.w(TAG, msg);
18825                    throw new SecurityException(msg);
18826                }
18827            }
18828        }
18829
18830        // Verify that protected broadcasts are only being sent by system code,
18831        // and that system code is only sending protected broadcasts.
18832        final String action = intent.getAction();
18833        final boolean isProtectedBroadcast;
18834        try {
18835            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18836        } catch (RemoteException e) {
18837            Slog.w(TAG, "Remote exception", e);
18838            return ActivityManager.BROADCAST_SUCCESS;
18839        }
18840
18841        final boolean isCallerSystem;
18842        switch (UserHandle.getAppId(callingUid)) {
18843            case ROOT_UID:
18844            case SYSTEM_UID:
18845            case PHONE_UID:
18846            case BLUETOOTH_UID:
18847            case NFC_UID:
18848                isCallerSystem = true;
18849                break;
18850            default:
18851                isCallerSystem = (callerApp != null) && callerApp.persistent;
18852                break;
18853        }
18854
18855        // First line security check before anything else: stop non-system apps from
18856        // sending protected broadcasts.
18857        if (!isCallerSystem) {
18858            if (isProtectedBroadcast) {
18859                String msg = "Permission Denial: not allowed to send broadcast "
18860                        + action + " from pid="
18861                        + callingPid + ", uid=" + callingUid;
18862                Slog.w(TAG, msg);
18863                throw new SecurityException(msg);
18864
18865            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18866                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18867                // Special case for compatibility: we don't want apps to send this,
18868                // but historically it has not been protected and apps may be using it
18869                // to poke their own app widget.  So, instead of making it protected,
18870                // just limit it to the caller.
18871                if (callerPackage == null) {
18872                    String msg = "Permission Denial: not allowed to send broadcast "
18873                            + action + " from unknown caller.";
18874                    Slog.w(TAG, msg);
18875                    throw new SecurityException(msg);
18876                } else if (intent.getComponent() != null) {
18877                    // They are good enough to send to an explicit component...  verify
18878                    // it is being sent to the calling app.
18879                    if (!intent.getComponent().getPackageName().equals(
18880                            callerPackage)) {
18881                        String msg = "Permission Denial: not allowed to send broadcast "
18882                                + action + " to "
18883                                + intent.getComponent().getPackageName() + " from "
18884                                + callerPackage;
18885                        Slog.w(TAG, msg);
18886                        throw new SecurityException(msg);
18887                    }
18888                } else {
18889                    // Limit broadcast to their own package.
18890                    intent.setPackage(callerPackage);
18891                }
18892            }
18893        }
18894
18895        if (action != null) {
18896            if (getBackgroundLaunchBroadcasts().contains(action)) {
18897                if (DEBUG_BACKGROUND_CHECK) {
18898                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
18899                }
18900                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
18901            }
18902
18903            switch (action) {
18904                case Intent.ACTION_UID_REMOVED:
18905                case Intent.ACTION_PACKAGE_REMOVED:
18906                case Intent.ACTION_PACKAGE_CHANGED:
18907                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18908                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18909                case Intent.ACTION_PACKAGES_SUSPENDED:
18910                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18911                    // Handle special intents: if this broadcast is from the package
18912                    // manager about a package being removed, we need to remove all of
18913                    // its activities from the history stack.
18914                    if (checkComponentPermission(
18915                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18916                            callingPid, callingUid, -1, true)
18917                            != PackageManager.PERMISSION_GRANTED) {
18918                        String msg = "Permission Denial: " + intent.getAction()
18919                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18920                                + ", uid=" + callingUid + ")"
18921                                + " requires "
18922                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18923                        Slog.w(TAG, msg);
18924                        throw new SecurityException(msg);
18925                    }
18926                    switch (action) {
18927                        case Intent.ACTION_UID_REMOVED:
18928                            final int uid = getUidFromIntent(intent);
18929                            if (uid >= 0) {
18930                                mBatteryStatsService.removeUid(uid);
18931                                mAppOpsService.uidRemoved(uid);
18932                            }
18933                            break;
18934                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18935                            // If resources are unavailable just force stop all those packages
18936                            // and flush the attribute cache as well.
18937                            String list[] =
18938                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18939                            if (list != null && list.length > 0) {
18940                                for (int i = 0; i < list.length; i++) {
18941                                    forceStopPackageLocked(list[i], -1, false, true, true,
18942                                            false, false, userId, "storage unmount");
18943                                }
18944                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18945                                sendPackageBroadcastLocked(
18946                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
18947                                        list, userId);
18948                            }
18949                            break;
18950                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18951                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18952                            break;
18953                        case Intent.ACTION_PACKAGE_REMOVED:
18954                        case Intent.ACTION_PACKAGE_CHANGED:
18955                            Uri data = intent.getData();
18956                            String ssp;
18957                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18958                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18959                                final boolean replacing =
18960                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18961                                final boolean killProcess =
18962                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18963                                final boolean fullUninstall = removed && !replacing;
18964                                if (removed) {
18965                                    if (killProcess) {
18966                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18967                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18968                                                false, true, true, false, fullUninstall, userId,
18969                                                removed ? "pkg removed" : "pkg changed");
18970                                    }
18971                                    final int cmd = killProcess
18972                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18973                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
18974                                    sendPackageBroadcastLocked(cmd,
18975                                            new String[] {ssp}, userId);
18976                                    if (fullUninstall) {
18977                                        mAppOpsService.packageRemoved(
18978                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18979
18980                                        // Remove all permissions granted from/to this package
18981                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18982
18983                                        removeTasksByPackageNameLocked(ssp, userId);
18984
18985                                        // Hide the "unsupported display" dialog if necessary.
18986                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18987                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18988                                            mUnsupportedDisplaySizeDialog.dismiss();
18989                                            mUnsupportedDisplaySizeDialog = null;
18990                                        }
18991                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18992                                        mBatteryStatsService.notePackageUninstalled(ssp);
18993                                    }
18994                                } else {
18995                                    if (killProcess) {
18996                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18997                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18998                                                userId, ProcessList.INVALID_ADJ,
18999                                                false, true, true, false, "change " + ssp);
19000                                    }
19001                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19002                                            intent.getStringArrayExtra(
19003                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19004                                }
19005                            }
19006                            break;
19007                        case Intent.ACTION_PACKAGES_SUSPENDED:
19008                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
19009                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19010                                    intent.getAction());
19011                            final String[] packageNames = intent.getStringArrayExtra(
19012                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
19013                            final int userHandle = intent.getIntExtra(
19014                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19015
19016                            synchronized(ActivityManagerService.this) {
19017                                mRecentTasks.onPackagesSuspendedChanged(
19018                                        packageNames, suspended, userHandle);
19019                            }
19020                            break;
19021                    }
19022                    break;
19023                case Intent.ACTION_PACKAGE_REPLACED:
19024                {
19025                    final Uri data = intent.getData();
19026                    final String ssp;
19027                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19028                        final ApplicationInfo aInfo =
19029                                getPackageManagerInternalLocked().getApplicationInfo(
19030                                        ssp,
19031                                        userId);
19032                        if (aInfo == null) {
19033                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19034                                    + " ssp=" + ssp + " data=" + data);
19035                            return ActivityManager.BROADCAST_SUCCESS;
19036                        }
19037                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19038                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19039                                new String[] {ssp}, userId);
19040                    }
19041                    break;
19042                }
19043                case Intent.ACTION_PACKAGE_ADDED:
19044                {
19045                    // Special case for adding a package: by default turn on compatibility mode.
19046                    Uri data = intent.getData();
19047                    String ssp;
19048                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19049                        final boolean replacing =
19050                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19051                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19052
19053                        try {
19054                            ApplicationInfo ai = AppGlobals.getPackageManager().
19055                                    getApplicationInfo(ssp, 0, 0);
19056                            mBatteryStatsService.notePackageInstalled(ssp,
19057                                    ai != null ? ai.versionCode : 0);
19058                        } catch (RemoteException e) {
19059                        }
19060                    }
19061                    break;
19062                }
19063                case Intent.ACTION_PACKAGE_DATA_CLEARED:
19064                {
19065                    Uri data = intent.getData();
19066                    String ssp;
19067                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19068                        // Hide the "unsupported display" dialog if necessary.
19069                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19070                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19071                            mUnsupportedDisplaySizeDialog.dismiss();
19072                            mUnsupportedDisplaySizeDialog = null;
19073                        }
19074                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
19075                    }
19076                    break;
19077                }
19078                case Intent.ACTION_TIMEZONE_CHANGED:
19079                    // If this is the time zone changed action, queue up a message that will reset
19080                    // the timezone of all currently running processes. This message will get
19081                    // queued up before the broadcast happens.
19082                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19083                    break;
19084                case Intent.ACTION_TIME_CHANGED:
19085                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19086                    // the tri-state value it may contain and "unknown".
19087                    // For convenience we re-use the Intent extra values.
19088                    final int NO_EXTRA_VALUE_FOUND = -1;
19089                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19090                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19091                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
19092                    // Only send a message if the time preference is available.
19093                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19094                        Message updateTimePreferenceMsg =
19095                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19096                                        timeFormatPreferenceMsgValue, 0);
19097                        mHandler.sendMessage(updateTimePreferenceMsg);
19098                    }
19099                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19100                    synchronized (stats) {
19101                        stats.noteCurrentTimeChangedLocked();
19102                    }
19103                    break;
19104                case Intent.ACTION_CLEAR_DNS_CACHE:
19105                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19106                    break;
19107                case Proxy.PROXY_CHANGE_ACTION:
19108                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19109                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19110                    break;
19111                case android.hardware.Camera.ACTION_NEW_PICTURE:
19112                case android.hardware.Camera.ACTION_NEW_VIDEO:
19113                    // In N we just turned these off; in O we are turing them back on partly,
19114                    // only for registered receivers.  This will still address the main problem
19115                    // (a spam of apps waking up when a picture is taken putting significant
19116                    // memory pressure on the system at a bad point), while still allowing apps
19117                    // that are already actively running to know about this happening.
19118                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19119                    break;
19120                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19121                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19122                    break;
19123            }
19124
19125            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19126                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19127                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19128                final int uid = getUidFromIntent(intent);
19129                if (uid != -1) {
19130                    final UidRecord uidRec = mActiveUids.get(uid);
19131                    if (uidRec != null) {
19132                        uidRec.updateHasInternetPermission();
19133                    }
19134                }
19135            }
19136        }
19137
19138        // Add to the sticky list if requested.
19139        if (sticky) {
19140            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19141                    callingPid, callingUid)
19142                    != PackageManager.PERMISSION_GRANTED) {
19143                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19144                        + callingPid + ", uid=" + callingUid
19145                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19146                Slog.w(TAG, msg);
19147                throw new SecurityException(msg);
19148            }
19149            if (requiredPermissions != null && requiredPermissions.length > 0) {
19150                Slog.w(TAG, "Can't broadcast sticky intent " + intent
19151                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
19152                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19153            }
19154            if (intent.getComponent() != null) {
19155                throw new SecurityException(
19156                        "Sticky broadcasts can't target a specific component");
19157            }
19158            // We use userId directly here, since the "all" target is maintained
19159            // as a separate set of sticky broadcasts.
19160            if (userId != UserHandle.USER_ALL) {
19161                // But first, if this is not a broadcast to all users, then
19162                // make sure it doesn't conflict with an existing broadcast to
19163                // all users.
19164                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19165                        UserHandle.USER_ALL);
19166                if (stickies != null) {
19167                    ArrayList<Intent> list = stickies.get(intent.getAction());
19168                    if (list != null) {
19169                        int N = list.size();
19170                        int i;
19171                        for (i=0; i<N; i++) {
19172                            if (intent.filterEquals(list.get(i))) {
19173                                throw new IllegalArgumentException(
19174                                        "Sticky broadcast " + intent + " for user "
19175                                        + userId + " conflicts with existing global broadcast");
19176                            }
19177                        }
19178                    }
19179                }
19180            }
19181            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19182            if (stickies == null) {
19183                stickies = new ArrayMap<>();
19184                mStickyBroadcasts.put(userId, stickies);
19185            }
19186            ArrayList<Intent> list = stickies.get(intent.getAction());
19187            if (list == null) {
19188                list = new ArrayList<>();
19189                stickies.put(intent.getAction(), list);
19190            }
19191            final int stickiesCount = list.size();
19192            int i;
19193            for (i = 0; i < stickiesCount; i++) {
19194                if (intent.filterEquals(list.get(i))) {
19195                    // This sticky already exists, replace it.
19196                    list.set(i, new Intent(intent));
19197                    break;
19198                }
19199            }
19200            if (i >= stickiesCount) {
19201                list.add(new Intent(intent));
19202            }
19203        }
19204
19205        int[] users;
19206        if (userId == UserHandle.USER_ALL) {
19207            // Caller wants broadcast to go to all started users.
19208            users = mUserController.getStartedUserArrayLocked();
19209        } else {
19210            // Caller wants broadcast to go to one specific user.
19211            users = new int[] {userId};
19212        }
19213
19214        // Figure out who all will receive this broadcast.
19215        List receivers = null;
19216        List<BroadcastFilter> registeredReceivers = null;
19217        // Need to resolve the intent to interested receivers...
19218        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19219                 == 0) {
19220            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19221        }
19222        if (intent.getComponent() == null) {
19223            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19224                // Query one target user at a time, excluding shell-restricted users
19225                for (int i = 0; i < users.length; i++) {
19226                    if (mUserController.hasUserRestriction(
19227                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19228                        continue;
19229                    }
19230                    List<BroadcastFilter> registeredReceiversForUser =
19231                            mReceiverResolver.queryIntent(intent,
19232                                    resolvedType, false /*defaultOnly*/, users[i]);
19233                    if (registeredReceivers == null) {
19234                        registeredReceivers = registeredReceiversForUser;
19235                    } else if (registeredReceiversForUser != null) {
19236                        registeredReceivers.addAll(registeredReceiversForUser);
19237                    }
19238                }
19239            } else {
19240                registeredReceivers = mReceiverResolver.queryIntent(intent,
19241                        resolvedType, false /*defaultOnly*/, userId);
19242            }
19243        }
19244
19245        final boolean replacePending =
19246                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19247
19248        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19249                + " replacePending=" + replacePending);
19250
19251        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19252        if (!ordered && NR > 0) {
19253            // If we are not serializing this broadcast, then send the
19254            // registered receivers separately so they don't wait for the
19255            // components to be launched.
19256            if (isCallerSystem) {
19257                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19258                        isProtectedBroadcast, registeredReceivers);
19259            }
19260            final BroadcastQueue queue = broadcastQueueForIntent(intent);
19261            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19262                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19263                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19264                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19265            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19266            final boolean replaced = replacePending
19267                    && (queue.replaceParallelBroadcastLocked(r) != null);
19268            // Note: We assume resultTo is null for non-ordered broadcasts.
19269            if (!replaced) {
19270                queue.enqueueParallelBroadcastLocked(r);
19271                queue.scheduleBroadcastsLocked();
19272            }
19273            registeredReceivers = null;
19274            NR = 0;
19275        }
19276
19277        // Merge into one list.
19278        int ir = 0;
19279        if (receivers != null) {
19280            // A special case for PACKAGE_ADDED: do not allow the package
19281            // being added to see this broadcast.  This prevents them from
19282            // using this as a back door to get run as soon as they are
19283            // installed.  Maybe in the future we want to have a special install
19284            // broadcast or such for apps, but we'd like to deliberately make
19285            // this decision.
19286            String skipPackages[] = null;
19287            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19288                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19289                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19290                Uri data = intent.getData();
19291                if (data != null) {
19292                    String pkgName = data.getSchemeSpecificPart();
19293                    if (pkgName != null) {
19294                        skipPackages = new String[] { pkgName };
19295                    }
19296                }
19297            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19298                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19299            }
19300            if (skipPackages != null && (skipPackages.length > 0)) {
19301                for (String skipPackage : skipPackages) {
19302                    if (skipPackage != null) {
19303                        int NT = receivers.size();
19304                        for (int it=0; it<NT; it++) {
19305                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
19306                            if (curt.activityInfo.packageName.equals(skipPackage)) {
19307                                receivers.remove(it);
19308                                it--;
19309                                NT--;
19310                            }
19311                        }
19312                    }
19313                }
19314            }
19315
19316            int NT = receivers != null ? receivers.size() : 0;
19317            int it = 0;
19318            ResolveInfo curt = null;
19319            BroadcastFilter curr = null;
19320            while (it < NT && ir < NR) {
19321                if (curt == null) {
19322                    curt = (ResolveInfo)receivers.get(it);
19323                }
19324                if (curr == null) {
19325                    curr = registeredReceivers.get(ir);
19326                }
19327                if (curr.getPriority() >= curt.priority) {
19328                    // Insert this broadcast record into the final list.
19329                    receivers.add(it, curr);
19330                    ir++;
19331                    curr = null;
19332                    it++;
19333                    NT++;
19334                } else {
19335                    // Skip to the next ResolveInfo in the final list.
19336                    it++;
19337                    curt = null;
19338                }
19339            }
19340        }
19341        while (ir < NR) {
19342            if (receivers == null) {
19343                receivers = new ArrayList();
19344            }
19345            receivers.add(registeredReceivers.get(ir));
19346            ir++;
19347        }
19348
19349        if (isCallerSystem) {
19350            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19351                    isProtectedBroadcast, receivers);
19352        }
19353
19354        if ((receivers != null && receivers.size() > 0)
19355                || resultTo != null) {
19356            BroadcastQueue queue = broadcastQueueForIntent(intent);
19357            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19358                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19359                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19360                    resultData, resultExtras, ordered, sticky, false, userId);
19361
19362            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19363                    + ": prev had " + queue.mOrderedBroadcasts.size());
19364            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19365                    "Enqueueing broadcast " + r.intent.getAction());
19366
19367            final BroadcastRecord oldRecord =
19368                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19369            if (oldRecord != null) {
19370                // Replaced, fire the result-to receiver.
19371                if (oldRecord.resultTo != null) {
19372                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19373                    try {
19374                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19375                                oldRecord.intent,
19376                                Activity.RESULT_CANCELED, null, null,
19377                                false, false, oldRecord.userId);
19378                    } catch (RemoteException e) {
19379                        Slog.w(TAG, "Failure ["
19380                                + queue.mQueueName + "] sending broadcast result of "
19381                                + intent, e);
19382
19383                    }
19384                }
19385            } else {
19386                queue.enqueueOrderedBroadcastLocked(r);
19387                queue.scheduleBroadcastsLocked();
19388            }
19389        } else {
19390            // There was nobody interested in the broadcast, but we still want to record
19391            // that it happened.
19392            if (intent.getComponent() == null && intent.getPackage() == null
19393                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19394                // This was an implicit broadcast... let's record it for posterity.
19395                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19396            }
19397        }
19398
19399        return ActivityManager.BROADCAST_SUCCESS;
19400    }
19401
19402    /**
19403     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19404     */
19405    private int getUidFromIntent(Intent intent) {
19406        if (intent == null) {
19407            return -1;
19408        }
19409        final Bundle intentExtras = intent.getExtras();
19410        return intent.hasExtra(Intent.EXTRA_UID)
19411                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19412    }
19413
19414    final void rotateBroadcastStatsIfNeededLocked() {
19415        final long now = SystemClock.elapsedRealtime();
19416        if (mCurBroadcastStats == null ||
19417                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19418            mLastBroadcastStats = mCurBroadcastStats;
19419            if (mLastBroadcastStats != null) {
19420                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19421                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19422            }
19423            mCurBroadcastStats = new BroadcastStats();
19424        }
19425    }
19426
19427    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19428            int skipCount, long dispatchTime) {
19429        rotateBroadcastStatsIfNeededLocked();
19430        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19431    }
19432
19433    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19434        rotateBroadcastStatsIfNeededLocked();
19435        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19436    }
19437
19438    final Intent verifyBroadcastLocked(Intent intent) {
19439        // Refuse possible leaked file descriptors
19440        if (intent != null && intent.hasFileDescriptors() == true) {
19441            throw new IllegalArgumentException("File descriptors passed in Intent");
19442        }
19443
19444        int flags = intent.getFlags();
19445
19446        if (!mProcessesReady) {
19447            // if the caller really truly claims to know what they're doing, go
19448            // ahead and allow the broadcast without launching any receivers
19449            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19450                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19451            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19452                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19453                        + " before boot completion");
19454                throw new IllegalStateException("Cannot broadcast before boot completed");
19455            }
19456        }
19457
19458        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19459            throw new IllegalArgumentException(
19460                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19461        }
19462
19463        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19464            switch (Binder.getCallingUid()) {
19465                case ROOT_UID:
19466                case SHELL_UID:
19467                    break;
19468                default:
19469                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19470                            + Binder.getCallingUid());
19471                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19472                    break;
19473            }
19474        }
19475
19476        return intent;
19477    }
19478
19479    public final int broadcastIntent(IApplicationThread caller,
19480            Intent intent, String resolvedType, IIntentReceiver resultTo,
19481            int resultCode, String resultData, Bundle resultExtras,
19482            String[] requiredPermissions, int appOp, Bundle bOptions,
19483            boolean serialized, boolean sticky, int userId) {
19484        enforceNotIsolatedCaller("broadcastIntent");
19485        synchronized(this) {
19486            intent = verifyBroadcastLocked(intent);
19487
19488            final ProcessRecord callerApp = getRecordForAppLocked(caller);
19489            final int callingPid = Binder.getCallingPid();
19490            final int callingUid = Binder.getCallingUid();
19491            final long origId = Binder.clearCallingIdentity();
19492            int res = broadcastIntentLocked(callerApp,
19493                    callerApp != null ? callerApp.info.packageName : null,
19494                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19495                    requiredPermissions, appOp, bOptions, serialized, sticky,
19496                    callingPid, callingUid, userId);
19497            Binder.restoreCallingIdentity(origId);
19498            return res;
19499        }
19500    }
19501
19502
19503    int broadcastIntentInPackage(String packageName, int uid,
19504            Intent intent, String resolvedType, IIntentReceiver resultTo,
19505            int resultCode, String resultData, Bundle resultExtras,
19506            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19507            int userId) {
19508        synchronized(this) {
19509            intent = verifyBroadcastLocked(intent);
19510
19511            final long origId = Binder.clearCallingIdentity();
19512            String[] requiredPermissions = requiredPermission == null ? null
19513                    : new String[] {requiredPermission};
19514            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19515                    resultTo, resultCode, resultData, resultExtras,
19516                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19517                    sticky, -1, uid, userId);
19518            Binder.restoreCallingIdentity(origId);
19519            return res;
19520        }
19521    }
19522
19523    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19524        // Refuse possible leaked file descriptors
19525        if (intent != null && intent.hasFileDescriptors() == true) {
19526            throw new IllegalArgumentException("File descriptors passed in Intent");
19527        }
19528
19529        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19530                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19531
19532        synchronized(this) {
19533            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19534                    != PackageManager.PERMISSION_GRANTED) {
19535                String msg = "Permission Denial: unbroadcastIntent() from pid="
19536                        + Binder.getCallingPid()
19537                        + ", uid=" + Binder.getCallingUid()
19538                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19539                Slog.w(TAG, msg);
19540                throw new SecurityException(msg);
19541            }
19542            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19543            if (stickies != null) {
19544                ArrayList<Intent> list = stickies.get(intent.getAction());
19545                if (list != null) {
19546                    int N = list.size();
19547                    int i;
19548                    for (i=0; i<N; i++) {
19549                        if (intent.filterEquals(list.get(i))) {
19550                            list.remove(i);
19551                            break;
19552                        }
19553                    }
19554                    if (list.size() <= 0) {
19555                        stickies.remove(intent.getAction());
19556                    }
19557                }
19558                if (stickies.size() <= 0) {
19559                    mStickyBroadcasts.remove(userId);
19560                }
19561            }
19562        }
19563    }
19564
19565    void backgroundServicesFinishedLocked(int userId) {
19566        for (BroadcastQueue queue : mBroadcastQueues) {
19567            queue.backgroundServicesFinishedLocked(userId);
19568        }
19569    }
19570
19571    public void finishReceiver(IBinder who, int resultCode, String resultData,
19572            Bundle resultExtras, boolean resultAbort, int flags) {
19573        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19574
19575        // Refuse possible leaked file descriptors
19576        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19577            throw new IllegalArgumentException("File descriptors passed in Bundle");
19578        }
19579
19580        final long origId = Binder.clearCallingIdentity();
19581        try {
19582            boolean doNext = false;
19583            BroadcastRecord r;
19584
19585            synchronized(this) {
19586                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19587                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19588                r = queue.getMatchingOrderedReceiver(who);
19589                if (r != null) {
19590                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19591                        resultData, resultExtras, resultAbort, true);
19592                }
19593            }
19594
19595            if (doNext) {
19596                r.queue.processNextBroadcast(false);
19597            }
19598            trimApplications();
19599        } finally {
19600            Binder.restoreCallingIdentity(origId);
19601        }
19602    }
19603
19604    // =========================================================
19605    // INSTRUMENTATION
19606    // =========================================================
19607
19608    public boolean startInstrumentation(ComponentName className,
19609            String profileFile, int flags, Bundle arguments,
19610            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19611            int userId, String abiOverride) {
19612        enforceNotIsolatedCaller("startInstrumentation");
19613        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19614                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19615        // Refuse possible leaked file descriptors
19616        if (arguments != null && arguments.hasFileDescriptors()) {
19617            throw new IllegalArgumentException("File descriptors passed in Bundle");
19618        }
19619
19620        synchronized(this) {
19621            InstrumentationInfo ii = null;
19622            ApplicationInfo ai = null;
19623            try {
19624                ii = mContext.getPackageManager().getInstrumentationInfo(
19625                    className, STOCK_PM_FLAGS);
19626                ai = AppGlobals.getPackageManager().getApplicationInfo(
19627                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19628            } catch (PackageManager.NameNotFoundException e) {
19629            } catch (RemoteException e) {
19630            }
19631            if (ii == null) {
19632                reportStartInstrumentationFailureLocked(watcher, className,
19633                        "Unable to find instrumentation info for: " + className);
19634                return false;
19635            }
19636            if (ai == null) {
19637                reportStartInstrumentationFailureLocked(watcher, className,
19638                        "Unable to find instrumentation target package: " + ii.targetPackage);
19639                return false;
19640            }
19641            if (!ai.hasCode()) {
19642                reportStartInstrumentationFailureLocked(watcher, className,
19643                        "Instrumentation target has no code: " + ii.targetPackage);
19644                return false;
19645            }
19646
19647            int match = mContext.getPackageManager().checkSignatures(
19648                    ii.targetPackage, ii.packageName);
19649            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19650                String msg = "Permission Denial: starting instrumentation "
19651                        + className + " from pid="
19652                        + Binder.getCallingPid()
19653                        + ", uid=" + Binder.getCallingPid()
19654                        + " not allowed because package " + ii.packageName
19655                        + " does not have a signature matching the target "
19656                        + ii.targetPackage;
19657                reportStartInstrumentationFailureLocked(watcher, className, msg);
19658                throw new SecurityException(msg);
19659            }
19660
19661            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19662            activeInstr.mClass = className;
19663            String defProcess = ai.processName;;
19664            if (ii.targetProcess == null) {
19665                activeInstr.mTargetProcesses = new String[]{ai.processName};
19666            } else if (ii.targetProcess.equals("*")) {
19667                activeInstr.mTargetProcesses = new String[0];
19668            } else {
19669                activeInstr.mTargetProcesses = ii.targetProcess.split(",");
19670                defProcess = activeInstr.mTargetProcesses[0];
19671            }
19672            activeInstr.mTargetInfo = ai;
19673            activeInstr.mProfileFile = profileFile;
19674            activeInstr.mArguments = arguments;
19675            activeInstr.mWatcher = watcher;
19676            activeInstr.mUiAutomationConnection = uiAutomationConnection;
19677            activeInstr.mResultClass = className;
19678
19679            final long origId = Binder.clearCallingIdentity();
19680            // Instrumentation can kill and relaunch even persistent processes
19681            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19682                    "start instr");
19683            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19684            app.instr = activeInstr;
19685            activeInstr.mFinished = false;
19686            activeInstr.mRunningProcesses.add(app);
19687            if (!mActiveInstrumentation.contains(activeInstr)) {
19688                mActiveInstrumentation.add(activeInstr);
19689            }
19690            Binder.restoreCallingIdentity(origId);
19691        }
19692
19693        return true;
19694    }
19695
19696    /**
19697     * Report errors that occur while attempting to start Instrumentation.  Always writes the
19698     * error to the logs, but if somebody is watching, send the report there too.  This enables
19699     * the "am" command to report errors with more information.
19700     *
19701     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19702     * @param cn The component name of the instrumentation.
19703     * @param report The error report.
19704     */
19705    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19706            ComponentName cn, String report) {
19707        Slog.w(TAG, report);
19708        if (watcher != null) {
19709            Bundle results = new Bundle();
19710            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19711            results.putString("Error", report);
19712            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19713        }
19714    }
19715
19716    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19717        if (app.instr == null) {
19718            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19719            return;
19720        }
19721
19722        if (!app.instr.mFinished && results != null) {
19723            if (app.instr.mCurResults == null) {
19724                app.instr.mCurResults = new Bundle(results);
19725            } else {
19726                app.instr.mCurResults.putAll(results);
19727            }
19728        }
19729    }
19730
19731    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
19732        int userId = UserHandle.getCallingUserId();
19733        // Refuse possible leaked file descriptors
19734        if (results != null && results.hasFileDescriptors()) {
19735            throw new IllegalArgumentException("File descriptors passed in Intent");
19736        }
19737
19738        synchronized(this) {
19739            ProcessRecord app = getRecordForAppLocked(target);
19740            if (app == null) {
19741                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
19742                return;
19743            }
19744            final long origId = Binder.clearCallingIdentity();
19745            addInstrumentationResultsLocked(app, results);
19746            Binder.restoreCallingIdentity(origId);
19747        }
19748    }
19749
19750    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
19751        if (app.instr == null) {
19752            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19753            return;
19754        }
19755
19756        if (!app.instr.mFinished) {
19757            if (app.instr.mWatcher != null) {
19758                Bundle finalResults = app.instr.mCurResults;
19759                if (finalResults != null) {
19760                    if (app.instr.mCurResults != null && results != null) {
19761                        finalResults.putAll(results);
19762                    }
19763                } else {
19764                    finalResults = results;
19765                }
19766                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
19767                        app.instr.mClass, resultCode, finalResults);
19768            }
19769
19770            // Can't call out of the system process with a lock held, so post a message.
19771            if (app.instr.mUiAutomationConnection != null) {
19772                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
19773                        app.instr.mUiAutomationConnection).sendToTarget();
19774            }
19775            app.instr.mFinished = true;
19776        }
19777
19778        app.instr.removeProcess(app);
19779        app.instr = null;
19780
19781        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
19782                "finished inst");
19783    }
19784
19785    public void finishInstrumentation(IApplicationThread target,
19786            int resultCode, Bundle results) {
19787        int userId = UserHandle.getCallingUserId();
19788        // Refuse possible leaked file descriptors
19789        if (results != null && results.hasFileDescriptors()) {
19790            throw new IllegalArgumentException("File descriptors passed in Intent");
19791        }
19792
19793        synchronized(this) {
19794            ProcessRecord app = getRecordForAppLocked(target);
19795            if (app == null) {
19796                Slog.w(TAG, "finishInstrumentation: no app for " + target);
19797                return;
19798            }
19799            final long origId = Binder.clearCallingIdentity();
19800            finishInstrumentationLocked(app, resultCode, results);
19801            Binder.restoreCallingIdentity(origId);
19802        }
19803    }
19804
19805    // =========================================================
19806    // CONFIGURATION
19807    // =========================================================
19808
19809    public ConfigurationInfo getDeviceConfigurationInfo() {
19810        ConfigurationInfo config = new ConfigurationInfo();
19811        synchronized (this) {
19812            final Configuration globalConfig = getGlobalConfiguration();
19813            config.reqTouchScreen = globalConfig.touchscreen;
19814            config.reqKeyboardType = globalConfig.keyboard;
19815            config.reqNavigation = globalConfig.navigation;
19816            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
19817                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
19818                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
19819            }
19820            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
19821                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
19822                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
19823            }
19824            config.reqGlEsVersion = GL_ES_VERSION;
19825        }
19826        return config;
19827    }
19828
19829    ActivityStack getFocusedStack() {
19830        return mStackSupervisor.getFocusedStack();
19831    }
19832
19833    @Override
19834    public int getFocusedStackId() throws RemoteException {
19835        ActivityStack focusedStack = getFocusedStack();
19836        if (focusedStack != null) {
19837            return focusedStack.getStackId();
19838        }
19839        return -1;
19840    }
19841
19842    public Configuration getConfiguration() {
19843        Configuration ci;
19844        synchronized(this) {
19845            ci = new Configuration(getGlobalConfiguration());
19846            ci.userSetLocale = false;
19847        }
19848        return ci;
19849    }
19850
19851    @Override
19852    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
19853        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
19854        synchronized (this) {
19855            mSuppressResizeConfigChanges = suppress;
19856        }
19857    }
19858
19859    /**
19860     * NOTE: For the pinned stack, this method is only called after the bounds animation has
19861     *       animated the stack to the fullscreen.
19862     */
19863    @Override
19864    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
19865        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
19866        if (StackId.isHomeOrRecentsStack(fromStackId)) {
19867            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
19868        }
19869        synchronized (this) {
19870            final long origId = Binder.clearCallingIdentity();
19871            try {
19872                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
19873            } finally {
19874                Binder.restoreCallingIdentity(origId);
19875            }
19876        }
19877    }
19878
19879    @Override
19880    public void updatePersistentConfiguration(Configuration values) {
19881        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
19882        enforceWriteSettingsPermission("updatePersistentConfiguration()");
19883        if (values == null) {
19884            throw new NullPointerException("Configuration must not be null");
19885        }
19886
19887        int userId = UserHandle.getCallingUserId();
19888
19889        synchronized(this) {
19890            updatePersistentConfigurationLocked(values, userId);
19891        }
19892    }
19893
19894    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
19895        final long origId = Binder.clearCallingIdentity();
19896        try {
19897            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
19898        } finally {
19899            Binder.restoreCallingIdentity(origId);
19900        }
19901    }
19902
19903    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
19904        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
19905                FONT_SCALE, 1.0f, userId);
19906
19907        synchronized (this) {
19908            if (getGlobalConfiguration().fontScale == scaleFactor) {
19909                return;
19910            }
19911
19912            final Configuration configuration
19913                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19914            configuration.fontScale = scaleFactor;
19915            updatePersistentConfigurationLocked(configuration, userId);
19916        }
19917    }
19918
19919    private void enforceWriteSettingsPermission(String func) {
19920        int uid = Binder.getCallingUid();
19921        if (uid == ROOT_UID) {
19922            return;
19923        }
19924
19925        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
19926                Settings.getPackageNameForUid(mContext, uid), false)) {
19927            return;
19928        }
19929
19930        String msg = "Permission Denial: " + func + " from pid="
19931                + Binder.getCallingPid()
19932                + ", uid=" + uid
19933                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
19934        Slog.w(TAG, msg);
19935        throw new SecurityException(msg);
19936    }
19937
19938    @Override
19939    public boolean updateConfiguration(Configuration values) {
19940        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
19941
19942        synchronized(this) {
19943            if (values == null && mWindowManager != null) {
19944                // sentinel: fetch the current configuration from the window manager
19945                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19946            }
19947
19948            if (mWindowManager != null) {
19949                // Update OOM levels based on display size.
19950                mProcessList.applyDisplaySize(mWindowManager);
19951            }
19952
19953            final long origId = Binder.clearCallingIdentity();
19954            try {
19955                if (values != null) {
19956                    Settings.System.clearConfiguration(values);
19957                }
19958                updateConfigurationLocked(values, null, false, false /* persistent */,
19959                        UserHandle.USER_NULL, false /* deferResume */,
19960                        mTmpUpdateConfigurationResult);
19961                return mTmpUpdateConfigurationResult.changes != 0;
19962            } finally {
19963                Binder.restoreCallingIdentity(origId);
19964            }
19965        }
19966    }
19967
19968    void updateUserConfigurationLocked() {
19969        final Configuration configuration = new Configuration(getGlobalConfiguration());
19970        final int currentUserId = mUserController.getCurrentUserIdLocked();
19971        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
19972                currentUserId, Settings.System.canWrite(mContext));
19973        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
19974                false /* persistent */, currentUserId, false /* deferResume */);
19975    }
19976
19977    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19978            boolean initLocale) {
19979        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19980    }
19981
19982    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19983            boolean initLocale, boolean deferResume) {
19984        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19985        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19986                UserHandle.USER_NULL, deferResume);
19987    }
19988
19989    // To cache the list of supported system locales
19990    private String[] mSupportedSystemLocales = null;
19991
19992    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19993            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19994        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
19995                deferResume, null /* result */);
19996    }
19997
19998    /**
19999     * Do either or both things: (1) change the current configuration, and (2)
20000     * make sure the given activity is running with the (now) current
20001     * configuration.  Returns true if the activity has been left running, or
20002     * false if <var>starting</var> is being destroyed to match the new
20003     * configuration.
20004     *
20005     * @param userId is only used when persistent parameter is set to true to persist configuration
20006     *               for that particular user
20007     */
20008    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20009            boolean initLocale, boolean persistent, int userId, boolean deferResume,
20010            UpdateConfigurationResult result) {
20011        int changes = 0;
20012        boolean kept = true;
20013
20014        if (mWindowManager != null) {
20015            mWindowManager.deferSurfaceLayout();
20016        }
20017        try {
20018            if (values != null) {
20019                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20020                        deferResume);
20021            }
20022
20023            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20024        } finally {
20025            if (mWindowManager != null) {
20026                mWindowManager.continueSurfaceLayout();
20027            }
20028        }
20029
20030        if (result != null) {
20031            result.changes = changes;
20032            result.activityRelaunched = !kept;
20033        }
20034        return kept;
20035    }
20036
20037    /** Update default (global) configuration and notify listeners about changes. */
20038    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20039            boolean persistent, int userId, boolean deferResume) {
20040        mTempConfig.setTo(getGlobalConfiguration());
20041        final int changes = mTempConfig.updateFrom(values);
20042        if (changes == 0) {
20043            return 0;
20044        }
20045
20046        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20047                "Updating global configuration to: " + values);
20048
20049        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20050
20051        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20052            final LocaleList locales = values.getLocales();
20053            int bestLocaleIndex = 0;
20054            if (locales.size() > 1) {
20055                if (mSupportedSystemLocales == null) {
20056                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20057                }
20058                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20059            }
20060            SystemProperties.set("persist.sys.locale",
20061                    locales.get(bestLocaleIndex).toLanguageTag());
20062            LocaleList.setDefault(locales, bestLocaleIndex);
20063            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20064                    locales.get(bestLocaleIndex)));
20065        }
20066
20067        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20068        mTempConfig.seq = mConfigurationSeq;
20069
20070        // Update stored global config and notify everyone about the change.
20071        mStackSupervisor.onConfigurationChanged(mTempConfig);
20072
20073        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20074        // TODO(multi-display): Update UsageEvents#Event to include displayId.
20075        mUsageStatsService.reportConfigurationChange(mTempConfig,
20076                mUserController.getCurrentUserIdLocked());
20077
20078        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20079        mShowDialogs = shouldShowDialogs(mTempConfig);
20080
20081        AttributeCache ac = AttributeCache.instance();
20082        if (ac != null) {
20083            ac.updateConfiguration(mTempConfig);
20084        }
20085
20086        // Make sure all resources in our process are updated right now, so that anyone who is going
20087        // to retrieve resource values after we return will be sure to get the new ones. This is
20088        // especially important during boot, where the first config change needs to guarantee all
20089        // resources have that config before following boot code is executed.
20090        mSystemThread.applyConfigurationToResources(mTempConfig);
20091
20092        // We need another copy of global config because we're scheduling some calls instead of
20093        // running them in place. We need to be sure that object we send will be handled unchanged.
20094        final Configuration configCopy = new Configuration(mTempConfig);
20095        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20096            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20097            msg.obj = configCopy;
20098            msg.arg1 = userId;
20099            mHandler.sendMessage(msg);
20100        }
20101
20102        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20103            ProcessRecord app = mLruProcesses.get(i);
20104            try {
20105                if (app.thread != null) {
20106                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20107                            + app.processName + " new config " + configCopy);
20108                    app.thread.scheduleConfigurationChanged(configCopy);
20109                }
20110            } catch (Exception e) {
20111            }
20112        }
20113
20114        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20115        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20116                | Intent.FLAG_RECEIVER_FOREGROUND
20117                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20118        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20119                AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20120                UserHandle.USER_ALL);
20121        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20122            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20123            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20124                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20125                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20126            if (initLocale || !mProcessesReady) {
20127                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20128            }
20129            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20130                    AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20131                    UserHandle.USER_ALL);
20132        }
20133
20134        // Override configuration of the default display duplicates global config, so we need to
20135        // update it also. This will also notify WindowManager about changes.
20136        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20137                DEFAULT_DISPLAY);
20138
20139        return changes;
20140    }
20141
20142    @Override
20143    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20144        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20145
20146        synchronized (this) {
20147            // Check if display is initialized in AM.
20148            if (!mStackSupervisor.isDisplayAdded(displayId)) {
20149                // Call might come when display is not yet added or has already been removed.
20150                if (DEBUG_CONFIGURATION) {
20151                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20152                            + displayId);
20153                }
20154                return false;
20155            }
20156
20157            if (values == null && mWindowManager != null) {
20158                // sentinel: fetch the current configuration from the window manager
20159                values = mWindowManager.computeNewConfiguration(displayId);
20160            }
20161
20162            if (mWindowManager != null) {
20163                // Update OOM levels based on display size.
20164                mProcessList.applyDisplaySize(mWindowManager);
20165            }
20166
20167            final long origId = Binder.clearCallingIdentity();
20168            try {
20169                if (values != null) {
20170                    Settings.System.clearConfiguration(values);
20171                }
20172                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20173                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20174                return mTmpUpdateConfigurationResult.changes != 0;
20175            } finally {
20176                Binder.restoreCallingIdentity(origId);
20177            }
20178        }
20179    }
20180
20181    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20182            boolean deferResume, int displayId) {
20183        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20184                displayId, null /* result */);
20185    }
20186
20187    /**
20188     * Updates override configuration specific for the selected display. If no config is provided,
20189     * new one will be computed in WM based on current display info.
20190     */
20191    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20192            ActivityRecord starting, boolean deferResume, int displayId,
20193            UpdateConfigurationResult result) {
20194        int changes = 0;
20195        boolean kept = true;
20196
20197        if (mWindowManager != null) {
20198            mWindowManager.deferSurfaceLayout();
20199        }
20200        try {
20201            if (values != null) {
20202                if (displayId == DEFAULT_DISPLAY) {
20203                    // Override configuration of the default display duplicates global config, so
20204                    // we're calling global config update instead for default display. It will also
20205                    // apply the correct override config.
20206                    changes = updateGlobalConfiguration(values, false /* initLocale */,
20207                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20208                } else {
20209                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20210                }
20211            }
20212
20213            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20214        } finally {
20215            if (mWindowManager != null) {
20216                mWindowManager.continueSurfaceLayout();
20217            }
20218        }
20219
20220        if (result != null) {
20221            result.changes = changes;
20222            result.activityRelaunched = !kept;
20223        }
20224        return kept;
20225    }
20226
20227    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20228            int displayId) {
20229        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20230        final int changes = mTempConfig.updateFrom(values);
20231        if (changes == 0) {
20232            return 0;
20233        }
20234
20235        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
20236                + " for displayId=" + displayId);
20237        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20238
20239        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20240        if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20241            // Reset the unsupported display size dialog.
20242            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20243
20244            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20245        }
20246
20247        // Update the configuration with WM first and check if any of the stacks need to be resized
20248        // due to the configuration change. If so, resize the stacks now and do any relaunches if
20249        // necessary. This way we don't need to relaunch again afterwards in
20250        // ensureActivityConfigurationLocked().
20251        if (mWindowManager != null) {
20252            final int[] resizedStacks =
20253                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20254            if (resizedStacks != null) {
20255                for (int stackId : resizedStacks) {
20256                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20257                }
20258            }
20259        }
20260
20261        return changes;
20262    }
20263
20264    /** Applies latest configuration and/or visibility updates if needed. */
20265    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20266        boolean kept = true;
20267        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20268        // mainStack is null during startup.
20269        if (mainStack != null) {
20270            if (changes != 0 && starting == null) {
20271                // If the configuration changed, and the caller is not already
20272                // in the process of starting an activity, then find the top
20273                // activity to check if its configuration needs to change.
20274                starting = mainStack.topRunningActivityLocked();
20275            }
20276
20277            if (starting != null) {
20278                kept = starting.ensureActivityConfigurationLocked(changes,
20279                        false /* preserveWindow */);
20280                // And we need to make sure at this point that all other activities
20281                // are made visible with the correct configuration.
20282                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20283                        !PRESERVE_WINDOWS);
20284            }
20285        }
20286
20287        return kept;
20288    }
20289
20290    /** Helper method that requests bounds from WM and applies them to stack. */
20291    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20292        final Rect newStackBounds = new Rect();
20293        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20294        mStackSupervisor.resizeStackLocked(
20295                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20296                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20297                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20298    }
20299
20300    /**
20301     * Decide based on the configuration whether we should show the ANR,
20302     * crash, etc dialogs.  The idea is that if there is no affordance to
20303     * press the on-screen buttons, or the user experience would be more
20304     * greatly impacted than the crash itself, we shouldn't show the dialog.
20305     *
20306     * A thought: SystemUI might also want to get told about this, the Power
20307     * dialog / global actions also might want different behaviors.
20308     */
20309    private static boolean shouldShowDialogs(Configuration config) {
20310        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20311                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20312                                   && config.navigation == Configuration.NAVIGATION_NONAV);
20313        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20314        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20315                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20316                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20317                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20318        return inputMethodExists && uiModeSupportsDialogs;
20319    }
20320
20321    @Override
20322    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20323        synchronized (this) {
20324            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20325            if (srec != null) {
20326                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20327            }
20328        }
20329        return false;
20330    }
20331
20332    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20333            Intent resultData) {
20334
20335        synchronized (this) {
20336            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20337            if (r != null) {
20338                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20339            }
20340            return false;
20341        }
20342    }
20343
20344    public int getLaunchedFromUid(IBinder activityToken) {
20345        ActivityRecord srec;
20346        synchronized (this) {
20347            srec = ActivityRecord.forTokenLocked(activityToken);
20348        }
20349        if (srec == null) {
20350            return -1;
20351        }
20352        return srec.launchedFromUid;
20353    }
20354
20355    public String getLaunchedFromPackage(IBinder activityToken) {
20356        ActivityRecord srec;
20357        synchronized (this) {
20358            srec = ActivityRecord.forTokenLocked(activityToken);
20359        }
20360        if (srec == null) {
20361            return null;
20362        }
20363        return srec.launchedFromPackage;
20364    }
20365
20366    // =========================================================
20367    // LIFETIME MANAGEMENT
20368    // =========================================================
20369
20370    // Returns whether the app is receiving broadcast.
20371    // If receiving, fetch all broadcast queues which the app is
20372    // the current [or imminent] receiver on.
20373    private boolean isReceivingBroadcastLocked(ProcessRecord app,
20374            ArraySet<BroadcastQueue> receivingQueues) {
20375        if (!app.curReceivers.isEmpty()) {
20376            for (BroadcastRecord r : app.curReceivers) {
20377                receivingQueues.add(r.queue);
20378            }
20379            return true;
20380        }
20381
20382        // It's not the current receiver, but it might be starting up to become one
20383        for (BroadcastQueue queue : mBroadcastQueues) {
20384            final BroadcastRecord r = queue.mPendingBroadcast;
20385            if (r != null && r.curApp == app) {
20386                // found it; report which queue it's in
20387                receivingQueues.add(queue);
20388            }
20389        }
20390
20391        return !receivingQueues.isEmpty();
20392    }
20393
20394    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20395            int targetUid, ComponentName targetComponent, String targetProcess) {
20396        if (!mTrackingAssociations) {
20397            return null;
20398        }
20399        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20400                = mAssociations.get(targetUid);
20401        if (components == null) {
20402            components = new ArrayMap<>();
20403            mAssociations.put(targetUid, components);
20404        }
20405        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20406        if (sourceUids == null) {
20407            sourceUids = new SparseArray<>();
20408            components.put(targetComponent, sourceUids);
20409        }
20410        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20411        if (sourceProcesses == null) {
20412            sourceProcesses = new ArrayMap<>();
20413            sourceUids.put(sourceUid, sourceProcesses);
20414        }
20415        Association ass = sourceProcesses.get(sourceProcess);
20416        if (ass == null) {
20417            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20418                    targetProcess);
20419            sourceProcesses.put(sourceProcess, ass);
20420        }
20421        ass.mCount++;
20422        ass.mNesting++;
20423        if (ass.mNesting == 1) {
20424            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20425            ass.mLastState = sourceState;
20426        }
20427        return ass;
20428    }
20429
20430    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20431            ComponentName targetComponent) {
20432        if (!mTrackingAssociations) {
20433            return;
20434        }
20435        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20436                = mAssociations.get(targetUid);
20437        if (components == null) {
20438            return;
20439        }
20440        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20441        if (sourceUids == null) {
20442            return;
20443        }
20444        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20445        if (sourceProcesses == null) {
20446            return;
20447        }
20448        Association ass = sourceProcesses.get(sourceProcess);
20449        if (ass == null || ass.mNesting <= 0) {
20450            return;
20451        }
20452        ass.mNesting--;
20453        if (ass.mNesting == 0) {
20454            long uptime = SystemClock.uptimeMillis();
20455            ass.mTime += uptime - ass.mStartTime;
20456            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20457                    += uptime - ass.mLastStateUptime;
20458            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20459        }
20460    }
20461
20462    private void noteUidProcessState(final int uid, final int state) {
20463        mBatteryStatsService.noteUidProcessState(uid, state);
20464        if (mTrackingAssociations) {
20465            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20466                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20467                        = mAssociations.valueAt(i1);
20468                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20469                    SparseArray<ArrayMap<String, Association>> sourceUids
20470                            = targetComponents.valueAt(i2);
20471                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20472                    if (sourceProcesses != null) {
20473                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20474                            Association ass = sourceProcesses.valueAt(i4);
20475                            if (ass.mNesting >= 1) {
20476                                // currently associated
20477                                long uptime = SystemClock.uptimeMillis();
20478                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20479                                        += uptime - ass.mLastStateUptime;
20480                                ass.mLastState = state;
20481                                ass.mLastStateUptime = uptime;
20482                            }
20483                        }
20484                    }
20485                }
20486            }
20487        }
20488    }
20489
20490    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20491            boolean doingAll, long now) {
20492        if (mAdjSeq == app.adjSeq) {
20493            // This adjustment has already been computed.
20494            return app.curRawAdj;
20495        }
20496
20497        if (app.thread == null) {
20498            app.adjSeq = mAdjSeq;
20499            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20500            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20501            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20502        }
20503
20504        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20505        app.adjSource = null;
20506        app.adjTarget = null;
20507        app.empty = false;
20508        app.cached = false;
20509
20510        final int activitiesSize = app.activities.size();
20511
20512        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20513            // The max adjustment doesn't allow this app to be anything
20514            // below foreground, so it is not worth doing work for it.
20515            app.adjType = "fixed";
20516            app.adjSeq = mAdjSeq;
20517            app.curRawAdj = app.maxAdj;
20518            app.foregroundActivities = false;
20519            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20520            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20521            // System processes can do UI, and when they do we want to have
20522            // them trim their memory after the user leaves the UI.  To
20523            // facilitate this, here we need to determine whether or not it
20524            // is currently showing UI.
20525            app.systemNoUi = true;
20526            if (app == TOP_APP) {
20527                app.systemNoUi = false;
20528                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20529                app.adjType = "pers-top-activity";
20530            } else if (app.hasTopUi) {
20531                app.systemNoUi = false;
20532                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20533                app.adjType = "pers-top-ui";
20534            } else if (activitiesSize > 0) {
20535                for (int j = 0; j < activitiesSize; j++) {
20536                    final ActivityRecord r = app.activities.get(j);
20537                    if (r.visible) {
20538                        app.systemNoUi = false;
20539                    }
20540                }
20541            }
20542            if (!app.systemNoUi) {
20543                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20544            }
20545            return (app.curAdj=app.maxAdj);
20546        }
20547
20548        app.systemNoUi = false;
20549
20550        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20551
20552        // Determine the importance of the process, starting with most
20553        // important to least, and assign an appropriate OOM adjustment.
20554        int adj;
20555        int schedGroup;
20556        int procState;
20557        boolean foregroundActivities = false;
20558        mTmpBroadcastQueue.clear();
20559        if (app == TOP_APP) {
20560            // The last app on the list is the foreground app.
20561            adj = ProcessList.FOREGROUND_APP_ADJ;
20562            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20563            app.adjType = "top-activity";
20564            foregroundActivities = true;
20565            procState = PROCESS_STATE_CUR_TOP;
20566        } else if (app.instr != null) {
20567            // Don't want to kill running instrumentation.
20568            adj = ProcessList.FOREGROUND_APP_ADJ;
20569            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20570            app.adjType = "instrumentation";
20571            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20572        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20573            // An app that is currently receiving a broadcast also
20574            // counts as being in the foreground for OOM killer purposes.
20575            // It's placed in a sched group based on the nature of the
20576            // broadcast as reflected by which queue it's active in.
20577            adj = ProcessList.FOREGROUND_APP_ADJ;
20578            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20579                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20580            app.adjType = "broadcast";
20581            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20582        } else if (app.executingServices.size() > 0) {
20583            // An app that is currently executing a service callback also
20584            // counts as being in the foreground.
20585            adj = ProcessList.FOREGROUND_APP_ADJ;
20586            schedGroup = app.execServicesFg ?
20587                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20588            app.adjType = "exec-service";
20589            procState = ActivityManager.PROCESS_STATE_SERVICE;
20590            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20591        } else {
20592            // As far as we know the process is empty.  We may change our mind later.
20593            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20594            // At this point we don't actually know the adjustment.  Use the cached adj
20595            // value that the caller wants us to.
20596            adj = cachedAdj;
20597            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20598            app.cached = true;
20599            app.empty = true;
20600            app.adjType = "cch-empty";
20601        }
20602
20603        // Examine all activities if not already foreground.
20604        if (!foregroundActivities && activitiesSize > 0) {
20605            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20606            for (int j = 0; j < activitiesSize; j++) {
20607                final ActivityRecord r = app.activities.get(j);
20608                if (r.app != app) {
20609                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20610                            + " instead of expected " + app);
20611                    if (r.app == null || (r.app.uid == app.uid)) {
20612                        // Only fix things up when they look sane
20613                        r.app = app;
20614                    } else {
20615                        continue;
20616                    }
20617                }
20618                if (r.visible) {
20619                    // App has a visible activity; only upgrade adjustment.
20620                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20621                        adj = ProcessList.VISIBLE_APP_ADJ;
20622                        app.adjType = "visible";
20623                    }
20624                    if (procState > PROCESS_STATE_CUR_TOP) {
20625                        procState = PROCESS_STATE_CUR_TOP;
20626                    }
20627                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20628                    app.cached = false;
20629                    app.empty = false;
20630                    foregroundActivities = true;
20631                    final TaskRecord task = r.getTask();
20632                    if (task != null && minLayer > 0) {
20633                        final int layer = task.mLayerRank;
20634                        if (layer >= 0 && minLayer > layer) {
20635                            minLayer = layer;
20636                        }
20637                    }
20638                    break;
20639                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20640                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20641                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20642                        app.adjType = "pausing";
20643                    }
20644                    if (procState > PROCESS_STATE_CUR_TOP) {
20645                        procState = PROCESS_STATE_CUR_TOP;
20646                    }
20647                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20648                    app.cached = false;
20649                    app.empty = false;
20650                    foregroundActivities = true;
20651                } else if (r.state == ActivityState.STOPPING) {
20652                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20653                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20654                        app.adjType = "stopping";
20655                    }
20656                    // For the process state, we will at this point consider the
20657                    // process to be cached.  It will be cached either as an activity
20658                    // or empty depending on whether the activity is finishing.  We do
20659                    // this so that we can treat the process as cached for purposes of
20660                    // memory trimming (determing current memory level, trim command to
20661                    // send to process) since there can be an arbitrary number of stopping
20662                    // processes and they should soon all go into the cached state.
20663                    if (!r.finishing) {
20664                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20665                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20666                        }
20667                    }
20668                    app.cached = false;
20669                    app.empty = false;
20670                    foregroundActivities = true;
20671                } else {
20672                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20673                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20674                        app.adjType = "cch-act";
20675                    }
20676                }
20677            }
20678            if (adj == ProcessList.VISIBLE_APP_ADJ) {
20679                adj += minLayer;
20680            }
20681        }
20682
20683        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20684                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20685            if (app.foregroundServices) {
20686                // The user is aware of this app, so make it visible.
20687                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20688                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20689                app.cached = false;
20690                app.adjType = "fg-service";
20691                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20692            } else if (app.forcingToForeground != null) {
20693                // The user is aware of this app, so make it visible.
20694                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20695                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20696                app.cached = false;
20697                app.adjType = "force-fg";
20698                app.adjSource = app.forcingToForeground;
20699                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20700            } else if (app.hasOverlayUi) {
20701                // The process is display an overlay UI.
20702                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20703                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20704                app.cached = false;
20705                app.adjType = "has-overlay-ui";
20706                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20707            }
20708        }
20709
20710        if (app == mHeavyWeightProcess) {
20711            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
20712                // We don't want to kill the current heavy-weight process.
20713                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
20714                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20715                app.cached = false;
20716                app.adjType = "heavy";
20717            }
20718            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20719                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
20720            }
20721        }
20722
20723        if (app == mHomeProcess) {
20724            if (adj > ProcessList.HOME_APP_ADJ) {
20725                // This process is hosting what we currently consider to be the
20726                // home app, so we don't want to let it go into the background.
20727                adj = ProcessList.HOME_APP_ADJ;
20728                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20729                app.cached = false;
20730                app.adjType = "home";
20731            }
20732            if (procState > ActivityManager.PROCESS_STATE_HOME) {
20733                procState = ActivityManager.PROCESS_STATE_HOME;
20734            }
20735        }
20736
20737        if (app == mPreviousProcess && app.activities.size() > 0) {
20738            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20739                // This was the previous process that showed UI to the user.
20740                // We want to try to keep it around more aggressively, to give
20741                // a good experience around switching between two apps.
20742                adj = ProcessList.PREVIOUS_APP_ADJ;
20743                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20744                app.cached = false;
20745                app.adjType = "previous";
20746            }
20747            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20748                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20749            }
20750        }
20751
20752        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
20753                + " reason=" + app.adjType);
20754
20755        // By default, we use the computed adjustment.  It may be changed if
20756        // there are applications dependent on our services or providers, but
20757        // this gives us a baseline and makes sure we don't get into an
20758        // infinite recursion.
20759        app.adjSeq = mAdjSeq;
20760        app.curRawAdj = adj;
20761        app.hasStartedServices = false;
20762
20763        if (mBackupTarget != null && app == mBackupTarget.app) {
20764            // If possible we want to avoid killing apps while they're being backed up
20765            if (adj > ProcessList.BACKUP_APP_ADJ) {
20766                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
20767                adj = ProcessList.BACKUP_APP_ADJ;
20768                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20769                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20770                }
20771                app.adjType = "backup";
20772                app.cached = false;
20773            }
20774            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
20775                procState = ActivityManager.PROCESS_STATE_BACKUP;
20776            }
20777        }
20778
20779        boolean mayBeTop = false;
20780
20781        for (int is = app.services.size()-1;
20782                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20783                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20784                        || procState > ActivityManager.PROCESS_STATE_TOP);
20785                is--) {
20786            ServiceRecord s = app.services.valueAt(is);
20787            if (s.startRequested) {
20788                app.hasStartedServices = true;
20789                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
20790                    procState = ActivityManager.PROCESS_STATE_SERVICE;
20791                }
20792                if (app.hasShownUi && app != mHomeProcess) {
20793                    // If this process has shown some UI, let it immediately
20794                    // go to the LRU list because it may be pretty heavy with
20795                    // UI stuff.  We'll tag it with a label just to help
20796                    // debug and understand what is going on.
20797                    if (adj > ProcessList.SERVICE_ADJ) {
20798                        app.adjType = "cch-started-ui-services";
20799                    }
20800                } else {
20801                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20802                        // This service has seen some activity within
20803                        // recent memory, so we will keep its process ahead
20804                        // of the background processes.
20805                        if (adj > ProcessList.SERVICE_ADJ) {
20806                            adj = ProcessList.SERVICE_ADJ;
20807                            app.adjType = "started-services";
20808                            app.cached = false;
20809                        }
20810                    }
20811                    // If we have let the service slide into the background
20812                    // state, still have some text describing what it is doing
20813                    // even though the service no longer has an impact.
20814                    if (adj > ProcessList.SERVICE_ADJ) {
20815                        app.adjType = "cch-started-services";
20816                    }
20817                }
20818            }
20819
20820            for (int conni = s.connections.size()-1;
20821                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20822                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20823                            || procState > ActivityManager.PROCESS_STATE_TOP);
20824                    conni--) {
20825                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
20826                for (int i = 0;
20827                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
20828                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20829                                || procState > ActivityManager.PROCESS_STATE_TOP);
20830                        i++) {
20831                    // XXX should compute this based on the max of
20832                    // all connected clients.
20833                    ConnectionRecord cr = clist.get(i);
20834                    if (cr.binding.client == app) {
20835                        // Binding to ourself is not interesting.
20836                        continue;
20837                    }
20838
20839                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
20840                        ProcessRecord client = cr.binding.client;
20841                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
20842                                TOP_APP, doingAll, now);
20843                        int clientProcState = client.curProcState;
20844                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20845                            // If the other app is cached for any reason, for purposes here
20846                            // we are going to consider it empty.  The specific cached state
20847                            // doesn't propagate except under certain conditions.
20848                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20849                        }
20850                        String adjType = null;
20851                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
20852                            // Not doing bind OOM management, so treat
20853                            // this guy more like a started service.
20854                            if (app.hasShownUi && app != mHomeProcess) {
20855                                // If this process has shown some UI, let it immediately
20856                                // go to the LRU list because it may be pretty heavy with
20857                                // UI stuff.  We'll tag it with a label just to help
20858                                // debug and understand what is going on.
20859                                if (adj > clientAdj) {
20860                                    adjType = "cch-bound-ui-services";
20861                                }
20862                                app.cached = false;
20863                                clientAdj = adj;
20864                                clientProcState = procState;
20865                            } else {
20866                                if (now >= (s.lastActivity
20867                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20868                                    // This service has not seen activity within
20869                                    // recent memory, so allow it to drop to the
20870                                    // LRU list if there is no other reason to keep
20871                                    // it around.  We'll also tag it with a label just
20872                                    // to help debug and undertand what is going on.
20873                                    if (adj > clientAdj) {
20874                                        adjType = "cch-bound-services";
20875                                    }
20876                                    clientAdj = adj;
20877                                }
20878                            }
20879                        }
20880                        if (adj > clientAdj) {
20881                            // If this process has recently shown UI, and
20882                            // the process that is binding to it is less
20883                            // important than being visible, then we don't
20884                            // care about the binding as much as we care
20885                            // about letting this process get into the LRU
20886                            // list to be killed and restarted if needed for
20887                            // memory.
20888                            if (app.hasShownUi && app != mHomeProcess
20889                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20890                                adjType = "cch-bound-ui-services";
20891                            } else {
20892                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
20893                                        |Context.BIND_IMPORTANT)) != 0) {
20894                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
20895                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
20896                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
20897                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
20898                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20899                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20900                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
20901                                    adj = clientAdj;
20902                                } else {
20903                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20904                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
20905                                    }
20906                                }
20907                                if (!client.cached) {
20908                                    app.cached = false;
20909                                }
20910                                adjType = "service";
20911                            }
20912                        }
20913                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20914                            // This will treat important bound services identically to
20915                            // the top app, which may behave differently than generic
20916                            // foreground work.
20917                            if (client.curSchedGroup > schedGroup) {
20918                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20919                                    schedGroup = client.curSchedGroup;
20920                                } else {
20921                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20922                                }
20923                            }
20924                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20925                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20926                                    // Special handling of clients who are in the top state.
20927                                    // We *may* want to consider this process to be in the
20928                                    // top state as well, but only if there is not another
20929                                    // reason for it to be running.  Being on the top is a
20930                                    // special state, meaning you are specifically running
20931                                    // for the current top app.  If the process is already
20932                                    // running in the background for some other reason, it
20933                                    // is more important to continue considering it to be
20934                                    // in the background state.
20935                                    mayBeTop = true;
20936                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20937                                } else {
20938                                    // Special handling for above-top states (persistent
20939                                    // processes).  These should not bring the current process
20940                                    // into the top state, since they are not on top.  Instead
20941                                    // give them the best state after that.
20942                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
20943                                        clientProcState =
20944                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20945                                    } else if (mWakefulness
20946                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
20947                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
20948                                                    != 0) {
20949                                        clientProcState =
20950                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20951                                    } else {
20952                                        clientProcState =
20953                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20954                                    }
20955                                }
20956                            }
20957                        } else {
20958                            if (clientProcState <
20959                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20960                                clientProcState =
20961                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20962                            }
20963                        }
20964                        if (procState > clientProcState) {
20965                            procState = clientProcState;
20966                        }
20967                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20968                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
20969                            app.pendingUiClean = true;
20970                        }
20971                        if (adjType != null) {
20972                            app.adjType = adjType;
20973                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20974                                    .REASON_SERVICE_IN_USE;
20975                            app.adjSource = cr.binding.client;
20976                            app.adjSourceProcState = clientProcState;
20977                            app.adjTarget = s.name;
20978                        }
20979                    }
20980                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
20981                        app.treatLikeActivity = true;
20982                    }
20983                    final ActivityRecord a = cr.activity;
20984                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
20985                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
20986                            (a.visible || a.state == ActivityState.RESUMED ||
20987                             a.state == ActivityState.PAUSING)) {
20988                            adj = ProcessList.FOREGROUND_APP_ADJ;
20989                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20990                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20991                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
20992                                } else {
20993                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20994                                }
20995                            }
20996                            app.cached = false;
20997                            app.adjType = "service";
20998                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20999                                    .REASON_SERVICE_IN_USE;
21000                            app.adjSource = a;
21001                            app.adjSourceProcState = procState;
21002                            app.adjTarget = s.name;
21003                        }
21004                    }
21005                }
21006            }
21007        }
21008
21009        for (int provi = app.pubProviders.size()-1;
21010                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21011                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21012                        || procState > ActivityManager.PROCESS_STATE_TOP);
21013                provi--) {
21014            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21015            for (int i = cpr.connections.size()-1;
21016                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21017                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21018                            || procState > ActivityManager.PROCESS_STATE_TOP);
21019                    i--) {
21020                ContentProviderConnection conn = cpr.connections.get(i);
21021                ProcessRecord client = conn.client;
21022                if (client == app) {
21023                    // Being our own client is not interesting.
21024                    continue;
21025                }
21026                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21027                int clientProcState = client.curProcState;
21028                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21029                    // If the other app is cached for any reason, for purposes here
21030                    // we are going to consider it empty.
21031                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21032                }
21033                if (adj > clientAdj) {
21034                    if (app.hasShownUi && app != mHomeProcess
21035                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21036                        app.adjType = "cch-ui-provider";
21037                    } else {
21038                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21039                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21040                        app.adjType = "provider";
21041                    }
21042                    app.cached &= client.cached;
21043                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21044                            .REASON_PROVIDER_IN_USE;
21045                    app.adjSource = client;
21046                    app.adjSourceProcState = clientProcState;
21047                    app.adjTarget = cpr.name;
21048                }
21049                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21050                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21051                        // Special handling of clients who are in the top state.
21052                        // We *may* want to consider this process to be in the
21053                        // top state as well, but only if there is not another
21054                        // reason for it to be running.  Being on the top is a
21055                        // special state, meaning you are specifically running
21056                        // for the current top app.  If the process is already
21057                        // running in the background for some other reason, it
21058                        // is more important to continue considering it to be
21059                        // in the background state.
21060                        mayBeTop = true;
21061                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21062                    } else {
21063                        // Special handling for above-top states (persistent
21064                        // processes).  These should not bring the current process
21065                        // into the top state, since they are not on top.  Instead
21066                        // give them the best state after that.
21067                        clientProcState =
21068                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21069                    }
21070                }
21071                if (procState > clientProcState) {
21072                    procState = clientProcState;
21073                }
21074                if (client.curSchedGroup > schedGroup) {
21075                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21076                }
21077            }
21078            // If the provider has external (non-framework) process
21079            // dependencies, ensure that its adjustment is at least
21080            // FOREGROUND_APP_ADJ.
21081            if (cpr.hasExternalProcessHandles()) {
21082                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21083                    adj = ProcessList.FOREGROUND_APP_ADJ;
21084                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21085                    app.cached = false;
21086                    app.adjType = "provider";
21087                    app.adjTarget = cpr.name;
21088                }
21089                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21090                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21091                }
21092            }
21093        }
21094
21095        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
21096            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21097                adj = ProcessList.PREVIOUS_APP_ADJ;
21098                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21099                app.cached = false;
21100                app.adjType = "provider";
21101            }
21102            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21103                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21104            }
21105        }
21106
21107        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21108            // A client of one of our services or providers is in the top state.  We
21109            // *may* want to be in the top state, but not if we are already running in
21110            // the background for some other reason.  For the decision here, we are going
21111            // to pick out a few specific states that we want to remain in when a client
21112            // is top (states that tend to be longer-term) and otherwise allow it to go
21113            // to the top state.
21114            switch (procState) {
21115                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21116                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21117                case ActivityManager.PROCESS_STATE_SERVICE:
21118                    // These all are longer-term states, so pull them up to the top
21119                    // of the background states, but not all the way to the top state.
21120                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21121                    break;
21122                default:
21123                    // Otherwise, top is a better choice, so take it.
21124                    procState = ActivityManager.PROCESS_STATE_TOP;
21125                    break;
21126            }
21127        }
21128
21129        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21130            if (app.hasClientActivities) {
21131                // This is a cached process, but with client activities.  Mark it so.
21132                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21133                app.adjType = "cch-client-act";
21134            } else if (app.treatLikeActivity) {
21135                // This is a cached process, but somebody wants us to treat it like it has
21136                // an activity, okay!
21137                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21138                app.adjType = "cch-as-act";
21139            }
21140        }
21141
21142        if (adj == ProcessList.SERVICE_ADJ) {
21143            if (doingAll) {
21144                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21145                mNewNumServiceProcs++;
21146                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21147                if (!app.serviceb) {
21148                    // This service isn't far enough down on the LRU list to
21149                    // normally be a B service, but if we are low on RAM and it
21150                    // is large we want to force it down since we would prefer to
21151                    // keep launcher over it.
21152                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21153                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21154                        app.serviceHighRam = true;
21155                        app.serviceb = true;
21156                        //Slog.i(TAG, "ADJ " + app + " high ram!");
21157                    } else {
21158                        mNewNumAServiceProcs++;
21159                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
21160                    }
21161                } else {
21162                    app.serviceHighRam = false;
21163                }
21164            }
21165            if (app.serviceb) {
21166                adj = ProcessList.SERVICE_B_ADJ;
21167            }
21168        }
21169
21170        app.curRawAdj = adj;
21171
21172        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21173        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21174        if (adj > app.maxAdj) {
21175            adj = app.maxAdj;
21176            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21177                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21178            }
21179        }
21180
21181        // Do final modification to adj.  Everything we do between here and applying
21182        // the final setAdj must be done in this function, because we will also use
21183        // it when computing the final cached adj later.  Note that we don't need to
21184        // worry about this for max adj above, since max adj will always be used to
21185        // keep it out of the cached vaues.
21186        app.curAdj = app.modifyRawOomAdj(adj);
21187        app.curSchedGroup = schedGroup;
21188        app.curProcState = procState;
21189        app.foregroundActivities = foregroundActivities;
21190
21191        return app.curRawAdj;
21192    }
21193
21194    /**
21195     * Record new PSS sample for a process.
21196     */
21197    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21198            long now) {
21199        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21200                swapPss * 1024);
21201        proc.lastPssTime = now;
21202        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21203        if (DEBUG_PSS) Slog.d(TAG_PSS,
21204                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21205                + " state=" + ProcessList.makeProcStateString(procState));
21206        if (proc.initialIdlePss == 0) {
21207            proc.initialIdlePss = pss;
21208        }
21209        proc.lastPss = pss;
21210        proc.lastSwapPss = swapPss;
21211        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21212            proc.lastCachedPss = pss;
21213            proc.lastCachedSwapPss = swapPss;
21214        }
21215
21216        final SparseArray<Pair<Long, String>> watchUids
21217                = mMemWatchProcesses.getMap().get(proc.processName);
21218        Long check = null;
21219        if (watchUids != null) {
21220            Pair<Long, String> val = watchUids.get(proc.uid);
21221            if (val == null) {
21222                val = watchUids.get(0);
21223            }
21224            if (val != null) {
21225                check = val.first;
21226            }
21227        }
21228        if (check != null) {
21229            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21230                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21231                if (!isDebuggable) {
21232                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21233                        isDebuggable = true;
21234                    }
21235                }
21236                if (isDebuggable) {
21237                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21238                    final ProcessRecord myProc = proc;
21239                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
21240                    mMemWatchDumpProcName = proc.processName;
21241                    mMemWatchDumpFile = heapdumpFile.toString();
21242                    mMemWatchDumpPid = proc.pid;
21243                    mMemWatchDumpUid = proc.uid;
21244                    BackgroundThread.getHandler().post(new Runnable() {
21245                        @Override
21246                        public void run() {
21247                            revokeUriPermission(ActivityThread.currentActivityThread()
21248                                            .getApplicationThread(),
21249                                    null, DumpHeapActivity.JAVA_URI,
21250                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
21251                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21252                                    UserHandle.myUserId());
21253                            ParcelFileDescriptor fd = null;
21254                            try {
21255                                heapdumpFile.delete();
21256                                fd = ParcelFileDescriptor.open(heapdumpFile,
21257                                        ParcelFileDescriptor.MODE_CREATE |
21258                                                ParcelFileDescriptor.MODE_TRUNCATE |
21259                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
21260                                                ParcelFileDescriptor.MODE_APPEND);
21261                                IApplicationThread thread = myProc.thread;
21262                                if (thread != null) {
21263                                    try {
21264                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
21265                                                "Requesting dump heap from "
21266                                                + myProc + " to " + heapdumpFile);
21267                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
21268                                    } catch (RemoteException e) {
21269                                    }
21270                                }
21271                            } catch (FileNotFoundException e) {
21272                                e.printStackTrace();
21273                            } finally {
21274                                if (fd != null) {
21275                                    try {
21276                                        fd.close();
21277                                    } catch (IOException e) {
21278                                    }
21279                                }
21280                            }
21281                        }
21282                    });
21283                } else {
21284                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21285                            + ", but debugging not enabled");
21286                }
21287            }
21288        }
21289    }
21290
21291    /**
21292     * Schedule PSS collection of a process.
21293     */
21294    void requestPssLocked(ProcessRecord proc, int procState) {
21295        if (mPendingPssProcesses.contains(proc)) {
21296            return;
21297        }
21298        if (mPendingPssProcesses.size() == 0) {
21299            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21300        }
21301        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21302        proc.pssProcState = procState;
21303        mPendingPssProcesses.add(proc);
21304    }
21305
21306    /**
21307     * Schedule PSS collection of all processes.
21308     */
21309    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21310        if (!always) {
21311            if (now < (mLastFullPssTime +
21312                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
21313                return;
21314            }
21315        }
21316        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21317        mLastFullPssTime = now;
21318        mFullPssPending = true;
21319        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21320        mPendingPssProcesses.clear();
21321        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21322            ProcessRecord app = mLruProcesses.get(i);
21323            if (app.thread == null
21324                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21325                continue;
21326            }
21327            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21328                app.pssProcState = app.setProcState;
21329                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21330                        mTestPssMode, isSleepingLocked(), now);
21331                mPendingPssProcesses.add(app);
21332            }
21333        }
21334        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21335    }
21336
21337    public void setTestPssMode(boolean enabled) {
21338        synchronized (this) {
21339            mTestPssMode = enabled;
21340            if (enabled) {
21341                // Whenever we enable the mode, we want to take a snapshot all of current
21342                // process mem use.
21343                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21344            }
21345        }
21346    }
21347
21348    /**
21349     * Ask a given process to GC right now.
21350     */
21351    final void performAppGcLocked(ProcessRecord app) {
21352        try {
21353            app.lastRequestedGc = SystemClock.uptimeMillis();
21354            if (app.thread != null) {
21355                if (app.reportLowMemory) {
21356                    app.reportLowMemory = false;
21357                    app.thread.scheduleLowMemory();
21358                } else {
21359                    app.thread.processInBackground();
21360                }
21361            }
21362        } catch (Exception e) {
21363            // whatever.
21364        }
21365    }
21366
21367    /**
21368     * Returns true if things are idle enough to perform GCs.
21369     */
21370    private final boolean canGcNowLocked() {
21371        boolean processingBroadcasts = false;
21372        for (BroadcastQueue q : mBroadcastQueues) {
21373            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21374                processingBroadcasts = true;
21375            }
21376        }
21377        return !processingBroadcasts
21378                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21379    }
21380
21381    /**
21382     * Perform GCs on all processes that are waiting for it, but only
21383     * if things are idle.
21384     */
21385    final void performAppGcsLocked() {
21386        final int N = mProcessesToGc.size();
21387        if (N <= 0) {
21388            return;
21389        }
21390        if (canGcNowLocked()) {
21391            while (mProcessesToGc.size() > 0) {
21392                ProcessRecord proc = mProcessesToGc.remove(0);
21393                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21394                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
21395                            <= SystemClock.uptimeMillis()) {
21396                        // To avoid spamming the system, we will GC processes one
21397                        // at a time, waiting a few seconds between each.
21398                        performAppGcLocked(proc);
21399                        scheduleAppGcsLocked();
21400                        return;
21401                    } else {
21402                        // It hasn't been long enough since we last GCed this
21403                        // process...  put it in the list to wait for its time.
21404                        addProcessToGcListLocked(proc);
21405                        break;
21406                    }
21407                }
21408            }
21409
21410            scheduleAppGcsLocked();
21411        }
21412    }
21413
21414    /**
21415     * If all looks good, perform GCs on all processes waiting for them.
21416     */
21417    final void performAppGcsIfAppropriateLocked() {
21418        if (canGcNowLocked()) {
21419            performAppGcsLocked();
21420            return;
21421        }
21422        // Still not idle, wait some more.
21423        scheduleAppGcsLocked();
21424    }
21425
21426    /**
21427     * Schedule the execution of all pending app GCs.
21428     */
21429    final void scheduleAppGcsLocked() {
21430        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21431
21432        if (mProcessesToGc.size() > 0) {
21433            // Schedule a GC for the time to the next process.
21434            ProcessRecord proc = mProcessesToGc.get(0);
21435            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21436
21437            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
21438            long now = SystemClock.uptimeMillis();
21439            if (when < (now+GC_TIMEOUT)) {
21440                when = now + GC_TIMEOUT;
21441            }
21442            mHandler.sendMessageAtTime(msg, when);
21443        }
21444    }
21445
21446    /**
21447     * Add a process to the array of processes waiting to be GCed.  Keeps the
21448     * list in sorted order by the last GC time.  The process can't already be
21449     * on the list.
21450     */
21451    final void addProcessToGcListLocked(ProcessRecord proc) {
21452        boolean added = false;
21453        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21454            if (mProcessesToGc.get(i).lastRequestedGc <
21455                    proc.lastRequestedGc) {
21456                added = true;
21457                mProcessesToGc.add(i+1, proc);
21458                break;
21459            }
21460        }
21461        if (!added) {
21462            mProcessesToGc.add(0, proc);
21463        }
21464    }
21465
21466    /**
21467     * Set up to ask a process to GC itself.  This will either do it
21468     * immediately, or put it on the list of processes to gc the next
21469     * time things are idle.
21470     */
21471    final void scheduleAppGcLocked(ProcessRecord app) {
21472        long now = SystemClock.uptimeMillis();
21473        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
21474            return;
21475        }
21476        if (!mProcessesToGc.contains(app)) {
21477            addProcessToGcListLocked(app);
21478            scheduleAppGcsLocked();
21479        }
21480    }
21481
21482    final void checkExcessivePowerUsageLocked(boolean doKills) {
21483        updateCpuStatsNow();
21484
21485        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21486        boolean doWakeKills = doKills;
21487        boolean doCpuKills = doKills;
21488        if (mLastPowerCheckRealtime == 0) {
21489            doWakeKills = false;
21490        }
21491        if (mLastPowerCheckUptime == 0) {
21492            doCpuKills = false;
21493        }
21494        if (stats.isScreenOn()) {
21495            doWakeKills = false;
21496        }
21497        final long curRealtime = SystemClock.elapsedRealtime();
21498        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21499        final long curUptime = SystemClock.uptimeMillis();
21500        final long uptimeSince = curUptime - mLastPowerCheckUptime;
21501        mLastPowerCheckRealtime = curRealtime;
21502        mLastPowerCheckUptime = curUptime;
21503        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
21504            doWakeKills = false;
21505        }
21506        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
21507            doCpuKills = false;
21508        }
21509        int i = mLruProcesses.size();
21510        while (i > 0) {
21511            i--;
21512            ProcessRecord app = mLruProcesses.get(i);
21513            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21514                long wtime;
21515                synchronized (stats) {
21516                    wtime = stats.getProcessWakeTime(app.info.uid,
21517                            app.pid, curRealtime);
21518                }
21519                long wtimeUsed = wtime - app.lastWakeTime;
21520                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21521                if (DEBUG_POWER) {
21522                    StringBuilder sb = new StringBuilder(128);
21523                    sb.append("Wake for ");
21524                    app.toShortString(sb);
21525                    sb.append(": over ");
21526                    TimeUtils.formatDuration(realtimeSince, sb);
21527                    sb.append(" used ");
21528                    TimeUtils.formatDuration(wtimeUsed, sb);
21529                    sb.append(" (");
21530                    sb.append((wtimeUsed*100)/realtimeSince);
21531                    sb.append("%)");
21532                    Slog.i(TAG_POWER, sb.toString());
21533                    sb.setLength(0);
21534                    sb.append("CPU for ");
21535                    app.toShortString(sb);
21536                    sb.append(": over ");
21537                    TimeUtils.formatDuration(uptimeSince, sb);
21538                    sb.append(" used ");
21539                    TimeUtils.formatDuration(cputimeUsed, sb);
21540                    sb.append(" (");
21541                    sb.append((cputimeUsed*100)/uptimeSince);
21542                    sb.append("%)");
21543                    Slog.i(TAG_POWER, sb.toString());
21544                }
21545                // If a process has held a wake lock for more
21546                // than 50% of the time during this period,
21547                // that sounds bad.  Kill!
21548                if (doWakeKills && realtimeSince > 0
21549                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
21550                    synchronized (stats) {
21551                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21552                                realtimeSince, wtimeUsed);
21553                    }
21554                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21555                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21556                } else if (doCpuKills && uptimeSince > 0
21557                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
21558                    synchronized (stats) {
21559                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21560                                uptimeSince, cputimeUsed);
21561                    }
21562                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21563                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21564                } else {
21565                    app.lastWakeTime = wtime;
21566                    app.lastCpuTime = app.curCpuTime;
21567                }
21568            }
21569        }
21570    }
21571
21572    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21573            long nowElapsed) {
21574        boolean success = true;
21575
21576        if (app.curRawAdj != app.setRawAdj) {
21577            app.setRawAdj = app.curRawAdj;
21578        }
21579
21580        int changes = 0;
21581
21582        if (app.curAdj != app.setAdj) {
21583            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21584            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21585                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21586                    + app.adjType);
21587            app.setAdj = app.curAdj;
21588            app.verifiedAdj = ProcessList.INVALID_ADJ;
21589        }
21590
21591        if (app.setSchedGroup != app.curSchedGroup) {
21592            int oldSchedGroup = app.setSchedGroup;
21593            app.setSchedGroup = app.curSchedGroup;
21594            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21595                    "Setting sched group of " + app.processName
21596                    + " to " + app.curSchedGroup);
21597            if (app.waitingToKill != null && app.curReceivers.isEmpty()
21598                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21599                app.kill(app.waitingToKill, true);
21600                success = false;
21601            } else {
21602                int processGroup;
21603                switch (app.curSchedGroup) {
21604                    case ProcessList.SCHED_GROUP_BACKGROUND:
21605                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21606                        break;
21607                    case ProcessList.SCHED_GROUP_TOP_APP:
21608                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21609                        processGroup = THREAD_GROUP_TOP_APP;
21610                        break;
21611                    default:
21612                        processGroup = THREAD_GROUP_DEFAULT;
21613                        break;
21614                }
21615                long oldId = Binder.clearCallingIdentity();
21616                try {
21617                    setProcessGroup(app.pid, processGroup);
21618                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21619                        // do nothing if we already switched to RT
21620                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21621                            mVrController.onTopProcChangedLocked(app);
21622                            if (mUseFifoUiScheduling) {
21623                                // Switch UI pipeline for app to SCHED_FIFO
21624                                app.savedPriority = Process.getThreadPriority(app.pid);
21625                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
21626                                if (app.renderThreadTid != 0) {
21627                                    scheduleAsFifoPriority(app.renderThreadTid,
21628                                        /* suppressLogs */true);
21629                                    if (DEBUG_OOM_ADJ) {
21630                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
21631                                            app.renderThreadTid + ") to FIFO");
21632                                    }
21633                                } else {
21634                                    if (DEBUG_OOM_ADJ) {
21635                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
21636                                    }
21637                                }
21638                            } else {
21639                                // Boost priority for top app UI and render threads
21640                                setThreadPriority(app.pid, -10);
21641                                if (app.renderThreadTid != 0) {
21642                                    try {
21643                                        setThreadPriority(app.renderThreadTid, -10);
21644                                    } catch (IllegalArgumentException e) {
21645                                        // thread died, ignore
21646                                    }
21647                                }
21648                            }
21649                        }
21650                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
21651                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21652                        mVrController.onTopProcChangedLocked(app);
21653                        if (mUseFifoUiScheduling) {
21654                            // Reset UI pipeline to SCHED_OTHER
21655                            setThreadScheduler(app.pid, SCHED_OTHER, 0);
21656                            setThreadPriority(app.pid, app.savedPriority);
21657                            if (app.renderThreadTid != 0) {
21658                                setThreadScheduler(app.renderThreadTid,
21659                                    SCHED_OTHER, 0);
21660                                setThreadPriority(app.renderThreadTid, -4);
21661                            }
21662                        } else {
21663                            // Reset priority for top app UI and render threads
21664                            setThreadPriority(app.pid, 0);
21665                            if (app.renderThreadTid != 0) {
21666                                setThreadPriority(app.renderThreadTid, 0);
21667                            }
21668                        }
21669                    }
21670                } catch (Exception e) {
21671                    Slog.w(TAG, "Failed setting process group of " + app.pid
21672                            + " to " + app.curSchedGroup);
21673                    e.printStackTrace();
21674                } finally {
21675                    Binder.restoreCallingIdentity(oldId);
21676                }
21677            }
21678        }
21679        if (app.repForegroundActivities != app.foregroundActivities) {
21680            app.repForegroundActivities = app.foregroundActivities;
21681            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
21682        }
21683        if (app.repProcState != app.curProcState) {
21684            app.repProcState = app.curProcState;
21685            if (app.thread != null) {
21686                try {
21687                    if (false) {
21688                        //RuntimeException h = new RuntimeException("here");
21689                        Slog.i(TAG, "Sending new process state " + app.repProcState
21690                                + " to " + app /*, h*/);
21691                    }
21692                    app.thread.setProcessState(app.repProcState);
21693                } catch (RemoteException e) {
21694                }
21695            }
21696        }
21697        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
21698                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
21699            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
21700                // Experimental code to more aggressively collect pss while
21701                // running test...  the problem is that this tends to collect
21702                // the data right when a process is transitioning between process
21703                // states, which well tend to give noisy data.
21704                long start = SystemClock.uptimeMillis();
21705                long pss = Debug.getPss(app.pid, mTmpLong, null);
21706                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
21707                mPendingPssProcesses.remove(app);
21708                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
21709                        + " to " + app.curProcState + ": "
21710                        + (SystemClock.uptimeMillis()-start) + "ms");
21711            }
21712            app.lastStateTime = now;
21713            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21714                    mTestPssMode, isSleepingLocked(), now);
21715            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
21716                    + ProcessList.makeProcStateString(app.setProcState) + " to "
21717                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
21718                    + (app.nextPssTime-now) + ": " + app);
21719        } else {
21720            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
21721                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
21722                    mTestPssMode)))) {
21723                requestPssLocked(app, app.setProcState);
21724                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
21725                        mTestPssMode, isSleepingLocked(), now);
21726            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
21727                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
21728        }
21729        if (app.setProcState != app.curProcState) {
21730            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21731                    "Proc state change of " + app.processName
21732                            + " to " + app.curProcState);
21733            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
21734            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
21735            if (setImportant && !curImportant) {
21736                // This app is no longer something we consider important enough to allow to
21737                // use arbitrary amounts of battery power.  Note
21738                // its current wake lock time to later know to kill it if
21739                // it is not behaving well.
21740                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21741                synchronized (stats) {
21742                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
21743                            app.pid, nowElapsed);
21744                }
21745                app.lastCpuTime = app.curCpuTime;
21746
21747            }
21748            // Inform UsageStats of important process state change
21749            // Must be called before updating setProcState
21750            maybeUpdateUsageStatsLocked(app, nowElapsed);
21751
21752            app.setProcState = app.curProcState;
21753            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21754                app.notCachedSinceIdle = false;
21755            }
21756            if (!doingAll) {
21757                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
21758            } else {
21759                app.procStateChanged = true;
21760            }
21761        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
21762                > USAGE_STATS_INTERACTION_INTERVAL) {
21763            // For apps that sit around for a long time in the interactive state, we need
21764            // to report this at least once a day so they don't go idle.
21765            maybeUpdateUsageStatsLocked(app, nowElapsed);
21766        }
21767
21768        if (changes != 0) {
21769            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21770                    "Changes in " + app + ": " + changes);
21771            int i = mPendingProcessChanges.size()-1;
21772            ProcessChangeItem item = null;
21773            while (i >= 0) {
21774                item = mPendingProcessChanges.get(i);
21775                if (item.pid == app.pid) {
21776                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21777                            "Re-using existing item: " + item);
21778                    break;
21779                }
21780                i--;
21781            }
21782            if (i < 0) {
21783                // No existing item in pending changes; need a new one.
21784                final int NA = mAvailProcessChanges.size();
21785                if (NA > 0) {
21786                    item = mAvailProcessChanges.remove(NA-1);
21787                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21788                            "Retrieving available item: " + item);
21789                } else {
21790                    item = new ProcessChangeItem();
21791                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21792                            "Allocating new item: " + item);
21793                }
21794                item.changes = 0;
21795                item.pid = app.pid;
21796                item.uid = app.info.uid;
21797                if (mPendingProcessChanges.size() == 0) {
21798                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21799                            "*** Enqueueing dispatch processes changed!");
21800                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
21801                }
21802                mPendingProcessChanges.add(item);
21803            }
21804            item.changes |= changes;
21805            item.foregroundActivities = app.repForegroundActivities;
21806            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21807                    "Item " + Integer.toHexString(System.identityHashCode(item))
21808                    + " " + app.toShortString() + ": changes=" + item.changes
21809                    + " foreground=" + item.foregroundActivities
21810                    + " type=" + app.adjType + " source=" + app.adjSource
21811                    + " target=" + app.adjTarget);
21812        }
21813
21814        return success;
21815    }
21816
21817    private boolean isEphemeralLocked(int uid) {
21818        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
21819        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
21820            return false;
21821        }
21822        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
21823                packages[0]);
21824    }
21825
21826    @VisibleForTesting
21827    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
21828        final UidRecord.ChangeItem pendingChange;
21829        if (uidRec == null || uidRec.pendingChange == null) {
21830            if (mPendingUidChanges.size() == 0) {
21831                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21832                        "*** Enqueueing dispatch uid changed!");
21833                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
21834            }
21835            final int NA = mAvailUidChanges.size();
21836            if (NA > 0) {
21837                pendingChange = mAvailUidChanges.remove(NA-1);
21838                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21839                        "Retrieving available item: " + pendingChange);
21840            } else {
21841                pendingChange = new UidRecord.ChangeItem();
21842                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21843                        "Allocating new item: " + pendingChange);
21844            }
21845            if (uidRec != null) {
21846                uidRec.pendingChange = pendingChange;
21847                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
21848                    // If this uid is going away, and we haven't yet reported it is gone,
21849                    // then do so now.
21850                    change = UidRecord.CHANGE_GONE_IDLE;
21851                }
21852            } else if (uid < 0) {
21853                throw new IllegalArgumentException("No UidRecord or uid");
21854            }
21855            pendingChange.uidRecord = uidRec;
21856            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
21857            mPendingUidChanges.add(pendingChange);
21858        } else {
21859            pendingChange = uidRec.pendingChange;
21860            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
21861                change = UidRecord.CHANGE_GONE_IDLE;
21862            }
21863        }
21864        pendingChange.change = change;
21865        pendingChange.processState = uidRec != null
21866                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
21867        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
21868        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
21869        if (uidRec != null) {
21870            uidRec.updateLastDispatchedProcStateSeq(change);
21871        }
21872
21873        // Directly update the power manager, since we sit on top of it and it is critical
21874        // it be kept in sync (so wake locks will be held as soon as appropriate).
21875        if (mLocalPowerManager != null) {
21876            switch (change) {
21877                case UidRecord.CHANGE_GONE:
21878                case UidRecord.CHANGE_GONE_IDLE:
21879                    mLocalPowerManager.uidGone(pendingChange.uid);
21880                    break;
21881                case UidRecord.CHANGE_IDLE:
21882                    mLocalPowerManager.uidIdle(pendingChange.uid);
21883                    break;
21884                case UidRecord.CHANGE_ACTIVE:
21885                    mLocalPowerManager.uidActive(pendingChange.uid);
21886                    break;
21887                default:
21888                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
21889                            pendingChange.processState);
21890                    break;
21891            }
21892        }
21893    }
21894
21895    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
21896            String authority) {
21897        if (app == null) return;
21898        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21899            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
21900            if (userState == null) return;
21901            final long now = SystemClock.elapsedRealtime();
21902            Long lastReported = userState.mProviderLastReportedFg.get(authority);
21903            if (lastReported == null || lastReported < now - 60 * 1000L) {
21904                if (mSystemReady) {
21905                    // Cannot touch the user stats if not system ready
21906                    mUsageStatsService.reportContentProviderUsage(
21907                            authority, providerPkgName, app.userId);
21908                }
21909                userState.mProviderLastReportedFg.put(authority, now);
21910            }
21911        }
21912    }
21913
21914    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
21915        if (DEBUG_USAGE_STATS) {
21916            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
21917                    + "] state changes: old = " + app.setProcState + ", new = "
21918                    + app.curProcState);
21919        }
21920        if (mUsageStatsService == null) {
21921            return;
21922        }
21923        boolean isInteraction;
21924        // To avoid some abuse patterns, we are going to be careful about what we consider
21925        // to be an app interaction.  Being the top activity doesn't count while the display
21926        // is sleeping, nor do short foreground services.
21927        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
21928            isInteraction = true;
21929            app.fgInteractionTime = 0;
21930        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
21931            if (app.fgInteractionTime == 0) {
21932                app.fgInteractionTime = nowElapsed;
21933                isInteraction = false;
21934            } else {
21935                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
21936            }
21937        } else {
21938            // If the app was being forced to the foreground, by say a Toast, then
21939            // no need to treat it as an interaction
21940            isInteraction = app.forcingToForeground == null
21941                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21942            app.fgInteractionTime = 0;
21943        }
21944        if (isInteraction && (!app.reportedInteraction
21945                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
21946            app.interactionEventTime = nowElapsed;
21947            String[] packages = app.getPackageList();
21948            if (packages != null) {
21949                for (int i = 0; i < packages.length; i++) {
21950                    mUsageStatsService.reportEvent(packages[i], app.userId,
21951                            UsageEvents.Event.SYSTEM_INTERACTION);
21952                }
21953            }
21954        }
21955        app.reportedInteraction = isInteraction;
21956        if (!isInteraction) {
21957            app.interactionEventTime = 0;
21958        }
21959    }
21960
21961    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
21962        if (proc.thread != null) {
21963            if (proc.baseProcessTracker != null) {
21964                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
21965            }
21966        }
21967    }
21968
21969    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
21970            ProcessRecord TOP_APP, boolean doingAll, long now) {
21971        if (app.thread == null) {
21972            return false;
21973        }
21974
21975        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
21976
21977        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
21978    }
21979
21980    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
21981            boolean oomAdj) {
21982        if (isForeground != proc.foregroundServices) {
21983            proc.foregroundServices = isForeground;
21984            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
21985                    proc.info.uid);
21986            if (isForeground) {
21987                if (curProcs == null) {
21988                    curProcs = new ArrayList<ProcessRecord>();
21989                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
21990                }
21991                if (!curProcs.contains(proc)) {
21992                    curProcs.add(proc);
21993                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
21994                            proc.info.packageName, proc.info.uid);
21995                }
21996            } else {
21997                if (curProcs != null) {
21998                    if (curProcs.remove(proc)) {
21999                        mBatteryStatsService.noteEvent(
22000                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22001                                proc.info.packageName, proc.info.uid);
22002                        if (curProcs.size() <= 0) {
22003                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22004                        }
22005                    }
22006                }
22007            }
22008            if (oomAdj) {
22009                updateOomAdjLocked();
22010            }
22011        }
22012    }
22013
22014    private final ActivityRecord resumedAppLocked() {
22015        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22016        String pkg;
22017        int uid;
22018        if (act != null) {
22019            pkg = act.packageName;
22020            uid = act.info.applicationInfo.uid;
22021        } else {
22022            pkg = null;
22023            uid = -1;
22024        }
22025        // Has the UID or resumed package name changed?
22026        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22027                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22028            if (mCurResumedPackage != null) {
22029                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22030                        mCurResumedPackage, mCurResumedUid);
22031            }
22032            mCurResumedPackage = pkg;
22033            mCurResumedUid = uid;
22034            if (mCurResumedPackage != null) {
22035                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22036                        mCurResumedPackage, mCurResumedUid);
22037            }
22038        }
22039        return act;
22040    }
22041
22042    final boolean updateOomAdjLocked(ProcessRecord app) {
22043        final ActivityRecord TOP_ACT = resumedAppLocked();
22044        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22045        final boolean wasCached = app.cached;
22046
22047        mAdjSeq++;
22048
22049        // This is the desired cached adjusment we want to tell it to use.
22050        // If our app is currently cached, we know it, and that is it.  Otherwise,
22051        // we don't know it yet, and it needs to now be cached we will then
22052        // need to do a complete oom adj.
22053        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22054                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22055        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22056                SystemClock.uptimeMillis());
22057        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
22058            // Changed to/from cached state, so apps after it in the LRU
22059            // list may also be changed.
22060            updateOomAdjLocked();
22061        }
22062        return success;
22063    }
22064
22065    final void updateOomAdjLocked() {
22066        final ActivityRecord TOP_ACT = resumedAppLocked();
22067        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22068        final long now = SystemClock.uptimeMillis();
22069        final long nowElapsed = SystemClock.elapsedRealtime();
22070        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22071        final int N = mLruProcesses.size();
22072
22073        if (false) {
22074            RuntimeException e = new RuntimeException();
22075            e.fillInStackTrace();
22076            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22077        }
22078
22079        // Reset state in all uid records.
22080        for (int i=mActiveUids.size()-1; i>=0; i--) {
22081            final UidRecord uidRec = mActiveUids.valueAt(i);
22082            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22083                    "Starting update of " + uidRec);
22084            uidRec.reset();
22085        }
22086
22087        mStackSupervisor.rankTaskLayersIfNeeded();
22088
22089        mAdjSeq++;
22090        mNewNumServiceProcs = 0;
22091        mNewNumAServiceProcs = 0;
22092
22093        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22094        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22095
22096        // Let's determine how many processes we have running vs.
22097        // how many slots we have for background processes; we may want
22098        // to put multiple processes in a slot of there are enough of
22099        // them.
22100        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22101                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22102        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22103        if (numEmptyProcs > cachedProcessLimit) {
22104            // If there are more empty processes than our limit on cached
22105            // processes, then use the cached process limit for the factor.
22106            // This ensures that the really old empty processes get pushed
22107            // down to the bottom, so if we are running low on memory we will
22108            // have a better chance at keeping around more cached processes
22109            // instead of a gazillion empty processes.
22110            numEmptyProcs = cachedProcessLimit;
22111        }
22112        int emptyFactor = numEmptyProcs/numSlots;
22113        if (emptyFactor < 1) emptyFactor = 1;
22114        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22115        if (cachedFactor < 1) cachedFactor = 1;
22116        int stepCached = 0;
22117        int stepEmpty = 0;
22118        int numCached = 0;
22119        int numEmpty = 0;
22120        int numTrimming = 0;
22121
22122        mNumNonCachedProcs = 0;
22123        mNumCachedHiddenProcs = 0;
22124
22125        // First update the OOM adjustment for each of the
22126        // application processes based on their current state.
22127        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22128        int nextCachedAdj = curCachedAdj+1;
22129        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22130        int nextEmptyAdj = curEmptyAdj+2;
22131        for (int i=N-1; i>=0; i--) {
22132            ProcessRecord app = mLruProcesses.get(i);
22133            if (!app.killedByAm && app.thread != null) {
22134                app.procStateChanged = false;
22135                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22136
22137                // If we haven't yet assigned the final cached adj
22138                // to the process, do that now.
22139                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22140                    switch (app.curProcState) {
22141                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22142                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22143                            // This process is a cached process holding activities...
22144                            // assign it the next cached value for that type, and then
22145                            // step that cached level.
22146                            app.curRawAdj = curCachedAdj;
22147                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22148                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22149                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22150                                    + ")");
22151                            if (curCachedAdj != nextCachedAdj) {
22152                                stepCached++;
22153                                if (stepCached >= cachedFactor) {
22154                                    stepCached = 0;
22155                                    curCachedAdj = nextCachedAdj;
22156                                    nextCachedAdj += 2;
22157                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22158                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22159                                    }
22160                                }
22161                            }
22162                            break;
22163                        default:
22164                            // For everything else, assign next empty cached process
22165                            // level and bump that up.  Note that this means that
22166                            // long-running services that have dropped down to the
22167                            // cached level will be treated as empty (since their process
22168                            // state is still as a service), which is what we want.
22169                            app.curRawAdj = curEmptyAdj;
22170                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22171                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22172                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22173                                    + ")");
22174                            if (curEmptyAdj != nextEmptyAdj) {
22175                                stepEmpty++;
22176                                if (stepEmpty >= emptyFactor) {
22177                                    stepEmpty = 0;
22178                                    curEmptyAdj = nextEmptyAdj;
22179                                    nextEmptyAdj += 2;
22180                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22181                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22182                                    }
22183                                }
22184                            }
22185                            break;
22186                    }
22187                }
22188
22189                applyOomAdjLocked(app, true, now, nowElapsed);
22190
22191                // Count the number of process types.
22192                switch (app.curProcState) {
22193                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22194                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22195                        mNumCachedHiddenProcs++;
22196                        numCached++;
22197                        if (numCached > cachedProcessLimit) {
22198                            app.kill("cached #" + numCached, true);
22199                        }
22200                        break;
22201                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22202                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22203                                && app.lastActivityTime < oldTime) {
22204                            app.kill("empty for "
22205                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22206                                    / 1000) + "s", true);
22207                        } else {
22208                            numEmpty++;
22209                            if (numEmpty > emptyProcessLimit) {
22210                                app.kill("empty #" + numEmpty, true);
22211                            }
22212                        }
22213                        break;
22214                    default:
22215                        mNumNonCachedProcs++;
22216                        break;
22217                }
22218
22219                if (app.isolated && app.services.size() <= 0) {
22220                    // If this is an isolated process, and there are no
22221                    // services running in it, then the process is no longer
22222                    // needed.  We agressively kill these because we can by
22223                    // definition not re-use the same process again, and it is
22224                    // good to avoid having whatever code was running in them
22225                    // left sitting around after no longer needed.
22226                    app.kill("isolated not needed", true);
22227                } else {
22228                    // Keeping this process, update its uid.
22229                    final UidRecord uidRec = app.uidRecord;
22230                    if (uidRec != null) {
22231                        uidRec.ephemeral = app.info.isInstantApp();
22232                        if (uidRec.curProcState > app.curProcState) {
22233                            uidRec.curProcState = app.curProcState;
22234                        }
22235                    }
22236                }
22237
22238                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22239                        && !app.killedByAm) {
22240                    numTrimming++;
22241                }
22242            }
22243        }
22244
22245        incrementProcStateSeqAndNotifyAppsLocked();
22246
22247        mNumServiceProcs = mNewNumServiceProcs;
22248
22249        // Now determine the memory trimming level of background processes.
22250        // Unfortunately we need to start at the back of the list to do this
22251        // properly.  We only do this if the number of background apps we
22252        // are managing to keep around is less than half the maximum we desire;
22253        // if we are keeping a good number around, we'll let them use whatever
22254        // memory they want.
22255        final int numCachedAndEmpty = numCached + numEmpty;
22256        int memFactor;
22257        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22258                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22259            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22260                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22261            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22262                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22263            } else {
22264                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22265            }
22266        } else {
22267            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22268        }
22269        // We always allow the memory level to go up (better).  We only allow it to go
22270        // down if we are in a state where that is allowed, *and* the total number of processes
22271        // has gone down since last time.
22272        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22273                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22274                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22275        if (memFactor > mLastMemoryLevel) {
22276            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22277                memFactor = mLastMemoryLevel;
22278                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22279            }
22280        }
22281        if (memFactor != mLastMemoryLevel) {
22282            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22283        }
22284        mLastMemoryLevel = memFactor;
22285        mLastNumProcesses = mLruProcesses.size();
22286        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22287        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22288        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22289            if (mLowRamStartTime == 0) {
22290                mLowRamStartTime = now;
22291            }
22292            int step = 0;
22293            int fgTrimLevel;
22294            switch (memFactor) {
22295                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22296                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22297                    break;
22298                case ProcessStats.ADJ_MEM_FACTOR_LOW:
22299                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22300                    break;
22301                default:
22302                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22303                    break;
22304            }
22305            int factor = numTrimming/3;
22306            int minFactor = 2;
22307            if (mHomeProcess != null) minFactor++;
22308            if (mPreviousProcess != null) minFactor++;
22309            if (factor < minFactor) factor = minFactor;
22310            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22311            for (int i=N-1; i>=0; i--) {
22312                ProcessRecord app = mLruProcesses.get(i);
22313                if (allChanged || app.procStateChanged) {
22314                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22315                    app.procStateChanged = false;
22316                }
22317                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22318                        && !app.killedByAm) {
22319                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
22320                        try {
22321                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22322                                    "Trimming memory of " + app.processName + " to " + curLevel);
22323                            app.thread.scheduleTrimMemory(curLevel);
22324                        } catch (RemoteException e) {
22325                        }
22326                        if (false) {
22327                            // For now we won't do this; our memory trimming seems
22328                            // to be good enough at this point that destroying
22329                            // activities causes more harm than good.
22330                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22331                                    && app != mHomeProcess && app != mPreviousProcess) {
22332                                // Need to do this on its own message because the stack may not
22333                                // be in a consistent state at this point.
22334                                // For these apps we will also finish their activities
22335                                // to help them free memory.
22336                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22337                            }
22338                        }
22339                    }
22340                    app.trimMemoryLevel = curLevel;
22341                    step++;
22342                    if (step >= factor) {
22343                        step = 0;
22344                        switch (curLevel) {
22345                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22346                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22347                                break;
22348                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22349                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22350                                break;
22351                        }
22352                    }
22353                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22354                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22355                            && app.thread != null) {
22356                        try {
22357                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22358                                    "Trimming memory of heavy-weight " + app.processName
22359                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22360                            app.thread.scheduleTrimMemory(
22361                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22362                        } catch (RemoteException e) {
22363                        }
22364                    }
22365                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22366                } else {
22367                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22368                            || app.systemNoUi) && app.pendingUiClean) {
22369                        // If this application is now in the background and it
22370                        // had done UI, then give it the special trim level to
22371                        // have it free UI resources.
22372                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22373                        if (app.trimMemoryLevel < level && app.thread != null) {
22374                            try {
22375                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22376                                        "Trimming memory of bg-ui " + app.processName
22377                                        + " to " + level);
22378                                app.thread.scheduleTrimMemory(level);
22379                            } catch (RemoteException e) {
22380                            }
22381                        }
22382                        app.pendingUiClean = false;
22383                    }
22384                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22385                        try {
22386                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22387                                    "Trimming memory of fg " + app.processName
22388                                    + " to " + fgTrimLevel);
22389                            app.thread.scheduleTrimMemory(fgTrimLevel);
22390                        } catch (RemoteException e) {
22391                        }
22392                    }
22393                    app.trimMemoryLevel = fgTrimLevel;
22394                }
22395            }
22396        } else {
22397            if (mLowRamStartTime != 0) {
22398                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22399                mLowRamStartTime = 0;
22400            }
22401            for (int i=N-1; i>=0; i--) {
22402                ProcessRecord app = mLruProcesses.get(i);
22403                if (allChanged || app.procStateChanged) {
22404                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22405                    app.procStateChanged = false;
22406                }
22407                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22408                        || app.systemNoUi) && app.pendingUiClean) {
22409                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22410                            && app.thread != null) {
22411                        try {
22412                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22413                                    "Trimming memory of ui hidden " + app.processName
22414                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22415                            app.thread.scheduleTrimMemory(
22416                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22417                        } catch (RemoteException e) {
22418                        }
22419                    }
22420                    app.pendingUiClean = false;
22421                }
22422                app.trimMemoryLevel = 0;
22423            }
22424        }
22425
22426        if (mAlwaysFinishActivities) {
22427            // Need to do this on its own message because the stack may not
22428            // be in a consistent state at this point.
22429            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22430        }
22431
22432        if (allChanged) {
22433            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22434        }
22435
22436        // Update from any uid changes.
22437        if (mLocalPowerManager != null) {
22438            mLocalPowerManager.startUidChanges();
22439        }
22440        for (int i=mActiveUids.size()-1; i>=0; i--) {
22441            final UidRecord uidRec = mActiveUids.valueAt(i);
22442            int uidChange = UidRecord.CHANGE_PROCSTATE;
22443            if (uidRec.setProcState != uidRec.curProcState
22444                    || uidRec.setWhitelist != uidRec.curWhitelist) {
22445                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22446                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22447                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22448                        + " to " + uidRec.curWhitelist);
22449                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22450                        && !uidRec.curWhitelist) {
22451                    // UID is now in the background (and not on the temp whitelist).  Was it
22452                    // previously in the foreground (or on the temp whitelist)?
22453                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22454                            || uidRec.setWhitelist) {
22455                        uidRec.lastBackgroundTime = nowElapsed;
22456                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22457                            // Note: the background settle time is in elapsed realtime, while
22458                            // the handler time base is uptime.  All this means is that we may
22459                            // stop background uids later than we had intended, but that only
22460                            // happens because the device was sleeping so we are okay anyway.
22461                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
22462                        }
22463                    }
22464                } else {
22465                    if (uidRec.idle) {
22466                        uidChange = UidRecord.CHANGE_ACTIVE;
22467                        uidRec.idle = false;
22468                    }
22469                    uidRec.lastBackgroundTime = 0;
22470                }
22471                uidRec.setProcState = uidRec.curProcState;
22472                uidRec.setWhitelist = uidRec.curWhitelist;
22473                enqueueUidChangeLocked(uidRec, -1, uidChange);
22474                noteUidProcessState(uidRec.uid, uidRec.curProcState);
22475            }
22476        }
22477        if (mLocalPowerManager != null) {
22478            mLocalPowerManager.finishUidChanges();
22479        }
22480
22481        if (mProcessStats.shouldWriteNowLocked(now)) {
22482            mHandler.post(new Runnable() {
22483                @Override public void run() {
22484                    synchronized (ActivityManagerService.this) {
22485                        mProcessStats.writeStateAsyncLocked();
22486                    }
22487                }
22488            });
22489        }
22490
22491        if (DEBUG_OOM_ADJ) {
22492            final long duration = SystemClock.uptimeMillis() - now;
22493            if (false) {
22494                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22495                        new RuntimeException("here").fillInStackTrace());
22496            } else {
22497                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22498            }
22499        }
22500    }
22501
22502    @Override
22503    public void makePackageIdle(String packageName, int userId) {
22504        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22505                != PackageManager.PERMISSION_GRANTED) {
22506            String msg = "Permission Denial: makePackageIdle() from pid="
22507                    + Binder.getCallingPid()
22508                    + ", uid=" + Binder.getCallingUid()
22509                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22510            Slog.w(TAG, msg);
22511            throw new SecurityException(msg);
22512        }
22513        final int callingPid = Binder.getCallingPid();
22514        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22515                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22516        long callingId = Binder.clearCallingIdentity();
22517        synchronized(this) {
22518            try {
22519                IPackageManager pm = AppGlobals.getPackageManager();
22520                int pkgUid = -1;
22521                try {
22522                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22523                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22524                } catch (RemoteException e) {
22525                }
22526                if (pkgUid == -1) {
22527                    throw new IllegalArgumentException("Unknown package name " + packageName);
22528                }
22529
22530                if (mLocalPowerManager != null) {
22531                    mLocalPowerManager.startUidChanges();
22532                }
22533                final int appId = UserHandle.getAppId(pkgUid);
22534                final int N = mActiveUids.size();
22535                for (int i=N-1; i>=0; i--) {
22536                    final UidRecord uidRec = mActiveUids.valueAt(i);
22537                    final long bgTime = uidRec.lastBackgroundTime;
22538                    if (bgTime > 0 && !uidRec.idle) {
22539                        if (UserHandle.getAppId(uidRec.uid) == appId) {
22540                            if (userId == UserHandle.USER_ALL ||
22541                                    userId == UserHandle.getUserId(uidRec.uid)) {
22542                                uidRec.idle = true;
22543                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22544                                        + " from package " + packageName + " user " + userId);
22545                                doStopUidLocked(uidRec.uid, uidRec);
22546                            }
22547                        }
22548                    }
22549                }
22550            } finally {
22551                if (mLocalPowerManager != null) {
22552                    mLocalPowerManager.finishUidChanges();
22553                }
22554                Binder.restoreCallingIdentity(callingId);
22555            }
22556        }
22557    }
22558
22559    final void idleUids() {
22560        synchronized (this) {
22561            final int N = mActiveUids.size();
22562            if (N <= 0) {
22563                return;
22564            }
22565            final long nowElapsed = SystemClock.elapsedRealtime();
22566            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
22567            long nextTime = 0;
22568            if (mLocalPowerManager != null) {
22569                mLocalPowerManager.startUidChanges();
22570            }
22571            for (int i=N-1; i>=0; i--) {
22572                final UidRecord uidRec = mActiveUids.valueAt(i);
22573                final long bgTime = uidRec.lastBackgroundTime;
22574                if (bgTime > 0 && !uidRec.idle) {
22575                    if (bgTime <= maxBgTime) {
22576                        uidRec.idle = true;
22577                        doStopUidLocked(uidRec.uid, uidRec);
22578                    } else {
22579                        if (nextTime == 0 || nextTime > bgTime) {
22580                            nextTime = bgTime;
22581                        }
22582                    }
22583                }
22584            }
22585            if (mLocalPowerManager != null) {
22586                mLocalPowerManager.finishUidChanges();
22587            }
22588            if (nextTime > 0) {
22589                mHandler.removeMessages(IDLE_UIDS_MSG);
22590                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22591                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
22592            }
22593        }
22594    }
22595
22596    /**
22597     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
22598     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
22599     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
22600     */
22601    @VisibleForTesting
22602    @GuardedBy("this")
22603    void incrementProcStateSeqAndNotifyAppsLocked() {
22604        if (mWaitForNetworkTimeoutMs <= 0) {
22605            return;
22606        }
22607        // Used for identifying which uids need to block for network.
22608        ArrayList<Integer> blockingUids = null;
22609        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
22610            final UidRecord uidRec = mActiveUids.valueAt(i);
22611            // If the network is not restricted for uid, then nothing to do here.
22612            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
22613                continue;
22614            }
22615            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
22616                continue;
22617            }
22618            // If process state is not changed, then there's nothing to do.
22619            if (uidRec.setProcState == uidRec.curProcState) {
22620                continue;
22621            }
22622            final int blockState = getBlockStateForUid(uidRec);
22623            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
22624            // there's nothing the app needs to do in this scenario.
22625            if (blockState == NETWORK_STATE_NO_CHANGE) {
22626                continue;
22627            }
22628            synchronized (uidRec.networkStateLock) {
22629                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
22630                if (blockState == NETWORK_STATE_BLOCK) {
22631                    if (blockingUids == null) {
22632                        blockingUids = new ArrayList<>();
22633                    }
22634                    blockingUids.add(uidRec.uid);
22635                } else {
22636                    if (DEBUG_NETWORK) {
22637                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
22638                                + " threads for uid: " + uidRec);
22639                    }
22640                    if (uidRec.waitingForNetwork) {
22641                        uidRec.networkStateLock.notifyAll();
22642                    }
22643                }
22644            }
22645        }
22646
22647        // There are no uids that need to block, so nothing more to do.
22648        if (blockingUids == null) {
22649            return;
22650        }
22651
22652        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
22653            final ProcessRecord app = mLruProcesses.get(i);
22654            if (!blockingUids.contains(app.uid)) {
22655                continue;
22656            }
22657            if (!app.killedByAm && app.thread != null) {
22658                final UidRecord uidRec = mActiveUids.get(app.uid);
22659                try {
22660                    if (DEBUG_NETWORK) {
22661                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
22662                                + uidRec);
22663                    }
22664                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
22665                } catch (RemoteException ignored) {
22666                }
22667            }
22668        }
22669    }
22670
22671    /**
22672     * Checks if the uid is coming from background to foreground or vice versa and returns
22673     * appropriate block state based on this.
22674     *
22675     * @return blockState based on whether the uid is coming from background to foreground or
22676     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
22677     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
22678     *         {@link #NETWORK_STATE_NO_CHANGE}.
22679     */
22680    @VisibleForTesting
22681    int getBlockStateForUid(UidRecord uidRec) {
22682        // Denotes whether uid's process state is currently allowed network access.
22683        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
22684                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
22685        // Denotes whether uid's process state was previously allowed network access.
22686        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
22687                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
22688
22689        // When the uid is coming to foreground, AMS should inform the app thread that it should
22690        // block for the network rules to get updated before launching an activity.
22691        if (!wasAllowed && isAllowed) {
22692            return NETWORK_STATE_BLOCK;
22693        }
22694        // When the uid is going to background, AMS should inform the app thread that if an
22695        // activity launch is blocked for the network rules to get updated, it should be unblocked.
22696        if (wasAllowed && !isAllowed) {
22697            return NETWORK_STATE_UNBLOCK;
22698        }
22699        return NETWORK_STATE_NO_CHANGE;
22700    }
22701
22702    final void runInBackgroundDisabled(int uid) {
22703        synchronized (this) {
22704            UidRecord uidRec = mActiveUids.get(uid);
22705            if (uidRec != null) {
22706                // This uid is actually running...  should it be considered background now?
22707                if (uidRec.idle) {
22708                    doStopUidLocked(uidRec.uid, uidRec);
22709                }
22710            } else {
22711                // This uid isn't actually running...  still send a report about it being "stopped".
22712                doStopUidLocked(uid, null);
22713            }
22714        }
22715    }
22716
22717    final void doStopUidLocked(int uid, final UidRecord uidRec) {
22718        mServices.stopInBackgroundLocked(uid);
22719        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
22720    }
22721
22722    /**
22723     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
22724     */
22725    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
22726            long duration, String tag) {
22727        if (DEBUG_WHITELISTS) {
22728            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
22729                    + targetUid + ", " + duration + ")");
22730        }
22731
22732        synchronized (mPidsSelfLocked) {
22733            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
22734            if (pr == null) {
22735                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
22736                        + callerPid);
22737                return;
22738            }
22739            if (!pr.whitelistManager) {
22740                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
22741                        != PackageManager.PERMISSION_GRANTED) {
22742                    if (DEBUG_WHITELISTS) {
22743                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
22744                                + ": pid " + callerPid + " is not allowed");
22745                    }
22746                    return;
22747                }
22748            }
22749        }
22750
22751        tempWhitelistUidLocked(targetUid, duration, tag);
22752    }
22753
22754    /**
22755     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
22756     */
22757    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
22758        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
22759        setUidTempWhitelistStateLocked(targetUid, true);
22760        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
22761    }
22762
22763    void pushTempWhitelist() {
22764        final int N;
22765        final PendingTempWhitelist[] list;
22766
22767        // First copy out the pending changes...  we need to leave them in the map for now,
22768        // in case someone needs to check what is coming up while we don't have the lock held.
22769        synchronized(this) {
22770            N = mPendingTempWhitelist.size();
22771            list = new PendingTempWhitelist[N];
22772            for (int i = 0; i < N; i++) {
22773                list[i] = mPendingTempWhitelist.valueAt(i);
22774            }
22775        }
22776
22777        // Now safely dispatch changes to device idle controller.
22778        for (int i = 0; i < N; i++) {
22779            PendingTempWhitelist ptw = list[i];
22780            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
22781                    ptw.duration, true, ptw.tag);
22782        }
22783
22784        // And now we can safely remove them from the map.
22785        synchronized(this) {
22786            for (int i = 0; i < N; i++) {
22787                PendingTempWhitelist ptw = list[i];
22788                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
22789                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
22790                    mPendingTempWhitelist.removeAt(index);
22791                }
22792            }
22793        }
22794    }
22795
22796    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
22797        boolean changed = false;
22798        for (int i=mActiveUids.size()-1; i>=0; i--) {
22799            final UidRecord uidRec = mActiveUids.valueAt(i);
22800            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
22801                uidRec.curWhitelist = onWhitelist;
22802                changed = true;
22803            }
22804        }
22805        if (changed) {
22806            updateOomAdjLocked();
22807        }
22808    }
22809
22810    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
22811        boolean changed = false;
22812        final UidRecord uidRec = mActiveUids.get(uid);
22813        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
22814            uidRec.curWhitelist = onWhitelist;
22815            updateOomAdjLocked();
22816        }
22817    }
22818
22819    final void trimApplications() {
22820        synchronized (this) {
22821            int i;
22822
22823            // First remove any unused application processes whose package
22824            // has been removed.
22825            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
22826                final ProcessRecord app = mRemovedProcesses.get(i);
22827                if (app.activities.size() == 0
22828                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
22829                    Slog.i(
22830                        TAG, "Exiting empty application process "
22831                        + app.toShortString() + " ("
22832                        + (app.thread != null ? app.thread.asBinder() : null)
22833                        + ")\n");
22834                    if (app.pid > 0 && app.pid != MY_PID) {
22835                        app.kill("empty", false);
22836                    } else {
22837                        try {
22838                            app.thread.scheduleExit();
22839                        } catch (Exception e) {
22840                            // Ignore exceptions.
22841                        }
22842                    }
22843                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
22844                    mRemovedProcesses.remove(i);
22845
22846                    if (app.persistent) {
22847                        addAppLocked(app.info, null, false, null /* ABI override */);
22848                    }
22849                }
22850            }
22851
22852            // Now update the oom adj for all processes.
22853            updateOomAdjLocked();
22854        }
22855    }
22856
22857    /** This method sends the specified signal to each of the persistent apps */
22858    public void signalPersistentProcesses(int sig) throws RemoteException {
22859        if (sig != SIGNAL_USR1) {
22860            throw new SecurityException("Only SIGNAL_USR1 is allowed");
22861        }
22862
22863        synchronized (this) {
22864            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
22865                    != PackageManager.PERMISSION_GRANTED) {
22866                throw new SecurityException("Requires permission "
22867                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
22868            }
22869
22870            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
22871                ProcessRecord r = mLruProcesses.get(i);
22872                if (r.thread != null && r.persistent) {
22873                    sendSignal(r.pid, sig);
22874                }
22875            }
22876        }
22877    }
22878
22879    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
22880        if (proc == null || proc == mProfileProc) {
22881            proc = mProfileProc;
22882            profileType = mProfileType;
22883            clearProfilerLocked();
22884        }
22885        if (proc == null) {
22886            return;
22887        }
22888        try {
22889            proc.thread.profilerControl(false, null, profileType);
22890        } catch (RemoteException e) {
22891            throw new IllegalStateException("Process disappeared");
22892        }
22893    }
22894
22895    private void clearProfilerLocked() {
22896        if (mProfileFd != null) {
22897            try {
22898                mProfileFd.close();
22899            } catch (IOException e) {
22900            }
22901        }
22902        mProfileApp = null;
22903        mProfileProc = null;
22904        mProfileFile = null;
22905        mProfileType = 0;
22906        mAutoStopProfiler = false;
22907        mStreamingOutput = false;
22908        mSamplingInterval = 0;
22909    }
22910
22911    public boolean profileControl(String process, int userId, boolean start,
22912            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
22913
22914        try {
22915            synchronized (this) {
22916                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
22917                // its own permission.
22918                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22919                        != PackageManager.PERMISSION_GRANTED) {
22920                    throw new SecurityException("Requires permission "
22921                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22922                }
22923
22924                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
22925                    throw new IllegalArgumentException("null profile info or fd");
22926                }
22927
22928                ProcessRecord proc = null;
22929                if (process != null) {
22930                    proc = findProcessLocked(process, userId, "profileControl");
22931                }
22932
22933                if (start && (proc == null || proc.thread == null)) {
22934                    throw new IllegalArgumentException("Unknown process: " + process);
22935                }
22936
22937                if (start) {
22938                    stopProfilerLocked(null, 0);
22939                    setProfileApp(proc.info, proc.processName, profilerInfo);
22940                    mProfileProc = proc;
22941                    mProfileType = profileType;
22942                    ParcelFileDescriptor fd = profilerInfo.profileFd;
22943                    try {
22944                        fd = fd.dup();
22945                    } catch (IOException e) {
22946                        fd = null;
22947                    }
22948                    profilerInfo.profileFd = fd;
22949                    proc.thread.profilerControl(start, profilerInfo, profileType);
22950                    fd = null;
22951                    try {
22952                        mProfileFd.close();
22953                    } catch (IOException e) {
22954                    }
22955                    mProfileFd = null;
22956                } else {
22957                    stopProfilerLocked(proc, profileType);
22958                    if (profilerInfo != null && profilerInfo.profileFd != null) {
22959                        try {
22960                            profilerInfo.profileFd.close();
22961                        } catch (IOException e) {
22962                        }
22963                    }
22964                }
22965
22966                return true;
22967            }
22968        } catch (RemoteException e) {
22969            throw new IllegalStateException("Process disappeared");
22970        } finally {
22971            if (profilerInfo != null && profilerInfo.profileFd != null) {
22972                try {
22973                    profilerInfo.profileFd.close();
22974                } catch (IOException e) {
22975                }
22976            }
22977        }
22978    }
22979
22980    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
22981        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22982                userId, true, ALLOW_FULL_ONLY, callName, null);
22983        ProcessRecord proc = null;
22984        try {
22985            int pid = Integer.parseInt(process);
22986            synchronized (mPidsSelfLocked) {
22987                proc = mPidsSelfLocked.get(pid);
22988            }
22989        } catch (NumberFormatException e) {
22990        }
22991
22992        if (proc == null) {
22993            ArrayMap<String, SparseArray<ProcessRecord>> all
22994                    = mProcessNames.getMap();
22995            SparseArray<ProcessRecord> procs = all.get(process);
22996            if (procs != null && procs.size() > 0) {
22997                proc = procs.valueAt(0);
22998                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
22999                    for (int i=1; i<procs.size(); i++) {
23000                        ProcessRecord thisProc = procs.valueAt(i);
23001                        if (thisProc.userId == userId) {
23002                            proc = thisProc;
23003                            break;
23004                        }
23005                    }
23006                }
23007            }
23008        }
23009
23010        return proc;
23011    }
23012
23013    public boolean dumpHeap(String process, int userId, boolean managed,
23014            String path, ParcelFileDescriptor fd) throws RemoteException {
23015
23016        try {
23017            synchronized (this) {
23018                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23019                // its own permission (same as profileControl).
23020                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23021                        != PackageManager.PERMISSION_GRANTED) {
23022                    throw new SecurityException("Requires permission "
23023                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23024                }
23025
23026                if (fd == null) {
23027                    throw new IllegalArgumentException("null fd");
23028                }
23029
23030                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23031                if (proc == null || proc.thread == null) {
23032                    throw new IllegalArgumentException("Unknown process: " + process);
23033                }
23034
23035                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23036                if (!isDebuggable) {
23037                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23038                        throw new SecurityException("Process not debuggable: " + proc);
23039                    }
23040                }
23041
23042                proc.thread.dumpHeap(managed, path, fd);
23043                fd = null;
23044                return true;
23045            }
23046        } catch (RemoteException e) {
23047            throw new IllegalStateException("Process disappeared");
23048        } finally {
23049            if (fd != null) {
23050                try {
23051                    fd.close();
23052                } catch (IOException e) {
23053                }
23054            }
23055        }
23056    }
23057
23058    @Override
23059    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23060            String reportPackage) {
23061        if (processName != null) {
23062            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23063                    "setDumpHeapDebugLimit()");
23064        } else {
23065            synchronized (mPidsSelfLocked) {
23066                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23067                if (proc == null) {
23068                    throw new SecurityException("No process found for calling pid "
23069                            + Binder.getCallingPid());
23070                }
23071                if (!Build.IS_DEBUGGABLE
23072                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23073                    throw new SecurityException("Not running a debuggable build");
23074                }
23075                processName = proc.processName;
23076                uid = proc.uid;
23077                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23078                    throw new SecurityException("Package " + reportPackage + " is not running in "
23079                            + proc);
23080                }
23081            }
23082        }
23083        synchronized (this) {
23084            if (maxMemSize > 0) {
23085                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23086            } else {
23087                if (uid != 0) {
23088                    mMemWatchProcesses.remove(processName, uid);
23089                } else {
23090                    mMemWatchProcesses.getMap().remove(processName);
23091                }
23092            }
23093        }
23094    }
23095
23096    @Override
23097    public void dumpHeapFinished(String path) {
23098        synchronized (this) {
23099            if (Binder.getCallingPid() != mMemWatchDumpPid) {
23100                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23101                        + " does not match last pid " + mMemWatchDumpPid);
23102                return;
23103            }
23104            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23105                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23106                        + " does not match last path " + mMemWatchDumpFile);
23107                return;
23108            }
23109            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23110            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23111        }
23112    }
23113
23114    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23115    public void monitor() {
23116        synchronized (this) { }
23117    }
23118
23119    void onCoreSettingsChange(Bundle settings) {
23120        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23121            ProcessRecord processRecord = mLruProcesses.get(i);
23122            try {
23123                if (processRecord.thread != null) {
23124                    processRecord.thread.setCoreSettings(settings);
23125                }
23126            } catch (RemoteException re) {
23127                /* ignore */
23128            }
23129        }
23130    }
23131
23132    // Multi-user methods
23133
23134    /**
23135     * Start user, if its not already running, but don't bring it to foreground.
23136     */
23137    @Override
23138    public boolean startUserInBackground(final int userId) {
23139        return mUserController.startUser(userId, /* foreground */ false);
23140    }
23141
23142    @Override
23143    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23144        return mUserController.unlockUser(userId, token, secret, listener);
23145    }
23146
23147    @Override
23148    public boolean switchUser(final int targetUserId) {
23149        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23150        int currentUserId;
23151        UserInfo targetUserInfo;
23152        synchronized (this) {
23153            currentUserId = mUserController.getCurrentUserIdLocked();
23154            targetUserInfo = mUserController.getUserInfo(targetUserId);
23155            if (targetUserId == currentUserId) {
23156                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23157                return true;
23158            }
23159            if (targetUserInfo == null) {
23160                Slog.w(TAG, "No user info for user #" + targetUserId);
23161                return false;
23162            }
23163            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23164                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23165                        + " when device is in demo mode");
23166                return false;
23167            }
23168            if (!targetUserInfo.supportsSwitchTo()) {
23169                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23170                return false;
23171            }
23172            if (targetUserInfo.isManagedProfile()) {
23173                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23174                return false;
23175            }
23176            mUserController.setTargetUserIdLocked(targetUserId);
23177        }
23178        if (mUserController.mUserSwitchUiEnabled) {
23179            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23180            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23181            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23182            mUiHandler.sendMessage(mHandler.obtainMessage(
23183                    START_USER_SWITCH_UI_MSG, userNames));
23184        } else {
23185            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23186            mHandler.sendMessage(mHandler.obtainMessage(
23187                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
23188        }
23189        return true;
23190    }
23191
23192    void scheduleStartProfilesLocked() {
23193        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23194            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23195                    DateUtils.SECOND_IN_MILLIS);
23196        }
23197    }
23198
23199    @Override
23200    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23201        return mUserController.stopUser(userId, force, callback);
23202    }
23203
23204    @Override
23205    public UserInfo getCurrentUser() {
23206        return mUserController.getCurrentUser();
23207    }
23208
23209    String getStartedUserState(int userId) {
23210        synchronized (this) {
23211            final UserState userState = mUserController.getStartedUserStateLocked(userId);
23212            return UserState.stateToString(userState.state);
23213        }
23214    }
23215
23216    @Override
23217    public boolean isUserRunning(int userId, int flags) {
23218        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23219                && checkCallingPermission(INTERACT_ACROSS_USERS)
23220                    != PackageManager.PERMISSION_GRANTED) {
23221            String msg = "Permission Denial: isUserRunning() from pid="
23222                    + Binder.getCallingPid()
23223                    + ", uid=" + Binder.getCallingUid()
23224                    + " requires " + INTERACT_ACROSS_USERS;
23225            Slog.w(TAG, msg);
23226            throw new SecurityException(msg);
23227        }
23228        synchronized (this) {
23229            return mUserController.isUserRunningLocked(userId, flags);
23230        }
23231    }
23232
23233    @Override
23234    public int[] getRunningUserIds() {
23235        if (checkCallingPermission(INTERACT_ACROSS_USERS)
23236                != PackageManager.PERMISSION_GRANTED) {
23237            String msg = "Permission Denial: isUserRunning() from pid="
23238                    + Binder.getCallingPid()
23239                    + ", uid=" + Binder.getCallingUid()
23240                    + " requires " + INTERACT_ACROSS_USERS;
23241            Slog.w(TAG, msg);
23242            throw new SecurityException(msg);
23243        }
23244        synchronized (this) {
23245            return mUserController.getStartedUserArrayLocked();
23246        }
23247    }
23248
23249    @Override
23250    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23251        mUserController.registerUserSwitchObserver(observer, name);
23252    }
23253
23254    @Override
23255    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23256        mUserController.unregisterUserSwitchObserver(observer);
23257    }
23258
23259    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23260        if (info == null) return null;
23261        ApplicationInfo newInfo = new ApplicationInfo(info);
23262        newInfo.initForUser(userId);
23263        return newInfo;
23264    }
23265
23266    public boolean isUserStopped(int userId) {
23267        synchronized (this) {
23268            return mUserController.getStartedUserStateLocked(userId) == null;
23269        }
23270    }
23271
23272    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23273        if (aInfo == null
23274                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23275            return aInfo;
23276        }
23277
23278        ActivityInfo info = new ActivityInfo(aInfo);
23279        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23280        return info;
23281    }
23282
23283    private boolean processSanityChecksLocked(ProcessRecord process) {
23284        if (process == null || process.thread == null) {
23285            return false;
23286        }
23287
23288        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23289        if (!isDebuggable) {
23290            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23291                return false;
23292            }
23293        }
23294
23295        return true;
23296    }
23297
23298    public boolean startBinderTracking() throws RemoteException {
23299        synchronized (this) {
23300            mBinderTransactionTrackingEnabled = true;
23301            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23302            // permission (same as profileControl).
23303            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23304                    != PackageManager.PERMISSION_GRANTED) {
23305                throw new SecurityException("Requires permission "
23306                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23307            }
23308
23309            for (int i = 0; i < mLruProcesses.size(); i++) {
23310                ProcessRecord process = mLruProcesses.get(i);
23311                if (!processSanityChecksLocked(process)) {
23312                    continue;
23313                }
23314                try {
23315                    process.thread.startBinderTracking();
23316                } catch (RemoteException e) {
23317                    Log.v(TAG, "Process disappared");
23318                }
23319            }
23320            return true;
23321        }
23322    }
23323
23324    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23325        try {
23326            synchronized (this) {
23327                mBinderTransactionTrackingEnabled = false;
23328                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23329                // permission (same as profileControl).
23330                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23331                        != PackageManager.PERMISSION_GRANTED) {
23332                    throw new SecurityException("Requires permission "
23333                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23334                }
23335
23336                if (fd == null) {
23337                    throw new IllegalArgumentException("null fd");
23338                }
23339
23340                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23341                pw.println("Binder transaction traces for all processes.\n");
23342                for (ProcessRecord process : mLruProcesses) {
23343                    if (!processSanityChecksLocked(process)) {
23344                        continue;
23345                    }
23346
23347                    pw.println("Traces for process: " + process.processName);
23348                    pw.flush();
23349                    try {
23350                        TransferPipe tp = new TransferPipe();
23351                        try {
23352                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23353                            tp.go(fd.getFileDescriptor());
23354                        } finally {
23355                            tp.kill();
23356                        }
23357                    } catch (IOException e) {
23358                        pw.println("Failure while dumping IPC traces from " + process +
23359                                ".  Exception: " + e);
23360                        pw.flush();
23361                    } catch (RemoteException e) {
23362                        pw.println("Got a RemoteException while dumping IPC traces from " +
23363                                process + ".  Exception: " + e);
23364                        pw.flush();
23365                    }
23366                }
23367                fd = null;
23368                return true;
23369            }
23370        } finally {
23371            if (fd != null) {
23372                try {
23373                    fd.close();
23374                } catch (IOException e) {
23375                }
23376            }
23377        }
23378    }
23379
23380    @VisibleForTesting
23381    final class LocalService extends ActivityManagerInternal {
23382        @Override
23383        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23384                int targetUserId) {
23385            synchronized (ActivityManagerService.this) {
23386                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23387                        targetPkg, intent, null, targetUserId);
23388            }
23389        }
23390
23391        @Override
23392        public String checkContentProviderAccess(String authority, int userId) {
23393            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23394        }
23395
23396        @Override
23397        public void onWakefulnessChanged(int wakefulness) {
23398            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23399        }
23400
23401        @Override
23402        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23403                String processName, String abiOverride, int uid, Runnable crashHandler) {
23404            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23405                    processName, abiOverride, uid, crashHandler);
23406        }
23407
23408        @Override
23409        public SleepToken acquireSleepToken(String tag) {
23410            Preconditions.checkNotNull(tag);
23411
23412            synchronized (ActivityManagerService.this) {
23413                SleepTokenImpl token = new SleepTokenImpl(tag);
23414                mSleepTokens.add(token);
23415                updateSleepIfNeededLocked();
23416                return token;
23417            }
23418        }
23419
23420        @Override
23421        public ComponentName getHomeActivityForUser(int userId) {
23422            synchronized (ActivityManagerService.this) {
23423                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23424                return homeActivity == null ? null : homeActivity.realActivity;
23425            }
23426        }
23427
23428        @Override
23429        public void onUserRemoved(int userId) {
23430            synchronized (ActivityManagerService.this) {
23431                ActivityManagerService.this.onUserStoppedLocked(userId);
23432            }
23433        }
23434
23435        @Override
23436        public void onLocalVoiceInteractionStarted(IBinder activity,
23437                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23438            synchronized (ActivityManagerService.this) {
23439                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23440                        voiceSession, voiceInteractor);
23441            }
23442        }
23443
23444        @Override
23445        public void notifyAppTransitionStarting(SparseIntArray reasons) {
23446            synchronized (ActivityManagerService.this) {
23447                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reasons);
23448            }
23449        }
23450
23451        @Override
23452        public void notifyAppTransitionFinished() {
23453            synchronized (ActivityManagerService.this) {
23454                mStackSupervisor.notifyAppTransitionDone();
23455            }
23456        }
23457
23458        @Override
23459        public void notifyAppTransitionCancelled() {
23460            synchronized (ActivityManagerService.this) {
23461                mStackSupervisor.notifyAppTransitionDone();
23462            }
23463        }
23464
23465        @Override
23466        public List<IBinder> getTopVisibleActivities() {
23467            synchronized (ActivityManagerService.this) {
23468                return mStackSupervisor.getTopVisibleActivities();
23469            }
23470        }
23471
23472        @Override
23473        public void notifyDockedStackMinimizedChanged(boolean minimized) {
23474            synchronized (ActivityManagerService.this) {
23475                mStackSupervisor.setDockedStackMinimized(minimized);
23476            }
23477        }
23478
23479        @Override
23480        public void killForegroundAppsForUser(int userHandle) {
23481            synchronized (ActivityManagerService.this) {
23482                final ArrayList<ProcessRecord> procs = new ArrayList<>();
23483                final int NP = mProcessNames.getMap().size();
23484                for (int ip = 0; ip < NP; ip++) {
23485                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23486                    final int NA = apps.size();
23487                    for (int ia = 0; ia < NA; ia++) {
23488                        final ProcessRecord app = apps.valueAt(ia);
23489                        if (app.persistent) {
23490                            // We don't kill persistent processes.
23491                            continue;
23492                        }
23493                        if (app.removed) {
23494                            procs.add(app);
23495                        } else if (app.userId == userHandle && app.foregroundActivities) {
23496                            app.removed = true;
23497                            procs.add(app);
23498                        }
23499                    }
23500                }
23501
23502                final int N = procs.size();
23503                for (int i = 0; i < N; i++) {
23504                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
23505                }
23506            }
23507        }
23508
23509        @Override
23510        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
23511            if (!(target instanceof PendingIntentRecord)) {
23512                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23513                return;
23514            }
23515            ((PendingIntentRecord) target).setWhitelistDurationLocked(duration);
23516        }
23517
23518        @Override
23519        public void setDeviceIdleWhitelist(int[] appids) {
23520            synchronized (ActivityManagerService.this) {
23521                mDeviceIdleWhitelist = appids;
23522            }
23523        }
23524
23525        @Override
23526        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23527            synchronized (ActivityManagerService.this) {
23528                mDeviceIdleTempWhitelist = appids;
23529                setAppIdTempWhitelistStateLocked(changingAppId, adding);
23530            }
23531        }
23532
23533        @Override
23534        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23535                int userId) {
23536            Preconditions.checkNotNull(values, "Configuration must not be null");
23537            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23538            synchronized (ActivityManagerService.this) {
23539                updateConfigurationLocked(values, null, false, true, userId,
23540                        false /* deferResume */);
23541            }
23542        }
23543
23544        @Override
23545        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23546                Bundle bOptions) {
23547            Preconditions.checkNotNull(intents, "intents");
23548            final String[] resolvedTypes = new String[intents.length];
23549            for (int i = 0; i < intents.length; i++) {
23550                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23551            }
23552
23553            // UID of the package on user userId.
23554            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23555            // packageUid may not be initialized.
23556            int packageUid = 0;
23557            try {
23558                packageUid = AppGlobals.getPackageManager().getPackageUid(
23559                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23560            } catch (RemoteException e) {
23561                // Shouldn't happen.
23562            }
23563
23564            synchronized (ActivityManagerService.this) {
23565                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23566                        /*resultTo*/ null, bOptions, userId);
23567            }
23568        }
23569
23570        @Override
23571        public int getUidProcessState(int uid) {
23572            return getUidState(uid);
23573        }
23574
23575        @Override
23576        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23577            synchronized (ActivityManagerService.this) {
23578
23579                // We might change the visibilities here, so prepare an empty app transition which
23580                // might be overridden later if we actually change visibilities.
23581                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
23582                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23583                mWindowManager.executeAppTransition();
23584            }
23585            if (callback != null) {
23586                callback.run();
23587            }
23588        }
23589
23590        @Override
23591        public boolean isSystemReady() {
23592            // no need to synchronize(this) just to read & return the value
23593            return mSystemReady;
23594        }
23595
23596        @Override
23597        public void notifyKeyguardTrustedChanged() {
23598            synchronized (ActivityManagerService.this) {
23599                if (mKeyguardController.isKeyguardShowing()) {
23600                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23601                }
23602            }
23603        }
23604
23605        /**
23606         * Sets if the given pid has an overlay UI or not.
23607         *
23608         * @param pid The pid we are setting overlay UI for.
23609         * @param hasOverlayUi True if the process has overlay UI.
23610         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
23611         */
23612        @Override
23613        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
23614            synchronized (ActivityManagerService.this) {
23615                final ProcessRecord pr;
23616                synchronized (mPidsSelfLocked) {
23617                    pr = mPidsSelfLocked.get(pid);
23618                    if (pr == null) {
23619                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
23620                        return;
23621                    }
23622                }
23623                if (pr.hasOverlayUi == hasOverlayUi) {
23624                    return;
23625                }
23626                pr.hasOverlayUi = hasOverlayUi;
23627                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
23628                updateOomAdjLocked(pr);
23629            }
23630        }
23631
23632        /**
23633         * Called after the network policy rules are updated by
23634         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
23635         * and {@param procStateSeq}.
23636         */
23637        @Override
23638        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
23639            if (DEBUG_NETWORK) {
23640                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
23641                        + uid + " seq: " + procStateSeq);
23642            }
23643            UidRecord record;
23644            synchronized (ActivityManagerService.this) {
23645                record = mActiveUids.get(uid);
23646                if (record == null) {
23647                    if (DEBUG_NETWORK) {
23648                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
23649                                + " procStateSeq: " + procStateSeq);
23650                    }
23651                    return;
23652                }
23653            }
23654            synchronized (record.networkStateLock) {
23655                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23656                    if (DEBUG_NETWORK) {
23657                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
23658                                + " been handled for uid: " + uid);
23659                    }
23660                    return;
23661                }
23662                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
23663                if (record.curProcStateSeq > procStateSeq) {
23664                    if (DEBUG_NETWORK) {
23665                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
23666                                + ", curProcstateSeq: " + record.curProcStateSeq
23667                                + ", procStateSeq: " + procStateSeq);
23668                    }
23669                    return;
23670                }
23671                if (record.waitingForNetwork) {
23672                    if (DEBUG_NETWORK) {
23673                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
23674                                + ", procStateSeq: " + procStateSeq);
23675                    }
23676                    record.networkStateLock.notifyAll();
23677                }
23678            }
23679        }
23680
23681        /**
23682         * Called after virtual display Id is updated by
23683         * {@link com.android.server.vr.CompatibilityDisplay} with a specific
23684         * {@param vrCompatibilityDisplayId}.
23685         */
23686        @Override
23687        public void setVrCompatibilityDisplayId(int vrCompatibilityDisplayId) {
23688            if (DEBUG_STACK) {
23689                Slog.d(TAG, "setVrCompatibilityDisplayId called for: " +
23690                        vrCompatibilityDisplayId);
23691            }
23692            synchronized (ActivityManagerService.this) {
23693                mVrCompatibilityDisplayId = vrCompatibilityDisplayId;
23694            }
23695        }
23696    }
23697
23698    /**
23699     * Called by app main thread to wait for the network policy rules to get udpated.
23700     *
23701     * @param procStateSeq The sequence number indicating the process state change that the main
23702     *                     thread is interested in.
23703     */
23704    @Override
23705    public void waitForNetworkStateUpdate(long procStateSeq) {
23706        final int callingUid = Binder.getCallingUid();
23707        if (DEBUG_NETWORK) {
23708            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
23709        }
23710        UidRecord record;
23711        synchronized (this) {
23712            record = mActiveUids.get(callingUid);
23713            if (record == null) {
23714                return;
23715            }
23716        }
23717        synchronized (record.networkStateLock) {
23718            if (record.lastDispatchedProcStateSeq < procStateSeq) {
23719                if (DEBUG_NETWORK) {
23720                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
23721                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
23722                            + " lastProcStateSeqDispatchedToObservers: "
23723                            + record.lastDispatchedProcStateSeq);
23724                }
23725                return;
23726            }
23727            if (record.curProcStateSeq > procStateSeq) {
23728                if (DEBUG_NETWORK) {
23729                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
23730                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
23731                            + ", procStateSeq: " + procStateSeq);
23732                }
23733                return;
23734            }
23735            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23736                if (DEBUG_NETWORK) {
23737                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
23738                            + procStateSeq + ", so no need to wait. Uid: "
23739                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
23740                            + record.lastNetworkUpdatedProcStateSeq);
23741                }
23742                return;
23743            }
23744            try {
23745                if (DEBUG_NETWORK) {
23746                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
23747                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
23748                }
23749                final long startTime = SystemClock.uptimeMillis();
23750                record.waitingForNetwork = true;
23751                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
23752                record.waitingForNetwork = false;
23753                final long totalTime = SystemClock.uptimeMillis() - startTime;
23754                if (totalTime >= mWaitForNetworkTimeoutMs) {
23755                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
23756                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
23757                            + procStateSeq);
23758                } else if (DEBUG_NETWORK ||  totalTime >= mWaitForNetworkTimeoutMs / 2) {
23759                    Slog.d(TAG_NETWORK, "Total time waited for network rules to get updated: "
23760                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
23761                            + procStateSeq);
23762                }
23763            } catch (InterruptedException e) {
23764                Thread.currentThread().interrupt();
23765            }
23766        }
23767    }
23768
23769    /**
23770     * Return the user id of the last resumed activity.
23771     */
23772    @Override
23773    public @UserIdInt int getLastResumedActivityUserId() {
23774        enforceCallingPermission(
23775                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
23776        synchronized (this) {
23777            if (mLastResumedActivity == null) {
23778                return mUserController.getCurrentUserIdLocked();
23779            }
23780            return mLastResumedActivity.userId;
23781        }
23782    }
23783
23784    private final class SleepTokenImpl extends SleepToken {
23785        private final String mTag;
23786        private final long mAcquireTime;
23787
23788        public SleepTokenImpl(String tag) {
23789            mTag = tag;
23790            mAcquireTime = SystemClock.uptimeMillis();
23791        }
23792
23793        @Override
23794        public void release() {
23795            synchronized (ActivityManagerService.this) {
23796                if (mSleepTokens.remove(this)) {
23797                    updateSleepIfNeededLocked();
23798                }
23799            }
23800        }
23801
23802        @Override
23803        public String toString() {
23804            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
23805        }
23806    }
23807
23808    /**
23809     * An implementation of IAppTask, that allows an app to manage its own tasks via
23810     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
23811     * only the process that calls getAppTasks() can call the AppTask methods.
23812     */
23813    class AppTaskImpl extends IAppTask.Stub {
23814        private int mTaskId;
23815        private int mCallingUid;
23816
23817        public AppTaskImpl(int taskId, int callingUid) {
23818            mTaskId = taskId;
23819            mCallingUid = callingUid;
23820        }
23821
23822        private void checkCaller() {
23823            if (mCallingUid != Binder.getCallingUid()) {
23824                throw new SecurityException("Caller " + mCallingUid
23825                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
23826            }
23827        }
23828
23829        @Override
23830        public void finishAndRemoveTask() {
23831            checkCaller();
23832
23833            synchronized (ActivityManagerService.this) {
23834                long origId = Binder.clearCallingIdentity();
23835                try {
23836                    // We remove the task from recents to preserve backwards
23837                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
23838                            REMOVE_FROM_RECENTS)) {
23839                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23840                    }
23841                } finally {
23842                    Binder.restoreCallingIdentity(origId);
23843                }
23844            }
23845        }
23846
23847        @Override
23848        public ActivityManager.RecentTaskInfo getTaskInfo() {
23849            checkCaller();
23850
23851            synchronized (ActivityManagerService.this) {
23852                long origId = Binder.clearCallingIdentity();
23853                try {
23854                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23855                    if (tr == null) {
23856                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23857                    }
23858                    return createRecentTaskInfoFromTaskRecord(tr);
23859                } finally {
23860                    Binder.restoreCallingIdentity(origId);
23861                }
23862            }
23863        }
23864
23865        @Override
23866        public void moveToFront() {
23867            checkCaller();
23868            // Will bring task to front if it already has a root activity.
23869            final long origId = Binder.clearCallingIdentity();
23870            try {
23871                synchronized (this) {
23872                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
23873                }
23874            } finally {
23875                Binder.restoreCallingIdentity(origId);
23876            }
23877        }
23878
23879        @Override
23880        public int startActivity(IBinder whoThread, String callingPackage,
23881                Intent intent, String resolvedType, Bundle bOptions) {
23882            checkCaller();
23883
23884            int callingUser = UserHandle.getCallingUserId();
23885            TaskRecord tr;
23886            IApplicationThread appThread;
23887            synchronized (ActivityManagerService.this) {
23888                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23889                if (tr == null) {
23890                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23891                }
23892                appThread = IApplicationThread.Stub.asInterface(whoThread);
23893                if (appThread == null) {
23894                    throw new IllegalArgumentException("Bad app thread " + appThread);
23895                }
23896            }
23897            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
23898                    resolvedType, null, null, null, null, 0, 0, null, null,
23899                    null, bOptions, false, callingUser, null, tr);
23900        }
23901
23902        @Override
23903        public void setExcludeFromRecents(boolean exclude) {
23904            checkCaller();
23905
23906            synchronized (ActivityManagerService.this) {
23907                long origId = Binder.clearCallingIdentity();
23908                try {
23909                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23910                    if (tr == null) {
23911                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23912                    }
23913                    Intent intent = tr.getBaseIntent();
23914                    if (exclude) {
23915                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23916                    } else {
23917                        intent.setFlags(intent.getFlags()
23918                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23919                    }
23920                } finally {
23921                    Binder.restoreCallingIdentity(origId);
23922                }
23923            }
23924        }
23925    }
23926
23927    /**
23928     * Kill processes for the user with id userId and that depend on the package named packageName
23929     */
23930    @Override
23931    public void killPackageDependents(String packageName, int userId) {
23932        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
23933        if (packageName == null) {
23934            throw new NullPointerException(
23935                    "Cannot kill the dependents of a package without its name.");
23936        }
23937
23938        long callingId = Binder.clearCallingIdentity();
23939        IPackageManager pm = AppGlobals.getPackageManager();
23940        int pkgUid = -1;
23941        try {
23942            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
23943        } catch (RemoteException e) {
23944        }
23945        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
23946            throw new IllegalArgumentException(
23947                    "Cannot kill dependents of non-existing package " + packageName);
23948        }
23949        try {
23950            synchronized(this) {
23951                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
23952                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
23953                        "dep: " + packageName);
23954            }
23955        } finally {
23956            Binder.restoreCallingIdentity(callingId);
23957        }
23958    }
23959
23960    @Override
23961    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
23962            throws RemoteException {
23963        final long callingId = Binder.clearCallingIdentity();
23964        try {
23965            mKeyguardController.dismissKeyguard(token, callback);
23966        } finally {
23967            Binder.restoreCallingIdentity(callingId);
23968        }
23969    }
23970
23971    @Override
23972    public int restartUserInBackground(final int userId) {
23973        return mUserController.restartUser(userId, /* foreground */ false);
23974    }
23975
23976    @Override
23977    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
23978        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
23979                "scheduleApplicationInfoChanged()");
23980
23981        synchronized (this) {
23982            final long origId = Binder.clearCallingIdentity();
23983            try {
23984                updateApplicationInfoLocked(packageNames, userId);
23985            } finally {
23986                Binder.restoreCallingIdentity(origId);
23987            }
23988        }
23989    }
23990
23991    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
23992        final PackageManagerInternal packageManager = getPackageManagerInternalLocked();
23993        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
23994        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23995            final ProcessRecord app = mLruProcesses.get(i);
23996            if (app.thread == null) {
23997                continue;
23998            }
23999
24000            if (userId != UserHandle.USER_ALL && app.userId != userId) {
24001                continue;
24002            }
24003
24004            final int packageCount = app.pkgList.size();
24005            for (int j = 0; j < packageCount; j++) {
24006                final String packageName = app.pkgList.keyAt(j);
24007                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24008                    try {
24009                        final ApplicationInfo ai = packageManager.getApplicationInfo(
24010                                packageName, app.userId);
24011                        if (ai != null) {
24012                            app.thread.scheduleApplicationInfoChanged(ai);
24013                        }
24014                    } catch (RemoteException e) {
24015                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24016                                    packageName, app));
24017                    }
24018                }
24019            }
24020        }
24021    }
24022
24023    /**
24024     * Attach an agent to the specified process (proces name or PID)
24025     */
24026    public void attachAgent(String process, String path) {
24027        try {
24028            synchronized (this) {
24029                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24030                if (proc == null || proc.thread == null) {
24031                    throw new IllegalArgumentException("Unknown process: " + process);
24032                }
24033
24034                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24035                if (!isDebuggable) {
24036                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24037                        throw new SecurityException("Process not debuggable: " + proc);
24038                    }
24039                }
24040
24041                proc.thread.attachAgent(path);
24042            }
24043        } catch (RemoteException e) {
24044            throw new IllegalStateException("Process disappeared");
24045        }
24046    }
24047
24048    @VisibleForTesting
24049    public static class Injector {
24050        private NetworkManagementInternal mNmi;
24051
24052        public Context getContext() {
24053            return null;
24054        }
24055
24056        public AppOpsService getAppOpsService(File file, Handler handler) {
24057            return new AppOpsService(file, handler);
24058        }
24059
24060        public Handler getUiHandler(ActivityManagerService service) {
24061            return service.new UiHandler();
24062        }
24063
24064        public boolean isNetworkRestrictedForUid(int uid) {
24065            if (ensureHasNetworkManagementInternal()) {
24066                return mNmi.isNetworkRestrictedForUid(uid);
24067            }
24068            return false;
24069        }
24070
24071        private boolean ensureHasNetworkManagementInternal() {
24072            if (mNmi == null) {
24073                mNmi = LocalServices.getService(NetworkManagementInternal.class);
24074            }
24075            return mNmi != null;
24076        }
24077    }
24078}
24079