ActivityManagerService.java revision 6d6015f652f1b7bca129a22b1bd256b990e3ca28
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 START_USER_SWITCH_FG_MSG = 712;
1707
1708    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1709    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1710    static final int FIRST_COMPAT_MODE_MSG = 300;
1711    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1712
1713    static ServiceThread sKillThread = null;
1714    static KillHandler sKillHandler = null;
1715
1716    CompatModeDialog mCompatModeDialog;
1717    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1718    long mLastMemUsageReportTime = 0;
1719
1720    /**
1721     * Flag whether the current user is a "monkey", i.e. whether
1722     * the UI is driven by a UI automation tool.
1723     */
1724    private boolean mUserIsMonkey;
1725
1726    /** Flag whether the device has a Recents UI */
1727    boolean mHasRecents;
1728
1729    /** The dimensions of the thumbnails in the Recents UI. */
1730    int mThumbnailWidth;
1731    int mThumbnailHeight;
1732    float mFullscreenThumbnailScale;
1733
1734    final ServiceThread mHandlerThread;
1735    final MainHandler mHandler;
1736    final Handler mUiHandler;
1737
1738    final ActivityManagerConstants mConstants;
1739
1740    PackageManagerInternal mPackageManagerInt;
1741
1742    // VoiceInteraction session ID that changes for each new request except when
1743    // being called for multiwindow assist in a single session.
1744    private int mViSessionId = 1000;
1745
1746    final boolean mPermissionReviewRequired;
1747
1748    /**
1749     * Current global configuration information. Contains general settings for the entire system,
1750     * also corresponds to the merged configuration of the default display.
1751     */
1752    Configuration getGlobalConfiguration() {
1753        return mStackSupervisor.getConfiguration();
1754    }
1755
1756    final class KillHandler extends Handler {
1757        static final int KILL_PROCESS_GROUP_MSG = 4000;
1758
1759        public KillHandler(Looper looper) {
1760            super(looper, null, true);
1761        }
1762
1763        @Override
1764        public void handleMessage(Message msg) {
1765            switch (msg.what) {
1766                case KILL_PROCESS_GROUP_MSG:
1767                {
1768                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1769                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1770                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1771                }
1772                break;
1773
1774                default:
1775                    super.handleMessage(msg);
1776            }
1777        }
1778    }
1779
1780    final class UiHandler extends Handler {
1781        public UiHandler() {
1782            super(com.android.server.UiThread.get().getLooper(), null, true);
1783        }
1784
1785        @Override
1786        public void handleMessage(Message msg) {
1787            switch (msg.what) {
1788            case SHOW_ERROR_UI_MSG: {
1789                mAppErrors.handleShowAppErrorUi(msg);
1790                ensureBootCompleted();
1791            } break;
1792            case SHOW_NOT_RESPONDING_UI_MSG: {
1793                mAppErrors.handleShowAnrUi(msg);
1794                ensureBootCompleted();
1795            } break;
1796            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1797                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1798                synchronized (ActivityManagerService.this) {
1799                    ProcessRecord proc = (ProcessRecord) data.get("app");
1800                    if (proc == null) {
1801                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1802                        break;
1803                    }
1804                    if (proc.crashDialog != null) {
1805                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1806                        return;
1807                    }
1808                    AppErrorResult res = (AppErrorResult) data.get("result");
1809                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1810                        Dialog d = new StrictModeViolationDialog(mContext,
1811                                ActivityManagerService.this, res, proc);
1812                        d.show();
1813                        proc.crashDialog = d;
1814                    } else {
1815                        // The device is asleep, so just pretend that the user
1816                        // saw a crash dialog and hit "force quit".
1817                        res.set(0);
1818                    }
1819                }
1820                ensureBootCompleted();
1821            } break;
1822            case SHOW_FACTORY_ERROR_UI_MSG: {
1823                Dialog d = new FactoryErrorDialog(
1824                        mUiContext, msg.getData().getCharSequence("msg"));
1825                d.show();
1826                ensureBootCompleted();
1827            } break;
1828            case WAIT_FOR_DEBUGGER_UI_MSG: {
1829                synchronized (ActivityManagerService.this) {
1830                    ProcessRecord app = (ProcessRecord)msg.obj;
1831                    if (msg.arg1 != 0) {
1832                        if (!app.waitedForDebugger) {
1833                            Dialog d = new AppWaitingForDebuggerDialog(
1834                                    ActivityManagerService.this,
1835                                    mUiContext, app);
1836                            app.waitDialog = d;
1837                            app.waitedForDebugger = true;
1838                            d.show();
1839                        }
1840                    } else {
1841                        if (app.waitDialog != null) {
1842                            app.waitDialog.dismiss();
1843                            app.waitDialog = null;
1844                        }
1845                    }
1846                }
1847            } break;
1848            case SHOW_UID_ERROR_UI_MSG: {
1849                if (mShowDialogs) {
1850                    AlertDialog d = new BaseErrorDialog(mUiContext);
1851                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1852                    d.setCancelable(false);
1853                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1854                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1855                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1856                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1857                    d.show();
1858                }
1859            } break;
1860            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1861                if (mShowDialogs) {
1862                    AlertDialog d = new BaseErrorDialog(mUiContext);
1863                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1864                    d.setCancelable(false);
1865                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1866                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1867                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1868                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1869                    d.show();
1870                }
1871            } break;
1872            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1873                synchronized (ActivityManagerService.this) {
1874                    ActivityRecord ar = (ActivityRecord) msg.obj;
1875                    if (mCompatModeDialog != null) {
1876                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1877                                ar.info.applicationInfo.packageName)) {
1878                            return;
1879                        }
1880                        mCompatModeDialog.dismiss();
1881                        mCompatModeDialog = null;
1882                    }
1883                    if (ar != null && false) {
1884                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1885                                ar.packageName)) {
1886                            int mode = mCompatModePackages.computeCompatModeLocked(
1887                                    ar.info.applicationInfo);
1888                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1889                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1890                                mCompatModeDialog = new CompatModeDialog(
1891                                        ActivityManagerService.this, mUiContext,
1892                                        ar.info.applicationInfo);
1893                                mCompatModeDialog.show();
1894                            }
1895                        }
1896                    }
1897                }
1898                break;
1899            }
1900            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1901                synchronized (ActivityManagerService.this) {
1902                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1903                    if (mUnsupportedDisplaySizeDialog != null) {
1904                        mUnsupportedDisplaySizeDialog.dismiss();
1905                        mUnsupportedDisplaySizeDialog = null;
1906                    }
1907                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1908                            ar.packageName)) {
1909                        // TODO(multi-display): Show dialog on appropriate display.
1910                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1911                                ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1912                        mUnsupportedDisplaySizeDialog.show();
1913                    }
1914                }
1915                break;
1916            }
1917            case START_USER_SWITCH_UI_MSG: {
1918                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1919                break;
1920            }
1921            case DISMISS_DIALOG_UI_MSG: {
1922                final Dialog d = (Dialog) msg.obj;
1923                d.dismiss();
1924                break;
1925            }
1926            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1927                dispatchProcessesChanged();
1928                break;
1929            }
1930            case DISPATCH_PROCESS_DIED_UI_MSG: {
1931                final int pid = msg.arg1;
1932                final int uid = msg.arg2;
1933                dispatchProcessDied(pid, uid);
1934                break;
1935            }
1936            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1937                dispatchUidsChanged();
1938            } break;
1939            case PUSH_TEMP_WHITELIST_UI_MSG: {
1940                pushTempWhitelist();
1941            } break;
1942            }
1943        }
1944    }
1945
1946    final class MainHandler extends Handler {
1947        public MainHandler(Looper looper) {
1948            super(looper, null, true);
1949        }
1950
1951        @Override
1952        public void handleMessage(Message msg) {
1953            switch (msg.what) {
1954            case UPDATE_CONFIGURATION_MSG: {
1955                final ContentResolver resolver = mContext.getContentResolver();
1956                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1957                        msg.arg1);
1958            } break;
1959            case GC_BACKGROUND_PROCESSES_MSG: {
1960                synchronized (ActivityManagerService.this) {
1961                    performAppGcsIfAppropriateLocked();
1962                }
1963            } break;
1964            case SERVICE_TIMEOUT_MSG: {
1965                if (mDidDexOpt) {
1966                    mDidDexOpt = false;
1967                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1968                    nmsg.obj = msg.obj;
1969                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1970                    return;
1971                }
1972                mServices.serviceTimeout((ProcessRecord)msg.obj);
1973            } break;
1974            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1975                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1976            } break;
1977            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1978                RemoteCallbackList<IResultReceiver> callbacks
1979                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
1980                int N = callbacks.beginBroadcast();
1981                for (int i = 0; i < N; i++) {
1982                    try {
1983                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1984                    } catch (RemoteException e) {
1985                    }
1986                }
1987                callbacks.finishBroadcast();
1988            } break;
1989            case UPDATE_TIME_ZONE: {
1990                synchronized (ActivityManagerService.this) {
1991                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1992                        ProcessRecord r = mLruProcesses.get(i);
1993                        if (r.thread != null) {
1994                            try {
1995                                r.thread.updateTimeZone();
1996                            } catch (RemoteException ex) {
1997                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1998                            }
1999                        }
2000                    }
2001                }
2002            } break;
2003            case CLEAR_DNS_CACHE_MSG: {
2004                synchronized (ActivityManagerService.this) {
2005                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2006                        ProcessRecord r = mLruProcesses.get(i);
2007                        if (r.thread != null) {
2008                            try {
2009                                r.thread.clearDnsCache();
2010                            } catch (RemoteException ex) {
2011                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2012                            }
2013                        }
2014                    }
2015                }
2016            } break;
2017            case UPDATE_HTTP_PROXY_MSG: {
2018                ProxyInfo proxy = (ProxyInfo)msg.obj;
2019                String host = "";
2020                String port = "";
2021                String exclList = "";
2022                Uri pacFileUrl = Uri.EMPTY;
2023                if (proxy != null) {
2024                    host = proxy.getHost();
2025                    port = Integer.toString(proxy.getPort());
2026                    exclList = proxy.getExclusionListAsString();
2027                    pacFileUrl = proxy.getPacFileUrl();
2028                }
2029                synchronized (ActivityManagerService.this) {
2030                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2031                        ProcessRecord r = mLruProcesses.get(i);
2032                        if (r.thread != null) {
2033                            try {
2034                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2035                            } catch (RemoteException ex) {
2036                                Slog.w(TAG, "Failed to update http proxy for: " +
2037                                        r.info.processName);
2038                            }
2039                        }
2040                    }
2041                }
2042            } break;
2043            case PROC_START_TIMEOUT_MSG: {
2044                if (mDidDexOpt) {
2045                    mDidDexOpt = false;
2046                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2047                    nmsg.obj = msg.obj;
2048                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
2049                    return;
2050                }
2051                ProcessRecord app = (ProcessRecord)msg.obj;
2052                synchronized (ActivityManagerService.this) {
2053                    processStartTimedOutLocked(app);
2054                }
2055            } break;
2056            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2057                ProcessRecord app = (ProcessRecord)msg.obj;
2058                synchronized (ActivityManagerService.this) {
2059                    processContentProviderPublishTimedOutLocked(app);
2060                }
2061            } break;
2062            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2063                synchronized (ActivityManagerService.this) {
2064                    mActivityStarter.doPendingActivityLaunchesLocked(true);
2065                }
2066            } break;
2067            case KILL_APPLICATION_MSG: {
2068                synchronized (ActivityManagerService.this) {
2069                    final int appId = msg.arg1;
2070                    final int userId = msg.arg2;
2071                    Bundle bundle = (Bundle)msg.obj;
2072                    String pkg = bundle.getString("pkg");
2073                    String reason = bundle.getString("reason");
2074                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2075                            false, userId, reason);
2076                }
2077            } break;
2078            case FINALIZE_PENDING_INTENT_MSG: {
2079                ((PendingIntentRecord)msg.obj).completeFinalize();
2080            } break;
2081            case POST_HEAVY_NOTIFICATION_MSG: {
2082                INotificationManager inm = NotificationManager.getService();
2083                if (inm == null) {
2084                    return;
2085                }
2086
2087                ActivityRecord root = (ActivityRecord)msg.obj;
2088                ProcessRecord process = root.app;
2089                if (process == null) {
2090                    return;
2091                }
2092
2093                try {
2094                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2095                    String text = mContext.getString(R.string.heavy_weight_notification,
2096                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2097                    Notification notification =
2098                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2099                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2100                            .setWhen(0)
2101                            .setOngoing(true)
2102                            .setTicker(text)
2103                            .setColor(mContext.getColor(
2104                                    com.android.internal.R.color.system_notification_accent_color))
2105                            .setContentTitle(text)
2106                            .setContentText(
2107                                    mContext.getText(R.string.heavy_weight_notification_detail))
2108                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2109                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2110                                    new UserHandle(root.userId)))
2111                            .build();
2112                    try {
2113                        int[] outId = new int[1];
2114                        inm.enqueueNotificationWithTag("android", "android", null,
2115                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2116                                notification, outId, root.userId);
2117                    } catch (RuntimeException e) {
2118                        Slog.w(ActivityManagerService.TAG,
2119                                "Error showing notification for heavy-weight app", e);
2120                    } catch (RemoteException e) {
2121                    }
2122                } catch (NameNotFoundException e) {
2123                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2124                }
2125            } break;
2126            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2127                INotificationManager inm = NotificationManager.getService();
2128                if (inm == null) {
2129                    return;
2130                }
2131                try {
2132                    inm.cancelNotificationWithTag("android", null,
2133                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2134                } catch (RuntimeException e) {
2135                    Slog.w(ActivityManagerService.TAG,
2136                            "Error canceling notification for service", e);
2137                } catch (RemoteException e) {
2138                }
2139            } break;
2140            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2141                synchronized (ActivityManagerService.this) {
2142                    checkExcessivePowerUsageLocked(true);
2143                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2144                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2145                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
2146                }
2147            } break;
2148            case REPORT_MEM_USAGE_MSG: {
2149                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2150                Thread thread = new Thread() {
2151                    @Override public void run() {
2152                        reportMemUsage(memInfos);
2153                    }
2154                };
2155                thread.start();
2156                break;
2157            }
2158            case START_USER_SWITCH_FG_MSG: {
2159                mUserController.startUserInForeground(msg.arg1);
2160                break;
2161            }
2162            case REPORT_USER_SWITCH_MSG: {
2163                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2164                break;
2165            }
2166            case CONTINUE_USER_SWITCH_MSG: {
2167                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2168                break;
2169            }
2170            case USER_SWITCH_TIMEOUT_MSG: {
2171                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2172                break;
2173            }
2174            case IMMERSIVE_MODE_LOCK_MSG: {
2175                final boolean nextState = (msg.arg1 != 0);
2176                if (mUpdateLock.isHeld() != nextState) {
2177                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2178                            "Applying new update lock state '" + nextState
2179                            + "' for " + (ActivityRecord)msg.obj);
2180                    if (nextState) {
2181                        mUpdateLock.acquire();
2182                    } else {
2183                        mUpdateLock.release();
2184                    }
2185                }
2186                break;
2187            }
2188            case PERSIST_URI_GRANTS_MSG: {
2189                writeGrantedUriPermissions();
2190                break;
2191            }
2192            case REQUEST_ALL_PSS_MSG: {
2193                synchronized (ActivityManagerService.this) {
2194                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2195                }
2196                break;
2197            }
2198            case START_PROFILES_MSG: {
2199                synchronized (ActivityManagerService.this) {
2200                    mUserController.startProfilesLocked();
2201                }
2202                break;
2203            }
2204            case UPDATE_TIME_PREFERENCE_MSG: {
2205                // The user's time format preference might have changed.
2206                // For convenience we re-use the Intent extra values.
2207                synchronized (ActivityManagerService.this) {
2208                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2209                        ProcessRecord r = mLruProcesses.get(i);
2210                        if (r.thread != null) {
2211                            try {
2212                                r.thread.updateTimePrefs(msg.arg1);
2213                            } catch (RemoteException ex) {
2214                                Slog.w(TAG, "Failed to update preferences for: "
2215                                        + r.info.processName);
2216                            }
2217                        }
2218                    }
2219                }
2220                break;
2221            }
2222            case SYSTEM_USER_START_MSG: {
2223                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2224                        Integer.toString(msg.arg1), msg.arg1);
2225                mSystemServiceManager.startUser(msg.arg1);
2226                break;
2227            }
2228            case SYSTEM_USER_UNLOCK_MSG: {
2229                final int userId = msg.arg1;
2230                mSystemServiceManager.unlockUser(userId);
2231                synchronized (ActivityManagerService.this) {
2232                    mRecentTasks.loadUserRecentsLocked(userId);
2233                }
2234                if (userId == UserHandle.USER_SYSTEM) {
2235                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2236                }
2237                installEncryptionUnawareProviders(userId);
2238                mUserController.finishUserUnlocked((UserState) msg.obj);
2239                break;
2240            }
2241            case SYSTEM_USER_CURRENT_MSG: {
2242                mBatteryStatsService.noteEvent(
2243                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2244                        Integer.toString(msg.arg2), msg.arg2);
2245                mBatteryStatsService.noteEvent(
2246                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2247                        Integer.toString(msg.arg1), msg.arg1);
2248                mSystemServiceManager.switchUser(msg.arg1);
2249                break;
2250            }
2251            case ENTER_ANIMATION_COMPLETE_MSG: {
2252                synchronized (ActivityManagerService.this) {
2253                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2254                    if (r != null && r.app != null && r.app.thread != null) {
2255                        try {
2256                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2257                        } catch (RemoteException e) {
2258                        }
2259                    }
2260                }
2261                break;
2262            }
2263            case FINISH_BOOTING_MSG: {
2264                if (msg.arg1 != 0) {
2265                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2266                    finishBooting();
2267                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2268                }
2269                if (msg.arg2 != 0) {
2270                    enableScreenAfterBoot();
2271                }
2272                break;
2273            }
2274            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2275                try {
2276                    Locale l = (Locale) msg.obj;
2277                    IBinder service = ServiceManager.getService("mount");
2278                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2279                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2280                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2281                } catch (RemoteException e) {
2282                    Log.e(TAG, "Error storing locale for decryption UI", e);
2283                }
2284                break;
2285            }
2286            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2287                final int uid = msg.arg1;
2288                final byte[] firstPacket = (byte[]) msg.obj;
2289
2290                synchronized (mPidsSelfLocked) {
2291                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2292                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2293                        if (p.uid == uid) {
2294                            try {
2295                                p.thread.notifyCleartextNetwork(firstPacket);
2296                            } catch (RemoteException ignored) {
2297                            }
2298                        }
2299                    }
2300                }
2301                break;
2302            }
2303            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2304                final String procName;
2305                final int uid;
2306                final long memLimit;
2307                final String reportPackage;
2308                synchronized (ActivityManagerService.this) {
2309                    procName = mMemWatchDumpProcName;
2310                    uid = mMemWatchDumpUid;
2311                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2312                    if (val == null) {
2313                        val = mMemWatchProcesses.get(procName, 0);
2314                    }
2315                    if (val != null) {
2316                        memLimit = val.first;
2317                        reportPackage = val.second;
2318                    } else {
2319                        memLimit = 0;
2320                        reportPackage = null;
2321                    }
2322                }
2323                if (procName == null) {
2324                    return;
2325                }
2326
2327                if (DEBUG_PSS) Slog.d(TAG_PSS,
2328                        "Showing dump heap notification from " + procName + "/" + uid);
2329
2330                INotificationManager inm = NotificationManager.getService();
2331                if (inm == null) {
2332                    return;
2333                }
2334
2335                String text = mContext.getString(R.string.dump_heap_notification, procName);
2336
2337
2338                Intent deleteIntent = new Intent();
2339                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2340                Intent intent = new Intent();
2341                intent.setClassName("android", DumpHeapActivity.class.getName());
2342                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2343                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2344                if (reportPackage != null) {
2345                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2346                }
2347                int userId = UserHandle.getUserId(uid);
2348                Notification notification =
2349                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2350                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2351                        .setWhen(0)
2352                        .setOngoing(true)
2353                        .setAutoCancel(true)
2354                        .setTicker(text)
2355                        .setColor(mContext.getColor(
2356                                com.android.internal.R.color.system_notification_accent_color))
2357                        .setContentTitle(text)
2358                        .setContentText(
2359                                mContext.getText(R.string.dump_heap_notification_detail))
2360                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2361                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2362                                new UserHandle(userId)))
2363                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2364                                deleteIntent, 0, UserHandle.SYSTEM))
2365                        .build();
2366
2367                try {
2368                    int[] outId = new int[1];
2369                    inm.enqueueNotificationWithTag("android", "android", null,
2370                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2371                            notification, outId, userId);
2372                } catch (RuntimeException e) {
2373                    Slog.w(ActivityManagerService.TAG,
2374                            "Error showing notification for dump heap", e);
2375                } catch (RemoteException e) {
2376                }
2377            } break;
2378            case DELETE_DUMPHEAP_MSG: {
2379                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2380                        null, DumpHeapActivity.JAVA_URI,
2381                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2382                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2383                        UserHandle.myUserId());
2384                synchronized (ActivityManagerService.this) {
2385                    mMemWatchDumpFile = null;
2386                    mMemWatchDumpProcName = null;
2387                    mMemWatchDumpPid = -1;
2388                    mMemWatchDumpUid = -1;
2389                }
2390            } break;
2391            case FOREGROUND_PROFILE_CHANGED_MSG: {
2392                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2393            } break;
2394            case REPORT_TIME_TRACKER_MSG: {
2395                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2396                tracker.deliverResult(mContext);
2397            } break;
2398            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2399                mUserController.dispatchUserSwitchComplete(msg.arg1);
2400            } break;
2401            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2402                mUserController.dispatchLockedBootComplete(msg.arg1);
2403            } break;
2404            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2405                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2406                try {
2407                    connection.shutdown();
2408                } catch (RemoteException e) {
2409                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2410                }
2411                // Only a UiAutomation can set this flag and now that
2412                // it is finished we make sure it is reset to its default.
2413                mUserIsMonkey = false;
2414            } break;
2415            case IDLE_UIDS_MSG: {
2416                idleUids();
2417            } break;
2418            case VR_MODE_CHANGE_MSG: {
2419                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2420                    return;
2421                }
2422                synchronized (ActivityManagerService.this) {
2423                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2424                    mWindowManager.disableNonVrUi(disableNonVrUi);
2425                    if (disableNonVrUi) {
2426                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2427                        // then remove the pinned stack.
2428                        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2429                                PINNED_STACK_ID);
2430                        if (pinnedStack != null) {
2431                            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2432                        }
2433                    }
2434                }
2435            } break;
2436            case NOTIFY_VR_SLEEPING_MSG: {
2437                notifyVrManagerOfSleepState(msg.arg1 != 0);
2438            } break;
2439            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2440                synchronized (ActivityManagerService.this) {
2441                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2442                        ProcessRecord r = mLruProcesses.get(i);
2443                        if (r.thread != null) {
2444                            try {
2445                                r.thread.handleTrustStorageUpdate();
2446                            } catch (RemoteException ex) {
2447                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2448                                        r.info.processName);
2449                            }
2450                        }
2451                    }
2452                }
2453            } break;
2454            }
2455        }
2456    };
2457
2458    static final int COLLECT_PSS_BG_MSG = 1;
2459
2460    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2461        @Override
2462        public void handleMessage(Message msg) {
2463            switch (msg.what) {
2464            case COLLECT_PSS_BG_MSG: {
2465                long start = SystemClock.uptimeMillis();
2466                MemInfoReader memInfo = null;
2467                synchronized (ActivityManagerService.this) {
2468                    if (mFullPssPending) {
2469                        mFullPssPending = false;
2470                        memInfo = new MemInfoReader();
2471                    }
2472                }
2473                if (memInfo != null) {
2474                    updateCpuStatsNow();
2475                    long nativeTotalPss = 0;
2476                    final List<ProcessCpuTracker.Stats> stats;
2477                    synchronized (mProcessCpuTracker) {
2478                        stats = mProcessCpuTracker.getStats( (st)-> {
2479                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2480                        });
2481                    }
2482                    final int N = stats.size();
2483                    for (int j = 0; j < N; j++) {
2484                        synchronized (mPidsSelfLocked) {
2485                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2486                                // This is one of our own processes; skip it.
2487                                continue;
2488                            }
2489                        }
2490                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2491                    }
2492                    memInfo.readMemInfo();
2493                    synchronized (ActivityManagerService.this) {
2494                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2495                                + (SystemClock.uptimeMillis()-start) + "ms");
2496                        final long cachedKb = memInfo.getCachedSizeKb();
2497                        final long freeKb = memInfo.getFreeSizeKb();
2498                        final long zramKb = memInfo.getZramTotalSizeKb();
2499                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2500                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2501                                kernelKb*1024, nativeTotalPss*1024);
2502                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2503                                nativeTotalPss);
2504                    }
2505                }
2506
2507                int num = 0;
2508                long[] tmp = new long[2];
2509                do {
2510                    ProcessRecord proc;
2511                    int procState;
2512                    int pid;
2513                    long lastPssTime;
2514                    synchronized (ActivityManagerService.this) {
2515                        if (mPendingPssProcesses.size() <= 0) {
2516                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2517                                    "Collected PSS of " + num + " processes in "
2518                                    + (SystemClock.uptimeMillis() - start) + "ms");
2519                            mPendingPssProcesses.clear();
2520                            return;
2521                        }
2522                        proc = mPendingPssProcesses.remove(0);
2523                        procState = proc.pssProcState;
2524                        lastPssTime = proc.lastPssTime;
2525                        if (proc.thread != null && procState == proc.setProcState
2526                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2527                                        < SystemClock.uptimeMillis()) {
2528                            pid = proc.pid;
2529                        } else {
2530                            proc = null;
2531                            pid = 0;
2532                        }
2533                    }
2534                    if (proc != null) {
2535                        long pss = Debug.getPss(pid, tmp, null);
2536                        synchronized (ActivityManagerService.this) {
2537                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2538                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2539                                num++;
2540                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2541                                        SystemClock.uptimeMillis());
2542                            }
2543                        }
2544                    }
2545                } while (true);
2546            }
2547            }
2548        }
2549    };
2550
2551    public void setSystemProcess() {
2552        try {
2553            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2554            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2555            ServiceManager.addService("meminfo", new MemBinder(this));
2556            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2557            ServiceManager.addService("dbinfo", new DbBinder(this));
2558            if (MONITOR_CPU_USAGE) {
2559                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2560            }
2561            ServiceManager.addService("permission", new PermissionController(this));
2562            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2563
2564            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2565                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2566            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2567
2568            synchronized (this) {
2569                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2570                app.persistent = true;
2571                app.pid = MY_PID;
2572                app.maxAdj = ProcessList.SYSTEM_ADJ;
2573                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2574                synchronized (mPidsSelfLocked) {
2575                    mPidsSelfLocked.put(app.pid, app);
2576                }
2577                updateLruProcessLocked(app, false, null);
2578                updateOomAdjLocked();
2579            }
2580        } catch (PackageManager.NameNotFoundException e) {
2581            throw new RuntimeException(
2582                    "Unable to find android system package", e);
2583        }
2584    }
2585
2586    public void setWindowManager(WindowManagerService wm) {
2587        mWindowManager = wm;
2588        mStackSupervisor.setWindowManager(wm);
2589        mActivityStarter.setWindowManager(wm);
2590    }
2591
2592    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2593        mUsageStatsService = usageStatsManager;
2594    }
2595
2596    public void startObservingNativeCrashes() {
2597        final NativeCrashListener ncl = new NativeCrashListener(this);
2598        ncl.start();
2599    }
2600
2601    public IAppOpsService getAppOpsService() {
2602        return mAppOpsService;
2603    }
2604
2605    static class MemBinder extends Binder {
2606        ActivityManagerService mActivityManagerService;
2607        MemBinder(ActivityManagerService activityManagerService) {
2608            mActivityManagerService = activityManagerService;
2609        }
2610
2611        @Override
2612        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2613            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2614                    "meminfo", pw)) return;
2615            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2616        }
2617    }
2618
2619    static class GraphicsBinder extends Binder {
2620        ActivityManagerService mActivityManagerService;
2621        GraphicsBinder(ActivityManagerService activityManagerService) {
2622            mActivityManagerService = activityManagerService;
2623        }
2624
2625        @Override
2626        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2627            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2628                    "gfxinfo", pw)) return;
2629            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2630        }
2631    }
2632
2633    static class DbBinder extends Binder {
2634        ActivityManagerService mActivityManagerService;
2635        DbBinder(ActivityManagerService activityManagerService) {
2636            mActivityManagerService = activityManagerService;
2637        }
2638
2639        @Override
2640        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2641            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2642                    "dbinfo", pw)) return;
2643            mActivityManagerService.dumpDbInfo(fd, pw, args);
2644        }
2645    }
2646
2647    static class CpuBinder extends Binder {
2648        ActivityManagerService mActivityManagerService;
2649        CpuBinder(ActivityManagerService activityManagerService) {
2650            mActivityManagerService = activityManagerService;
2651        }
2652
2653        @Override
2654        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2655            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2656                    "cpuinfo", pw)) return;
2657            synchronized (mActivityManagerService.mProcessCpuTracker) {
2658                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2659                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2660                        SystemClock.uptimeMillis()));
2661            }
2662        }
2663    }
2664
2665    public static final class Lifecycle extends SystemService {
2666        private final ActivityManagerService mService;
2667
2668        public Lifecycle(Context context) {
2669            super(context);
2670            mService = new ActivityManagerService(context);
2671        }
2672
2673        @Override
2674        public void onStart() {
2675            mService.start();
2676        }
2677
2678        public ActivityManagerService getService() {
2679            return mService;
2680        }
2681    }
2682
2683    @VisibleForTesting
2684    public ActivityManagerService(Injector injector) {
2685        mInjector = injector;
2686        mContext = mInjector.getContext();
2687        mUiContext = null;
2688        GL_ES_VERSION = 0;
2689        mActivityStarter = null;
2690        mAppErrors = null;
2691        mAppOpsService = mInjector.getAppOpsService(null, null);
2692        mBatteryStatsService = null;
2693        mCompatModePackages = null;
2694        mConstants = null;
2695        mGrantFile = null;
2696        mHandler = null;
2697        mHandlerThread = null;
2698        mIntentFirewall = null;
2699        mKeyguardController = null;
2700        mPermissionReviewRequired = false;
2701        mProcessCpuThread = null;
2702        mProcessStats = null;
2703        mProviderMap = null;
2704        mRecentTasks = null;
2705        mServices = null;
2706        mStackSupervisor = null;
2707        mSystemThread = null;
2708        mTaskChangeNotificationController = null;
2709        mUiHandler = injector.getUiHandler(null);
2710        mUserController = null;
2711        mVrController = null;
2712    }
2713
2714    // Note: This method is invoked on the main thread but may need to attach various
2715    // handlers to other threads.  So take care to be explicit about the looper.
2716    public ActivityManagerService(Context systemContext) {
2717        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2718        mInjector = new Injector();
2719        mContext = systemContext;
2720
2721        mFactoryTest = FactoryTest.getMode();
2722        mSystemThread = ActivityThread.currentActivityThread();
2723        mUiContext = mSystemThread.getSystemUiContext();
2724
2725        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2726
2727        mPermissionReviewRequired = mContext.getResources().getBoolean(
2728                com.android.internal.R.bool.config_permissionReviewRequired);
2729
2730        mHandlerThread = new ServiceThread(TAG,
2731                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2732        mHandlerThread.start();
2733        mHandler = new MainHandler(mHandlerThread.getLooper());
2734        mUiHandler = mInjector.getUiHandler(this);
2735
2736        mConstants = new ActivityManagerConstants(this, mHandler);
2737
2738        /* static; one-time init here */
2739        if (sKillHandler == null) {
2740            sKillThread = new ServiceThread(TAG + ":kill",
2741                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2742            sKillThread.start();
2743            sKillHandler = new KillHandler(sKillThread.getLooper());
2744        }
2745
2746        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2747                "foreground", BROADCAST_FG_TIMEOUT, false);
2748        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2749                "background", BROADCAST_BG_TIMEOUT, true);
2750        mBroadcastQueues[0] = mFgBroadcastQueue;
2751        mBroadcastQueues[1] = mBgBroadcastQueue;
2752
2753        mServices = new ActiveServices(this);
2754        mProviderMap = new ProviderMap(this);
2755        mAppErrors = new AppErrors(mUiContext, this);
2756
2757        // TODO: Move creation of battery stats service outside of activity manager service.
2758        File dataDir = Environment.getDataDirectory();
2759        File systemDir = new File(dataDir, "system");
2760        systemDir.mkdirs();
2761        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2762        mBatteryStatsService.getActiveStatistics().readLocked();
2763        mBatteryStatsService.scheduleWriteToDisk();
2764        mOnBattery = DEBUG_POWER ? true
2765                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2766        mBatteryStatsService.getActiveStatistics().setCallback(this);
2767
2768        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2769
2770        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2771        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2772                new IAppOpsCallback.Stub() {
2773                    @Override public void opChanged(int op, int uid, String packageName) {
2774                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2775                            if (mAppOpsService.checkOperation(op, uid, packageName)
2776                                    != AppOpsManager.MODE_ALLOWED) {
2777                                runInBackgroundDisabled(uid);
2778                            }
2779                        }
2780                    }
2781                });
2782
2783        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2784
2785        mUserController = new UserController(this);
2786
2787        mVrController = new VrController(this);
2788
2789        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2790            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2791
2792        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2793            mUseFifoUiScheduling = true;
2794        }
2795
2796        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2797        mTempConfig.setToDefaults();
2798        mTempConfig.setLocales(LocaleList.getDefault());
2799        mConfigurationSeq = mTempConfig.seq = 1;
2800        mStackSupervisor = createStackSupervisor();
2801        mStackSupervisor.onConfigurationChanged(mTempConfig);
2802        mKeyguardController = mStackSupervisor.mKeyguardController;
2803        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2804        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2805        mTaskChangeNotificationController =
2806                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2807        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2808        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2809
2810        mProcessCpuThread = new Thread("CpuTracker") {
2811            @Override
2812            public void run() {
2813                synchronized (mProcessCpuTracker) {
2814                    mProcessCpuInitLatch.countDown();
2815                    mProcessCpuTracker.init();
2816                }
2817                while (true) {
2818                    try {
2819                        try {
2820                            synchronized(this) {
2821                                final long now = SystemClock.uptimeMillis();
2822                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2823                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2824                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2825                                //        + ", write delay=" + nextWriteDelay);
2826                                if (nextWriteDelay < nextCpuDelay) {
2827                                    nextCpuDelay = nextWriteDelay;
2828                                }
2829                                if (nextCpuDelay > 0) {
2830                                    mProcessCpuMutexFree.set(true);
2831                                    this.wait(nextCpuDelay);
2832                                }
2833                            }
2834                        } catch (InterruptedException e) {
2835                        }
2836                        updateCpuStatsNow();
2837                    } catch (Exception e) {
2838                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2839                    }
2840                }
2841            }
2842        };
2843
2844        Watchdog.getInstance().addMonitor(this);
2845        Watchdog.getInstance().addThread(mHandler);
2846    }
2847
2848    protected ActivityStackSupervisor createStackSupervisor() {
2849        return new ActivityStackSupervisor(this, mHandler.getLooper());
2850    }
2851
2852    public void setSystemServiceManager(SystemServiceManager mgr) {
2853        mSystemServiceManager = mgr;
2854    }
2855
2856    public void setInstaller(Installer installer) {
2857        mInstaller = installer;
2858    }
2859
2860    private void start() {
2861        removeAllProcessGroups();
2862        mProcessCpuThread.start();
2863
2864        mBatteryStatsService.publish(mContext);
2865        mAppOpsService.publish(mContext);
2866        Slog.d("AppOps", "AppOpsService published");
2867        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2868        // Wait for the synchronized block started in mProcessCpuThread,
2869        // so that any other acccess to mProcessCpuTracker from main thread
2870        // will be blocked during mProcessCpuTracker initialization.
2871        try {
2872            mProcessCpuInitLatch.await();
2873        } catch (InterruptedException e) {
2874            Slog.wtf(TAG, "Interrupted wait during start", e);
2875            Thread.currentThread().interrupt();
2876            throw new IllegalStateException("Interrupted wait during start");
2877        }
2878    }
2879
2880    void onUserStoppedLocked(int userId) {
2881        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2882    }
2883
2884    public void initPowerManagement() {
2885        mStackSupervisor.initPowerManagement();
2886        mBatteryStatsService.initPowerManagement();
2887        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2888        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2889        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2890        mVoiceWakeLock.setReferenceCounted(false);
2891    }
2892
2893    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2894        if (mBackgroundLaunchBroadcasts == null) {
2895            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2896        }
2897        return mBackgroundLaunchBroadcasts;
2898    }
2899
2900    @Override
2901    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2902            throws RemoteException {
2903        if (code == SYSPROPS_TRANSACTION) {
2904            // We need to tell all apps about the system property change.
2905            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2906            synchronized(this) {
2907                final int NP = mProcessNames.getMap().size();
2908                for (int ip=0; ip<NP; ip++) {
2909                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2910                    final int NA = apps.size();
2911                    for (int ia=0; ia<NA; ia++) {
2912                        ProcessRecord app = apps.valueAt(ia);
2913                        if (app.thread != null) {
2914                            procs.add(app.thread.asBinder());
2915                        }
2916                    }
2917                }
2918            }
2919
2920            int N = procs.size();
2921            for (int i=0; i<N; i++) {
2922                Parcel data2 = Parcel.obtain();
2923                try {
2924                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2925                            Binder.FLAG_ONEWAY);
2926                } catch (RemoteException e) {
2927                }
2928                data2.recycle();
2929            }
2930        }
2931        try {
2932            return super.onTransact(code, data, reply, flags);
2933        } catch (RuntimeException e) {
2934            // The activity manager only throws security exceptions, so let's
2935            // log all others.
2936            if (!(e instanceof SecurityException)) {
2937                Slog.wtf(TAG, "Activity Manager Crash", e);
2938            }
2939            throw e;
2940        }
2941    }
2942
2943    void updateCpuStats() {
2944        final long now = SystemClock.uptimeMillis();
2945        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2946            return;
2947        }
2948        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2949            synchronized (mProcessCpuThread) {
2950                mProcessCpuThread.notify();
2951            }
2952        }
2953    }
2954
2955    void updateCpuStatsNow() {
2956        synchronized (mProcessCpuTracker) {
2957            mProcessCpuMutexFree.set(false);
2958            final long now = SystemClock.uptimeMillis();
2959            boolean haveNewCpuStats = false;
2960
2961            if (MONITOR_CPU_USAGE &&
2962                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2963                mLastCpuTime.set(now);
2964                mProcessCpuTracker.update();
2965                if (mProcessCpuTracker.hasGoodLastStats()) {
2966                    haveNewCpuStats = true;
2967                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2968                    //Slog.i(TAG, "Total CPU usage: "
2969                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2970
2971                    // Slog the cpu usage if the property is set.
2972                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2973                        int user = mProcessCpuTracker.getLastUserTime();
2974                        int system = mProcessCpuTracker.getLastSystemTime();
2975                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2976                        int irq = mProcessCpuTracker.getLastIrqTime();
2977                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2978                        int idle = mProcessCpuTracker.getLastIdleTime();
2979
2980                        int total = user + system + iowait + irq + softIrq + idle;
2981                        if (total == 0) total = 1;
2982
2983                        EventLog.writeEvent(EventLogTags.CPU,
2984                                ((user+system+iowait+irq+softIrq) * 100) / total,
2985                                (user * 100) / total,
2986                                (system * 100) / total,
2987                                (iowait * 100) / total,
2988                                (irq * 100) / total,
2989                                (softIrq * 100) / total);
2990                    }
2991                }
2992            }
2993
2994            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2995            synchronized(bstats) {
2996                synchronized(mPidsSelfLocked) {
2997                    if (haveNewCpuStats) {
2998                        if (bstats.startAddingCpuLocked()) {
2999                            int totalUTime = 0;
3000                            int totalSTime = 0;
3001                            final int N = mProcessCpuTracker.countStats();
3002                            for (int i=0; i<N; i++) {
3003                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3004                                if (!st.working) {
3005                                    continue;
3006                                }
3007                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3008                                totalUTime += st.rel_utime;
3009                                totalSTime += st.rel_stime;
3010                                if (pr != null) {
3011                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3012                                    if (ps == null || !ps.isActive()) {
3013                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3014                                                pr.info.uid, pr.processName);
3015                                    }
3016                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3017                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3018                                } else {
3019                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3020                                    if (ps == null || !ps.isActive()) {
3021                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3022                                                bstats.mapUid(st.uid), st.name);
3023                                    }
3024                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3025                                }
3026                            }
3027                            final int userTime = mProcessCpuTracker.getLastUserTime();
3028                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3029                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3030                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3031                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3032                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3033                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3034                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3035                        }
3036                    }
3037                }
3038
3039                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3040                    mLastWriteTime = now;
3041                    mBatteryStatsService.scheduleWriteToDisk();
3042                }
3043            }
3044        }
3045    }
3046
3047    @Override
3048    public void batteryNeedsCpuUpdate() {
3049        updateCpuStatsNow();
3050    }
3051
3052    @Override
3053    public void batteryPowerChanged(boolean onBattery) {
3054        // When plugging in, update the CPU stats first before changing
3055        // the plug state.
3056        updateCpuStatsNow();
3057        synchronized (this) {
3058            synchronized(mPidsSelfLocked) {
3059                mOnBattery = DEBUG_POWER ? true : onBattery;
3060            }
3061        }
3062    }
3063
3064    @Override
3065    public void batterySendBroadcast(Intent intent) {
3066        synchronized (this) {
3067            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3068                    AppOpsManager.OP_NONE, null, false, false,
3069                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3070        }
3071    }
3072
3073    /**
3074     * Initialize the application bind args. These are passed to each
3075     * process when the bindApplication() IPC is sent to the process. They're
3076     * lazily setup to make sure the services are running when they're asked for.
3077     */
3078    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3079        // Isolated processes won't get this optimization, so that we don't
3080        // violate the rules about which services they have access to.
3081        if (isolated) {
3082            if (mIsolatedAppBindArgs == null) {
3083                mIsolatedAppBindArgs = new HashMap<>();
3084                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3085            }
3086            return mIsolatedAppBindArgs;
3087        }
3088
3089        if (mAppBindArgs == null) {
3090            mAppBindArgs = new HashMap<>();
3091
3092            // Setup the application init args
3093            mAppBindArgs.put("package", ServiceManager.getService("package"));
3094            mAppBindArgs.put("window", ServiceManager.getService("window"));
3095            mAppBindArgs.put(Context.ALARM_SERVICE,
3096                    ServiceManager.getService(Context.ALARM_SERVICE));
3097        }
3098        return mAppBindArgs;
3099    }
3100
3101    /**
3102     * Update AMS states when an activity is resumed. This should only be called by
3103     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3104     */
3105    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3106        final TaskRecord task = r.getTask();
3107        if (task.isApplicationTask()) {
3108            if (mCurAppTimeTracker != r.appTimeTracker) {
3109                // We are switching app tracking.  Complete the current one.
3110                if (mCurAppTimeTracker != null) {
3111                    mCurAppTimeTracker.stop();
3112                    mHandler.obtainMessage(
3113                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3114                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3115                    mCurAppTimeTracker = null;
3116                }
3117                if (r.appTimeTracker != null) {
3118                    mCurAppTimeTracker = r.appTimeTracker;
3119                    startTimeTrackingFocusedActivityLocked();
3120                }
3121            } else {
3122                startTimeTrackingFocusedActivityLocked();
3123            }
3124        } else {
3125            r.appTimeTracker = null;
3126        }
3127        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3128        // TODO: Probably not, because we don't want to resume voice on switching
3129        // back to this activity
3130        if (task.voiceInteractor != null) {
3131            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3132        } else {
3133            finishRunningVoiceLocked();
3134
3135            if (mLastResumedActivity != null) {
3136                final IVoiceInteractionSession session;
3137
3138                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3139                if (lastResumedActivityTask != null
3140                        && lastResumedActivityTask.voiceSession != null) {
3141                    session = lastResumedActivityTask.voiceSession;
3142                } else {
3143                    session = mLastResumedActivity.voiceSession;
3144                }
3145
3146                if (session != null) {
3147                    // We had been in a voice interaction session, but now focused has
3148                    // move to something different.  Just finish the session, we can't
3149                    // return to it and retain the proper state and synchronization with
3150                    // the voice interaction service.
3151                    finishVoiceTask(session);
3152                }
3153            }
3154        }
3155
3156        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3157            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3158            mHandler.obtainMessage(
3159                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3160        }
3161        mLastResumedActivity = r;
3162
3163        mWindowManager.setFocusedApp(r.appToken, true);
3164
3165        applyUpdateLockStateLocked(r);
3166        applyUpdateVrModeLocked(r);
3167
3168        EventLogTags.writeAmSetResumedActivity(
3169                r == null ? -1 : r.userId,
3170                r == null ? "NULL" : r.shortComponentName,
3171                reason);
3172    }
3173
3174    @Override
3175    public void setFocusedStack(int stackId) {
3176        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3177        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3178        final long callingId = Binder.clearCallingIdentity();
3179        try {
3180            synchronized (this) {
3181                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3182                if (stack == null) {
3183                    return;
3184                }
3185                final ActivityRecord r = stack.topRunningActivityLocked();
3186                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3187                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3188                }
3189            }
3190        } finally {
3191            Binder.restoreCallingIdentity(callingId);
3192        }
3193    }
3194
3195    @Override
3196    public void setFocusedTask(int taskId) {
3197        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3198        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3199        final long callingId = Binder.clearCallingIdentity();
3200        try {
3201            synchronized (this) {
3202                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3203                if (task == null) {
3204                    return;
3205                }
3206                final ActivityRecord r = task.topRunningActivityLocked();
3207                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3208                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3209                }
3210            }
3211        } finally {
3212            Binder.restoreCallingIdentity(callingId);
3213        }
3214    }
3215
3216    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3217    @Override
3218    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3219        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3220        mTaskChangeNotificationController.registerTaskStackListener(listener);
3221    }
3222
3223    /**
3224     * Unregister a task stack listener so that it stops receiving callbacks.
3225     */
3226    @Override
3227    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3228         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3229         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3230     }
3231
3232    @Override
3233    public void notifyActivityDrawn(IBinder token) {
3234        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3235        synchronized (this) {
3236            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3237            if (r != null) {
3238                r.getStack().notifyActivityDrawnLocked(r);
3239            }
3240        }
3241    }
3242
3243    final void applyUpdateLockStateLocked(ActivityRecord r) {
3244        // Modifications to the UpdateLock state are done on our handler, outside
3245        // the activity manager's locks.  The new state is determined based on the
3246        // state *now* of the relevant activity record.  The object is passed to
3247        // the handler solely for logging detail, not to be consulted/modified.
3248        final boolean nextState = r != null && r.immersive;
3249        mHandler.sendMessage(
3250                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3251    }
3252
3253    final void applyUpdateVrModeLocked(ActivityRecord r) {
3254        mHandler.sendMessage(
3255                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3256    }
3257
3258    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3259        mHandler.sendMessage(
3260                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3261    }
3262
3263    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3264        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3265        if (vrService == null) {
3266            return;
3267        }
3268        vrService.onSleepStateChanged(isSleeping);
3269    }
3270
3271    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3272        Message msg = Message.obtain();
3273        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3274        msg.obj = r.getTask().askedCompatMode ? null : r;
3275        mUiHandler.sendMessage(msg);
3276    }
3277
3278    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3279        final Configuration globalConfig = getGlobalConfiguration();
3280        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3281                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3282            final Message msg = Message.obtain();
3283            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3284            msg.obj = r;
3285            mUiHandler.sendMessage(msg);
3286        }
3287    }
3288
3289    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3290            String what, Object obj, ProcessRecord srcApp) {
3291        app.lastActivityTime = now;
3292
3293        if (app.activities.size() > 0) {
3294            // Don't want to touch dependent processes that are hosting activities.
3295            return index;
3296        }
3297
3298        int lrui = mLruProcesses.lastIndexOf(app);
3299        if (lrui < 0) {
3300            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3301                    + what + " " + obj + " from " + srcApp);
3302            return index;
3303        }
3304
3305        if (lrui >= index) {
3306            // Don't want to cause this to move dependent processes *back* in the
3307            // list as if they were less frequently used.
3308            return index;
3309        }
3310
3311        if (lrui >= mLruProcessActivityStart) {
3312            // Don't want to touch dependent processes that are hosting activities.
3313            return index;
3314        }
3315
3316        mLruProcesses.remove(lrui);
3317        if (index > 0) {
3318            index--;
3319        }
3320        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3321                + " in LRU list: " + app);
3322        mLruProcesses.add(index, app);
3323        return index;
3324    }
3325
3326    static void killProcessGroup(int uid, int pid) {
3327        if (sKillHandler != null) {
3328            sKillHandler.sendMessage(
3329                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3330        } else {
3331            Slog.w(TAG, "Asked to kill process group before system bringup!");
3332            Process.killProcessGroup(uid, pid);
3333        }
3334    }
3335
3336    final void removeLruProcessLocked(ProcessRecord app) {
3337        int lrui = mLruProcesses.lastIndexOf(app);
3338        if (lrui >= 0) {
3339            if (!app.killed) {
3340                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3341                killProcessQuiet(app.pid);
3342                killProcessGroup(app.uid, app.pid);
3343            }
3344            if (lrui <= mLruProcessActivityStart) {
3345                mLruProcessActivityStart--;
3346            }
3347            if (lrui <= mLruProcessServiceStart) {
3348                mLruProcessServiceStart--;
3349            }
3350            mLruProcesses.remove(lrui);
3351        }
3352    }
3353
3354    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3355            ProcessRecord client) {
3356        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3357                || app.treatLikeActivity;
3358        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3359        if (!activityChange && hasActivity) {
3360            // The process has activities, so we are only allowing activity-based adjustments
3361            // to move it.  It should be kept in the front of the list with other
3362            // processes that have activities, and we don't want those to change their
3363            // order except due to activity operations.
3364            return;
3365        }
3366
3367        mLruSeq++;
3368        final long now = SystemClock.uptimeMillis();
3369        app.lastActivityTime = now;
3370
3371        // First a quick reject: if the app is already at the position we will
3372        // put it, then there is nothing to do.
3373        if (hasActivity) {
3374            final int N = mLruProcesses.size();
3375            if (N > 0 && mLruProcesses.get(N-1) == app) {
3376                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3377                return;
3378            }
3379        } else {
3380            if (mLruProcessServiceStart > 0
3381                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3382                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3383                return;
3384            }
3385        }
3386
3387        int lrui = mLruProcesses.lastIndexOf(app);
3388
3389        if (app.persistent && lrui >= 0) {
3390            // We don't care about the position of persistent processes, as long as
3391            // they are in the list.
3392            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3393            return;
3394        }
3395
3396        /* In progress: compute new position first, so we can avoid doing work
3397           if the process is not actually going to move.  Not yet working.
3398        int addIndex;
3399        int nextIndex;
3400        boolean inActivity = false, inService = false;
3401        if (hasActivity) {
3402            // Process has activities, put it at the very tipsy-top.
3403            addIndex = mLruProcesses.size();
3404            nextIndex = mLruProcessServiceStart;
3405            inActivity = true;
3406        } else if (hasService) {
3407            // Process has services, put it at the top of the service list.
3408            addIndex = mLruProcessActivityStart;
3409            nextIndex = mLruProcessServiceStart;
3410            inActivity = true;
3411            inService = true;
3412        } else  {
3413            // Process not otherwise of interest, it goes to the top of the non-service area.
3414            addIndex = mLruProcessServiceStart;
3415            if (client != null) {
3416                int clientIndex = mLruProcesses.lastIndexOf(client);
3417                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3418                        + app);
3419                if (clientIndex >= 0 && addIndex > clientIndex) {
3420                    addIndex = clientIndex;
3421                }
3422            }
3423            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3424        }
3425
3426        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3427                + mLruProcessActivityStart + "): " + app);
3428        */
3429
3430        if (lrui >= 0) {
3431            if (lrui < mLruProcessActivityStart) {
3432                mLruProcessActivityStart--;
3433            }
3434            if (lrui < mLruProcessServiceStart) {
3435                mLruProcessServiceStart--;
3436            }
3437            /*
3438            if (addIndex > lrui) {
3439                addIndex--;
3440            }
3441            if (nextIndex > lrui) {
3442                nextIndex--;
3443            }
3444            */
3445            mLruProcesses.remove(lrui);
3446        }
3447
3448        /*
3449        mLruProcesses.add(addIndex, app);
3450        if (inActivity) {
3451            mLruProcessActivityStart++;
3452        }
3453        if (inService) {
3454            mLruProcessActivityStart++;
3455        }
3456        */
3457
3458        int nextIndex;
3459        if (hasActivity) {
3460            final int N = mLruProcesses.size();
3461            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3462                // Process doesn't have activities, but has clients with
3463                // activities...  move it up, but one below the top (the top
3464                // should always have a real activity).
3465                if (DEBUG_LRU) Slog.d(TAG_LRU,
3466                        "Adding to second-top of LRU activity list: " + app);
3467                mLruProcesses.add(N - 1, app);
3468                // To keep it from spamming the LRU list (by making a bunch of clients),
3469                // we will push down any other entries owned by the app.
3470                final int uid = app.info.uid;
3471                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3472                    ProcessRecord subProc = mLruProcesses.get(i);
3473                    if (subProc.info.uid == uid) {
3474                        // We want to push this one down the list.  If the process after
3475                        // it is for the same uid, however, don't do so, because we don't
3476                        // want them internally to be re-ordered.
3477                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3478                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3479                                    "Pushing uid " + uid + " swapping at " + i + ": "
3480                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3481                            ProcessRecord tmp = mLruProcesses.get(i);
3482                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3483                            mLruProcesses.set(i - 1, tmp);
3484                            i--;
3485                        }
3486                    } else {
3487                        // A gap, we can stop here.
3488                        break;
3489                    }
3490                }
3491            } else {
3492                // Process has activities, put it at the very tipsy-top.
3493                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3494                mLruProcesses.add(app);
3495            }
3496            nextIndex = mLruProcessServiceStart;
3497        } else if (hasService) {
3498            // Process has services, put it at the top of the service list.
3499            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3500            mLruProcesses.add(mLruProcessActivityStart, app);
3501            nextIndex = mLruProcessServiceStart;
3502            mLruProcessActivityStart++;
3503        } else  {
3504            // Process not otherwise of interest, it goes to the top of the non-service area.
3505            int index = mLruProcessServiceStart;
3506            if (client != null) {
3507                // If there is a client, don't allow the process to be moved up higher
3508                // in the list than that client.
3509                int clientIndex = mLruProcesses.lastIndexOf(client);
3510                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3511                        + " when updating " + app);
3512                if (clientIndex <= lrui) {
3513                    // Don't allow the client index restriction to push it down farther in the
3514                    // list than it already is.
3515                    clientIndex = lrui;
3516                }
3517                if (clientIndex >= 0 && index > clientIndex) {
3518                    index = clientIndex;
3519                }
3520            }
3521            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3522            mLruProcesses.add(index, app);
3523            nextIndex = index-1;
3524            mLruProcessActivityStart++;
3525            mLruProcessServiceStart++;
3526        }
3527
3528        // If the app is currently using a content provider or service,
3529        // bump those processes as well.
3530        for (int j=app.connections.size()-1; j>=0; j--) {
3531            ConnectionRecord cr = app.connections.valueAt(j);
3532            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3533                    && cr.binding.service.app != null
3534                    && cr.binding.service.app.lruSeq != mLruSeq
3535                    && !cr.binding.service.app.persistent) {
3536                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3537                        "service connection", cr, app);
3538            }
3539        }
3540        for (int j=app.conProviders.size()-1; j>=0; j--) {
3541            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3542            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3543                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3544                        "provider reference", cpr, app);
3545            }
3546        }
3547    }
3548
3549    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3550        if (uid == SYSTEM_UID) {
3551            // The system gets to run in any process.  If there are multiple
3552            // processes with the same uid, just pick the first (this
3553            // should never happen).
3554            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3555            if (procs == null) return null;
3556            final int procCount = procs.size();
3557            for (int i = 0; i < procCount; i++) {
3558                final int procUid = procs.keyAt(i);
3559                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3560                    // Don't use an app process or different user process for system component.
3561                    continue;
3562                }
3563                return procs.valueAt(i);
3564            }
3565        }
3566        ProcessRecord proc = mProcessNames.get(processName, uid);
3567        if (false && proc != null && !keepIfLarge
3568                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3569                && proc.lastCachedPss >= 4000) {
3570            // Turn this condition on to cause killing to happen regularly, for testing.
3571            if (proc.baseProcessTracker != null) {
3572                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3573            }
3574            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3575        } else if (proc != null && !keepIfLarge
3576                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3577                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3578            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3579            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3580                if (proc.baseProcessTracker != null) {
3581                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3582                }
3583                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3584            }
3585        }
3586        return proc;
3587    }
3588
3589    void notifyPackageUse(String packageName, int reason) {
3590        IPackageManager pm = AppGlobals.getPackageManager();
3591        try {
3592            pm.notifyPackageUse(packageName, reason);
3593        } catch (RemoteException e) {
3594        }
3595    }
3596
3597    boolean isNextTransitionForward() {
3598        int transit = mWindowManager.getPendingAppTransition();
3599        return transit == TRANSIT_ACTIVITY_OPEN
3600                || transit == TRANSIT_TASK_OPEN
3601                || transit == TRANSIT_TASK_TO_FRONT;
3602    }
3603
3604    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3605            String processName, String abiOverride, int uid, Runnable crashHandler) {
3606        synchronized(this) {
3607            ApplicationInfo info = new ApplicationInfo();
3608            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3609            // For isolated processes, the former contains the parent's uid and the latter the
3610            // actual uid of the isolated process.
3611            // In the special case introduced by this method (which is, starting an isolated
3612            // process directly from the SystemServer without an actual parent app process) the
3613            // closest thing to a parent's uid is SYSTEM_UID.
3614            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3615            // the |isolated| logic in the ProcessRecord constructor.
3616            info.uid = SYSTEM_UID;
3617            info.processName = processName;
3618            info.className = entryPoint;
3619            info.packageName = "android";
3620            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3621            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3622                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3623                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3624                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3625                    crashHandler);
3626            return proc != null ? proc.pid : 0;
3627        }
3628    }
3629
3630    final ProcessRecord startProcessLocked(String processName,
3631            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3632            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3633            boolean isolated, boolean keepIfLarge) {
3634        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3635                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3636                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3637                null /* crashHandler */);
3638    }
3639
3640    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3641            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3642            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3643            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3644        long startTime = SystemClock.elapsedRealtime();
3645        ProcessRecord app;
3646        if (!isolated) {
3647            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3648            checkTime(startTime, "startProcess: after getProcessRecord");
3649
3650            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3651                // If we are in the background, then check to see if this process
3652                // is bad.  If so, we will just silently fail.
3653                if (mAppErrors.isBadProcessLocked(info)) {
3654                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3655                            + "/" + info.processName);
3656                    return null;
3657                }
3658            } else {
3659                // When the user is explicitly starting a process, then clear its
3660                // crash count so that we won't make it bad until they see at
3661                // least one crash dialog again, and make the process good again
3662                // if it had been bad.
3663                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3664                        + "/" + info.processName);
3665                mAppErrors.resetProcessCrashTimeLocked(info);
3666                if (mAppErrors.isBadProcessLocked(info)) {
3667                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3668                            UserHandle.getUserId(info.uid), info.uid,
3669                            info.processName);
3670                    mAppErrors.clearBadProcessLocked(info);
3671                    if (app != null) {
3672                        app.bad = false;
3673                    }
3674                }
3675            }
3676        } else {
3677            // If this is an isolated process, it can't re-use an existing process.
3678            app = null;
3679        }
3680
3681        // We don't have to do anything more if:
3682        // (1) There is an existing application record; and
3683        // (2) The caller doesn't think it is dead, OR there is no thread
3684        //     object attached to it so we know it couldn't have crashed; and
3685        // (3) There is a pid assigned to it, so it is either starting or
3686        //     already running.
3687        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3688                + " app=" + app + " knownToBeDead=" + knownToBeDead
3689                + " thread=" + (app != null ? app.thread : null)
3690                + " pid=" + (app != null ? app.pid : -1));
3691        if (app != null && app.pid > 0) {
3692            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3693                // We already have the app running, or are waiting for it to
3694                // come up (we have a pid but not yet its thread), so keep it.
3695                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3696                // If this is a new package in the process, add the package to the list
3697                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3698                checkTime(startTime, "startProcess: done, added package to proc");
3699                return app;
3700            }
3701
3702            // An application record is attached to a previous process,
3703            // clean it up now.
3704            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3705            checkTime(startTime, "startProcess: bad proc running, killing");
3706            killProcessGroup(app.uid, app.pid);
3707            handleAppDiedLocked(app, true, true);
3708            checkTime(startTime, "startProcess: done killing old proc");
3709        }
3710
3711        String hostingNameStr = hostingName != null
3712                ? hostingName.flattenToShortString() : null;
3713
3714        if (app == null) {
3715            checkTime(startTime, "startProcess: creating new process record");
3716            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3717            if (app == null) {
3718                Slog.w(TAG, "Failed making new process record for "
3719                        + processName + "/" + info.uid + " isolated=" + isolated);
3720                return null;
3721            }
3722            app.crashHandler = crashHandler;
3723            checkTime(startTime, "startProcess: done creating new process record");
3724        } else {
3725            // If this is a new package in the process, add the package to the list
3726            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3727            checkTime(startTime, "startProcess: added package to existing proc");
3728        }
3729
3730        // If the system is not ready yet, then hold off on starting this
3731        // process until it is.
3732        if (!mProcessesReady
3733                && !isAllowedWhileBooting(info)
3734                && !allowWhileBooting) {
3735            if (!mProcessesOnHold.contains(app)) {
3736                mProcessesOnHold.add(app);
3737            }
3738            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3739                    "System not ready, putting on hold: " + app);
3740            checkTime(startTime, "startProcess: returning with proc on hold");
3741            return app;
3742        }
3743
3744        checkTime(startTime, "startProcess: stepping in to startProcess");
3745        startProcessLocked(
3746                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3747        checkTime(startTime, "startProcess: done starting proc!");
3748        return (app.pid != 0) ? app : null;
3749    }
3750
3751    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3752        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3753    }
3754
3755    private final void startProcessLocked(ProcessRecord app,
3756            String hostingType, String hostingNameStr) {
3757        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3758                null /* entryPoint */, null /* entryPointArgs */);
3759    }
3760
3761    private final void startProcessLocked(ProcessRecord app, String hostingType,
3762            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3763        long startTime = SystemClock.elapsedRealtime();
3764        if (app.pid > 0 && app.pid != MY_PID) {
3765            checkTime(startTime, "startProcess: removing from pids map");
3766            synchronized (mPidsSelfLocked) {
3767                mPidsSelfLocked.remove(app.pid);
3768                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3769            }
3770            checkTime(startTime, "startProcess: done removing from pids map");
3771            app.setPid(0);
3772        }
3773
3774        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3775                "startProcessLocked removing on hold: " + app);
3776        mProcessesOnHold.remove(app);
3777
3778        checkTime(startTime, "startProcess: starting to update cpu stats");
3779        updateCpuStats();
3780        checkTime(startTime, "startProcess: done updating cpu stats");
3781
3782        try {
3783            try {
3784                final int userId = UserHandle.getUserId(app.uid);
3785                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3786            } catch (RemoteException e) {
3787                throw e.rethrowAsRuntimeException();
3788            }
3789
3790            int uid = app.uid;
3791            int[] gids = null;
3792            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3793            if (!app.isolated) {
3794                int[] permGids = null;
3795                try {
3796                    checkTime(startTime, "startProcess: getting gids from package manager");
3797                    final IPackageManager pm = AppGlobals.getPackageManager();
3798                    permGids = pm.getPackageGids(app.info.packageName,
3799                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3800                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3801                            StorageManagerInternal.class);
3802                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3803                            app.info.packageName);
3804                } catch (RemoteException e) {
3805                    throw e.rethrowAsRuntimeException();
3806                }
3807
3808                /*
3809                 * Add shared application and profile GIDs so applications can share some
3810                 * resources like shared libraries and access user-wide resources
3811                 */
3812                if (ArrayUtils.isEmpty(permGids)) {
3813                    gids = new int[3];
3814                } else {
3815                    gids = new int[permGids.length + 3];
3816                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3817                }
3818                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3819                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3820                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3821            }
3822            checkTime(startTime, "startProcess: building args");
3823            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3824                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3825                        && mTopComponent != null
3826                        && app.processName.equals(mTopComponent.getPackageName())) {
3827                    uid = 0;
3828                }
3829                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3830                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3831                    uid = 0;
3832                }
3833            }
3834            int debugFlags = 0;
3835            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3836                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3837                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3838                // Also turn on CheckJNI for debuggable apps. It's quite
3839                // awkward to turn on otherwise.
3840                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3841            }
3842            // Run the app in safe mode if its manifest requests so or the
3843            // system is booted in safe mode.
3844            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3845                mSafeMode == true) {
3846                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3847            }
3848            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3849                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3850            }
3851            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3852            if ("true".equals(genDebugInfoProperty)) {
3853                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3854            }
3855            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3856                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3857            }
3858            if ("1".equals(SystemProperties.get("debug.assert"))) {
3859                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3860            }
3861            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3862                // Enable all debug flags required by the native debugger.
3863                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3864                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3865                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3866                mNativeDebuggingApp = null;
3867            }
3868
3869            String invokeWith = null;
3870            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3871                // Debuggable apps may include a wrapper script with their library directory.
3872                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3873                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3874                try {
3875                    if (new File(wrapperFileName).exists()) {
3876                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3877                    }
3878                } finally {
3879                    StrictMode.setThreadPolicy(oldPolicy);
3880                }
3881            }
3882
3883            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3884            if (requiredAbi == null) {
3885                requiredAbi = Build.SUPPORTED_ABIS[0];
3886            }
3887
3888            String instructionSet = null;
3889            if (app.info.primaryCpuAbi != null) {
3890                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3891            }
3892
3893            app.gids = gids;
3894            app.requiredAbi = requiredAbi;
3895            app.instructionSet = instructionSet;
3896
3897            // the per-user SELinux context must be set
3898            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3899                Slog.wtf(TAG, "SELinux tag not defined",
3900                        new IllegalStateException("SELinux tag not defined for "
3901                        + app.info.packageName + " (uid " + app.uid + ")"));
3902            }
3903            final String seInfo = app.info.seInfo
3904                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3905            // Start the process.  It will either succeed and return a result containing
3906            // the PID of the new process, or else throw a RuntimeException.
3907            boolean isActivityProcess = (entryPoint == null);
3908            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3909            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3910                    app.processName);
3911            checkTime(startTime, "startProcess: asking zygote to start proc");
3912            ProcessStartResult startResult;
3913            if (hostingType.equals("webview_service")) {
3914                startResult = startWebView(entryPoint,
3915                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3916                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3917                        app.info.dataDir, null, entryPointArgs);
3918            } else {
3919                startResult = Process.start(entryPoint,
3920                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3921                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3922                        app.info.dataDir, invokeWith, entryPointArgs);
3923            }
3924            checkTime(startTime, "startProcess: returned from zygote!");
3925            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3926
3927            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3928            checkTime(startTime, "startProcess: done updating battery stats");
3929
3930            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3931                    UserHandle.getUserId(uid), startResult.pid, uid,
3932                    app.processName, hostingType,
3933                    hostingNameStr != null ? hostingNameStr : "");
3934
3935            try {
3936                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3937                        seInfo, app.info.sourceDir, startResult.pid);
3938            } catch (RemoteException ex) {
3939                // Ignore
3940            }
3941
3942            if (app.persistent) {
3943                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3944            }
3945
3946            checkTime(startTime, "startProcess: building log message");
3947            StringBuilder buf = mStringBuilder;
3948            buf.setLength(0);
3949            buf.append("Start proc ");
3950            buf.append(startResult.pid);
3951            buf.append(':');
3952            buf.append(app.processName);
3953            buf.append('/');
3954            UserHandle.formatUid(buf, uid);
3955            if (!isActivityProcess) {
3956                buf.append(" [");
3957                buf.append(entryPoint);
3958                buf.append("]");
3959            }
3960            buf.append(" for ");
3961            buf.append(hostingType);
3962            if (hostingNameStr != null) {
3963                buf.append(" ");
3964                buf.append(hostingNameStr);
3965            }
3966            Slog.i(TAG, buf.toString());
3967            app.setPid(startResult.pid);
3968            app.usingWrapper = startResult.usingWrapper;
3969            app.removed = false;
3970            app.killed = false;
3971            app.killedByAm = false;
3972            checkTime(startTime, "startProcess: starting to update pids map");
3973            ProcessRecord oldApp;
3974            synchronized (mPidsSelfLocked) {
3975                oldApp = mPidsSelfLocked.get(startResult.pid);
3976            }
3977            // If there is already an app occupying that pid that hasn't been cleaned up
3978            if (oldApp != null && !app.isolated) {
3979                // Clean up anything relating to this pid first
3980                Slog.w(TAG, "Reusing pid " + startResult.pid
3981                        + " while app is still mapped to it");
3982                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3983                        true /*replacingPid*/);
3984            }
3985            synchronized (mPidsSelfLocked) {
3986                this.mPidsSelfLocked.put(startResult.pid, app);
3987                if (isActivityProcess) {
3988                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3989                    msg.obj = app;
3990                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3991                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3992                }
3993            }
3994            checkTime(startTime, "startProcess: done updating pids map");
3995        } catch (RuntimeException e) {
3996            Slog.e(TAG, "Failure starting process " + app.processName, e);
3997
3998            // Something went very wrong while trying to start this process; one
3999            // common case is when the package is frozen due to an active
4000            // upgrade. To recover, clean up any active bookkeeping related to
4001            // starting this process. (We already invoked this method once when
4002            // the package was initially frozen through KILL_APPLICATION_MSG, so
4003            // it doesn't hurt to use it again.)
4004            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4005                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4006        }
4007    }
4008
4009    void updateUsageStats(ActivityRecord component, boolean resumed) {
4010        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4011                "updateUsageStats: comp=" + component + "res=" + resumed);
4012        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4013        if (resumed) {
4014            if (mUsageStatsService != null) {
4015                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4016                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4017            }
4018            synchronized (stats) {
4019                stats.noteActivityResumedLocked(component.app.uid);
4020            }
4021        } else {
4022            if (mUsageStatsService != null) {
4023                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4024                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4025            }
4026            synchronized (stats) {
4027                stats.noteActivityPausedLocked(component.app.uid);
4028            }
4029        }
4030    }
4031
4032    Intent getHomeIntent() {
4033        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4034        intent.setComponent(mTopComponent);
4035        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4036        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4037            intent.addCategory(Intent.CATEGORY_HOME);
4038        }
4039        return intent;
4040    }
4041
4042    boolean startHomeActivityLocked(int userId, String reason) {
4043        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4044                && mTopAction == null) {
4045            // We are running in factory test mode, but unable to find
4046            // the factory test app, so just sit around displaying the
4047            // error message and don't try to start anything.
4048            return false;
4049        }
4050        Intent intent = getHomeIntent();
4051        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4052        if (aInfo != null) {
4053            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4054            // Don't do this if the home app is currently being
4055            // instrumented.
4056            aInfo = new ActivityInfo(aInfo);
4057            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4058            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4059                    aInfo.applicationInfo.uid, true);
4060            if (app == null || app.instr == null) {
4061                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4062                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
4063            }
4064        } else {
4065            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4066        }
4067
4068        return true;
4069    }
4070
4071    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4072        ActivityInfo ai = null;
4073        ComponentName comp = intent.getComponent();
4074        try {
4075            if (comp != null) {
4076                // Factory test.
4077                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4078            } else {
4079                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4080                        intent,
4081                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4082                        flags, userId);
4083
4084                if (info != null) {
4085                    ai = info.activityInfo;
4086                }
4087            }
4088        } catch (RemoteException e) {
4089            // ignore
4090        }
4091
4092        return ai;
4093    }
4094
4095    /**
4096     * Starts the "new version setup screen" if appropriate.
4097     */
4098    void startSetupActivityLocked() {
4099        // Only do this once per boot.
4100        if (mCheckedForSetup) {
4101            return;
4102        }
4103
4104        // We will show this screen if the current one is a different
4105        // version than the last one shown, and we are not running in
4106        // low-level factory test mode.
4107        final ContentResolver resolver = mContext.getContentResolver();
4108        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4109                Settings.Global.getInt(resolver,
4110                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4111            mCheckedForSetup = true;
4112
4113            // See if we should be showing the platform update setup UI.
4114            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4115            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4116                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4117            if (!ris.isEmpty()) {
4118                final ResolveInfo ri = ris.get(0);
4119                String vers = ri.activityInfo.metaData != null
4120                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4121                        : null;
4122                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4123                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4124                            Intent.METADATA_SETUP_VERSION);
4125                }
4126                String lastVers = Settings.Secure.getString(
4127                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4128                if (vers != null && !vers.equals(lastVers)) {
4129                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4130                    intent.setComponent(new ComponentName(
4131                            ri.activityInfo.packageName, ri.activityInfo.name));
4132                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4133                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4134                            null, 0, 0, 0, null, false, false, null, null, null);
4135                }
4136            }
4137        }
4138    }
4139
4140    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4141        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4142    }
4143
4144    void enforceNotIsolatedCaller(String caller) {
4145        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4146            throw new SecurityException("Isolated process not allowed to call " + caller);
4147        }
4148    }
4149
4150    void enforceShellRestriction(String restriction, int userHandle) {
4151        if (Binder.getCallingUid() == SHELL_UID) {
4152            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4153                throw new SecurityException("Shell does not have permission to access user "
4154                        + userHandle);
4155            }
4156        }
4157    }
4158
4159    @Override
4160    public int getFrontActivityScreenCompatMode() {
4161        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4162        synchronized (this) {
4163            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4164        }
4165    }
4166
4167    @Override
4168    public void setFrontActivityScreenCompatMode(int mode) {
4169        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4170                "setFrontActivityScreenCompatMode");
4171        synchronized (this) {
4172            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4173        }
4174    }
4175
4176    @Override
4177    public int getPackageScreenCompatMode(String packageName) {
4178        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4179        synchronized (this) {
4180            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4181        }
4182    }
4183
4184    @Override
4185    public void setPackageScreenCompatMode(String packageName, int mode) {
4186        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4187                "setPackageScreenCompatMode");
4188        synchronized (this) {
4189            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4190        }
4191    }
4192
4193    @Override
4194    public boolean getPackageAskScreenCompat(String packageName) {
4195        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4196        synchronized (this) {
4197            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4198        }
4199    }
4200
4201    @Override
4202    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4203        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4204                "setPackageAskScreenCompat");
4205        synchronized (this) {
4206            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4207        }
4208    }
4209
4210    private boolean hasUsageStatsPermission(String callingPackage) {
4211        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4212                Binder.getCallingUid(), callingPackage);
4213        if (mode == AppOpsManager.MODE_DEFAULT) {
4214            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4215                    == PackageManager.PERMISSION_GRANTED;
4216        }
4217        return mode == AppOpsManager.MODE_ALLOWED;
4218    }
4219
4220    @Override
4221    public int getPackageProcessState(String packageName, String callingPackage) {
4222        if (!hasUsageStatsPermission(callingPackage)) {
4223            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4224                    "getPackageProcessState");
4225        }
4226
4227        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4228        synchronized (this) {
4229            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4230                final ProcessRecord proc = mLruProcesses.get(i);
4231                if (procState > proc.setProcState) {
4232                    if (proc.pkgList.containsKey(packageName) ||
4233                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4234                        procState = proc.setProcState;
4235                    }
4236                }
4237            }
4238        }
4239        return procState;
4240    }
4241
4242    @Override
4243    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4244            throws RemoteException {
4245        synchronized (this) {
4246            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4247            if (app == null) {
4248                throw new IllegalArgumentException("Unknown process: " + process);
4249            }
4250            if (app.thread == null) {
4251                throw new IllegalArgumentException("Process has no app thread");
4252            }
4253            if (app.trimMemoryLevel >= level) {
4254                throw new IllegalArgumentException(
4255                        "Unable to set a higher trim level than current level");
4256            }
4257            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4258                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4259                throw new IllegalArgumentException("Unable to set a background trim level "
4260                    + "on a foreground process");
4261            }
4262            app.thread.scheduleTrimMemory(level);
4263            app.trimMemoryLevel = level;
4264            return true;
4265        }
4266    }
4267
4268    private void dispatchProcessesChanged() {
4269        int N;
4270        synchronized (this) {
4271            N = mPendingProcessChanges.size();
4272            if (mActiveProcessChanges.length < N) {
4273                mActiveProcessChanges = new ProcessChangeItem[N];
4274            }
4275            mPendingProcessChanges.toArray(mActiveProcessChanges);
4276            mPendingProcessChanges.clear();
4277            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4278                    "*** Delivering " + N + " process changes");
4279        }
4280
4281        int i = mProcessObservers.beginBroadcast();
4282        while (i > 0) {
4283            i--;
4284            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4285            if (observer != null) {
4286                try {
4287                    for (int j=0; j<N; j++) {
4288                        ProcessChangeItem item = mActiveProcessChanges[j];
4289                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4290                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4291                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4292                                    + item.uid + ": " + item.foregroundActivities);
4293                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4294                                    item.foregroundActivities);
4295                        }
4296                    }
4297                } catch (RemoteException e) {
4298                }
4299            }
4300        }
4301        mProcessObservers.finishBroadcast();
4302
4303        synchronized (this) {
4304            for (int j=0; j<N; j++) {
4305                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4306            }
4307        }
4308    }
4309
4310    private void dispatchProcessDied(int pid, int uid) {
4311        int i = mProcessObservers.beginBroadcast();
4312        while (i > 0) {
4313            i--;
4314            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4315            if (observer != null) {
4316                try {
4317                    observer.onProcessDied(pid, uid);
4318                } catch (RemoteException e) {
4319                }
4320            }
4321        }
4322        mProcessObservers.finishBroadcast();
4323    }
4324
4325    @VisibleForTesting
4326    void dispatchUidsChanged() {
4327        int N;
4328        synchronized (this) {
4329            N = mPendingUidChanges.size();
4330            if (mActiveUidChanges.length < N) {
4331                mActiveUidChanges = new UidRecord.ChangeItem[N];
4332            }
4333            for (int i=0; i<N; i++) {
4334                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4335                mActiveUidChanges[i] = change;
4336                if (change.uidRecord != null) {
4337                    change.uidRecord.pendingChange = null;
4338                    change.uidRecord = null;
4339                }
4340            }
4341            mPendingUidChanges.clear();
4342            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4343                    "*** Delivering " + N + " uid changes");
4344        }
4345
4346        int i = mUidObservers.beginBroadcast();
4347        while (i > 0) {
4348            i--;
4349            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4350                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4351        }
4352        mUidObservers.finishBroadcast();
4353
4354        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4355            for (int j = 0; j < N; ++j) {
4356                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4357                if (item.change == UidRecord.CHANGE_GONE
4358                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4359                    mValidateUids.remove(item.uid);
4360                } else {
4361                    UidRecord validateUid = mValidateUids.get(item.uid);
4362                    if (validateUid == null) {
4363                        validateUid = new UidRecord(item.uid);
4364                        mValidateUids.put(item.uid, validateUid);
4365                    }
4366                    if (item.change == UidRecord.CHANGE_IDLE) {
4367                        validateUid.idle = true;
4368                    } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4369                        validateUid.idle = false;
4370                    }
4371                    validateUid.curProcState = validateUid.setProcState = item.processState;
4372                }
4373            }
4374        }
4375
4376        synchronized (this) {
4377            for (int j = 0; j < N; j++) {
4378                mAvailUidChanges.add(mActiveUidChanges[j]);
4379            }
4380        }
4381    }
4382
4383    private void dispatchUidsChangedForObserver(IUidObserver observer,
4384            UidObserverRegistration reg, int changesSize) {
4385        if (observer == null) {
4386            return;
4387        }
4388        try {
4389            for (int j = 0; j < changesSize; j++) {
4390                UidRecord.ChangeItem item = mActiveUidChanges[j];
4391                final int change = item.change;
4392                if (change == UidRecord.CHANGE_IDLE
4393                        || change == UidRecord.CHANGE_GONE_IDLE) {
4394                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4395                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4396                                "UID idle uid=" + item.uid);
4397                        observer.onUidIdle(item.uid, item.ephemeral);
4398                    }
4399                } else if (change == UidRecord.CHANGE_ACTIVE) {
4400                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4401                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4402                                "UID active uid=" + item.uid);
4403                        observer.onUidActive(item.uid);
4404                    }
4405                }
4406                if (change == UidRecord.CHANGE_GONE
4407                        || change == UidRecord.CHANGE_GONE_IDLE) {
4408                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4409                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4410                                "UID gone uid=" + item.uid);
4411                        observer.onUidGone(item.uid, item.ephemeral);
4412                    }
4413                    if (reg.lastProcStates != null) {
4414                        reg.lastProcStates.delete(item.uid);
4415                    }
4416                } else {
4417                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4418                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4419                                "UID CHANGED uid=" + item.uid
4420                                        + ": " + item.processState);
4421                        boolean doReport = true;
4422                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4423                            final int lastState = reg.lastProcStates.get(item.uid,
4424                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4425                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4426                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4427                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4428                                doReport = lastAboveCut != newAboveCut;
4429                            } else {
4430                                doReport = item.processState
4431                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4432                            }
4433                        }
4434                        if (doReport) {
4435                            if (reg.lastProcStates != null) {
4436                                reg.lastProcStates.put(item.uid, item.processState);
4437                            }
4438                            observer.onUidStateChanged(item.uid, item.processState,
4439                                    item.procStateSeq);
4440                        }
4441                    }
4442                }
4443            }
4444        } catch (RemoteException e) {
4445        }
4446    }
4447
4448    @Override
4449    public final int startActivity(IApplicationThread caller, String callingPackage,
4450            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4451            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4452        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4453                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4454                UserHandle.getCallingUserId());
4455    }
4456
4457    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4458        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4459        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4460                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4461                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4462
4463        // TODO: Switch to user app stacks here.
4464        String mimeType = intent.getType();
4465        final Uri data = intent.getData();
4466        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4467            mimeType = getProviderMimeType(data, userId);
4468        }
4469        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4470
4471        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4472        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4473                null, 0, 0, null, null, null, null, false, userId, container, null);
4474    }
4475
4476    @Override
4477    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4478            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4479            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4480        enforceNotIsolatedCaller("startActivity");
4481        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4482                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4483        // TODO: Switch to user app stacks here.
4484        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4485                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4486                profilerInfo, null, null, bOptions, false, userId, null, null);
4487    }
4488
4489    @Override
4490    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4491            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4492            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4493            int userId) {
4494
4495        // This is very dangerous -- it allows you to perform a start activity (including
4496        // permission grants) as any app that may launch one of your own activities.  So
4497        // we will only allow this to be done from activities that are part of the core framework,
4498        // and then only when they are running as the system.
4499        final ActivityRecord sourceRecord;
4500        final int targetUid;
4501        final String targetPackage;
4502        synchronized (this) {
4503            if (resultTo == null) {
4504                throw new SecurityException("Must be called from an activity");
4505            }
4506            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4507            if (sourceRecord == null) {
4508                throw new SecurityException("Called with bad activity token: " + resultTo);
4509            }
4510            if (!sourceRecord.info.packageName.equals("android")) {
4511                throw new SecurityException(
4512                        "Must be called from an activity that is declared in the android package");
4513            }
4514            if (sourceRecord.app == null) {
4515                throw new SecurityException("Called without a process attached to activity");
4516            }
4517            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4518                // This is still okay, as long as this activity is running under the
4519                // uid of the original calling activity.
4520                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4521                    throw new SecurityException(
4522                            "Calling activity in uid " + sourceRecord.app.uid
4523                                    + " must be system uid or original calling uid "
4524                                    + sourceRecord.launchedFromUid);
4525                }
4526            }
4527            if (ignoreTargetSecurity) {
4528                if (intent.getComponent() == null) {
4529                    throw new SecurityException(
4530                            "Component must be specified with ignoreTargetSecurity");
4531                }
4532                if (intent.getSelector() != null) {
4533                    throw new SecurityException(
4534                            "Selector not allowed with ignoreTargetSecurity");
4535                }
4536            }
4537            targetUid = sourceRecord.launchedFromUid;
4538            targetPackage = sourceRecord.launchedFromPackage;
4539        }
4540
4541        if (userId == UserHandle.USER_NULL) {
4542            userId = UserHandle.getUserId(sourceRecord.app.uid);
4543        }
4544
4545        // TODO: Switch to user app stacks here.
4546        try {
4547            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4548                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4549                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4550            return ret;
4551        } catch (SecurityException e) {
4552            // XXX need to figure out how to propagate to original app.
4553            // A SecurityException here is generally actually a fault of the original
4554            // calling activity (such as a fairly granting permissions), so propagate it
4555            // back to them.
4556            /*
4557            StringBuilder msg = new StringBuilder();
4558            msg.append("While launching");
4559            msg.append(intent.toString());
4560            msg.append(": ");
4561            msg.append(e.getMessage());
4562            */
4563            throw e;
4564        }
4565    }
4566
4567    @Override
4568    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4569            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4570            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4571        enforceNotIsolatedCaller("startActivityAndWait");
4572        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4573                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4574        WaitResult res = new WaitResult();
4575        // TODO: Switch to user app stacks here.
4576        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4577                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4578                bOptions, false, userId, null, null);
4579        return res;
4580    }
4581
4582    @Override
4583    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4584            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4585            int startFlags, Configuration config, Bundle bOptions, int userId) {
4586        enforceNotIsolatedCaller("startActivityWithConfig");
4587        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4588                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4589        // TODO: Switch to user app stacks here.
4590        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4591                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4592                null, null, config, bOptions, false, userId, null, null);
4593        return ret;
4594    }
4595
4596    @Override
4597    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4598            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4599            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4600            throws TransactionTooLargeException {
4601        enforceNotIsolatedCaller("startActivityIntentSender");
4602        // Refuse possible leaked file descriptors
4603        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4604            throw new IllegalArgumentException("File descriptors passed in Intent");
4605        }
4606
4607        IIntentSender sender = intent.getTarget();
4608        if (!(sender instanceof PendingIntentRecord)) {
4609            throw new IllegalArgumentException("Bad PendingIntent object");
4610        }
4611
4612        PendingIntentRecord pir = (PendingIntentRecord)sender;
4613
4614        synchronized (this) {
4615            // If this is coming from the currently resumed activity, it is
4616            // effectively saying that app switches are allowed at this point.
4617            final ActivityStack stack = getFocusedStack();
4618            if (stack.mResumedActivity != null &&
4619                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4620                mAppSwitchesAllowedTime = 0;
4621            }
4622        }
4623        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4624                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4625        return ret;
4626    }
4627
4628    @Override
4629    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4630            Intent intent, String resolvedType, IVoiceInteractionSession session,
4631            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4632            Bundle bOptions, int userId) {
4633        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4634                != PackageManager.PERMISSION_GRANTED) {
4635            String msg = "Permission Denial: startVoiceActivity() from pid="
4636                    + Binder.getCallingPid()
4637                    + ", uid=" + Binder.getCallingUid()
4638                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4639            Slog.w(TAG, msg);
4640            throw new SecurityException(msg);
4641        }
4642        if (session == null || interactor == null) {
4643            throw new NullPointerException("null session or interactor");
4644        }
4645        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4646                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4647        // TODO: Switch to user app stacks here.
4648        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4649                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4650                null, bOptions, false, userId, null, null);
4651    }
4652
4653    @Override
4654    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4655            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4656        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4657                != PackageManager.PERMISSION_GRANTED) {
4658            final String msg = "Permission Denial: startAssistantActivity() from pid="
4659                    + Binder.getCallingPid()
4660                    + ", uid=" + Binder.getCallingUid()
4661                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4662            Slog.w(TAG, msg);
4663            throw new SecurityException(msg);
4664        }
4665        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4666                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4667        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4668                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4669                userId, null, null);
4670    }
4671
4672    @Override
4673    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4674            throws RemoteException {
4675        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4676        synchronized (this) {
4677            ActivityRecord activity = getFocusedStack().topActivity();
4678            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4679                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4680            }
4681            if (mRunningVoice != null || activity.getTask().voiceSession != null
4682                    || activity.voiceSession != null) {
4683                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4684                return;
4685            }
4686            if (activity.pendingVoiceInteractionStart) {
4687                Slog.w(TAG, "Pending start of voice interaction already.");
4688                return;
4689            }
4690            activity.pendingVoiceInteractionStart = true;
4691        }
4692        LocalServices.getService(VoiceInteractionManagerInternal.class)
4693                .startLocalVoiceInteraction(callingActivity, options);
4694    }
4695
4696    @Override
4697    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4698        LocalServices.getService(VoiceInteractionManagerInternal.class)
4699                .stopLocalVoiceInteraction(callingActivity);
4700    }
4701
4702    @Override
4703    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4704        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4705                .supportsLocalVoiceInteraction();
4706    }
4707
4708    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4709            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4710        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4711        if (activityToCallback == null) return;
4712        activityToCallback.setVoiceSessionLocked(voiceSession);
4713
4714        // Inform the activity
4715        try {
4716            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4717                    voiceInteractor);
4718            long token = Binder.clearCallingIdentity();
4719            try {
4720                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4721            } finally {
4722                Binder.restoreCallingIdentity(token);
4723            }
4724            // TODO: VI Should we cache the activity so that it's easier to find later
4725            // rather than scan through all the stacks and activities?
4726        } catch (RemoteException re) {
4727            activityToCallback.clearVoiceSessionLocked();
4728            // TODO: VI Should this terminate the voice session?
4729        }
4730    }
4731
4732    @Override
4733    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4734        synchronized (this) {
4735            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4736                if (keepAwake) {
4737                    mVoiceWakeLock.acquire();
4738                } else {
4739                    mVoiceWakeLock.release();
4740                }
4741            }
4742        }
4743    }
4744
4745    @Override
4746    public boolean startNextMatchingActivity(IBinder callingActivity,
4747            Intent intent, Bundle bOptions) {
4748        // Refuse possible leaked file descriptors
4749        if (intent != null && intent.hasFileDescriptors() == true) {
4750            throw new IllegalArgumentException("File descriptors passed in Intent");
4751        }
4752        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4753
4754        synchronized (this) {
4755            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4756            if (r == null) {
4757                ActivityOptions.abort(options);
4758                return false;
4759            }
4760            if (r.app == null || r.app.thread == null) {
4761                // The caller is not running...  d'oh!
4762                ActivityOptions.abort(options);
4763                return false;
4764            }
4765            intent = new Intent(intent);
4766            // The caller is not allowed to change the data.
4767            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4768            // And we are resetting to find the next component...
4769            intent.setComponent(null);
4770
4771            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4772
4773            ActivityInfo aInfo = null;
4774            try {
4775                List<ResolveInfo> resolves =
4776                    AppGlobals.getPackageManager().queryIntentActivities(
4777                            intent, r.resolvedType,
4778                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4779                            UserHandle.getCallingUserId()).getList();
4780
4781                // Look for the original activity in the list...
4782                final int N = resolves != null ? resolves.size() : 0;
4783                for (int i=0; i<N; i++) {
4784                    ResolveInfo rInfo = resolves.get(i);
4785                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4786                            && rInfo.activityInfo.name.equals(r.info.name)) {
4787                        // We found the current one...  the next matching is
4788                        // after it.
4789                        i++;
4790                        if (i<N) {
4791                            aInfo = resolves.get(i).activityInfo;
4792                        }
4793                        if (debug) {
4794                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4795                                    + "/" + r.info.name);
4796                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4797                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4798                        }
4799                        break;
4800                    }
4801                }
4802            } catch (RemoteException e) {
4803            }
4804
4805            if (aInfo == null) {
4806                // Nobody who is next!
4807                ActivityOptions.abort(options);
4808                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4809                return false;
4810            }
4811
4812            intent.setComponent(new ComponentName(
4813                    aInfo.applicationInfo.packageName, aInfo.name));
4814            intent.setFlags(intent.getFlags()&~(
4815                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4816                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4817                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4818                    Intent.FLAG_ACTIVITY_NEW_TASK));
4819
4820            // Okay now we need to start the new activity, replacing the
4821            // currently running activity.  This is a little tricky because
4822            // we want to start the new one as if the current one is finished,
4823            // but not finish the current one first so that there is no flicker.
4824            // And thus...
4825            final boolean wasFinishing = r.finishing;
4826            r.finishing = true;
4827
4828            // Propagate reply information over to the new activity.
4829            final ActivityRecord resultTo = r.resultTo;
4830            final String resultWho = r.resultWho;
4831            final int requestCode = r.requestCode;
4832            r.resultTo = null;
4833            if (resultTo != null) {
4834                resultTo.removeResultsLocked(r, resultWho, requestCode);
4835            }
4836
4837            final long origId = Binder.clearCallingIdentity();
4838            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4839                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4840                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4841                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4842                    false, false, null, null, null);
4843            Binder.restoreCallingIdentity(origId);
4844
4845            r.finishing = wasFinishing;
4846            if (res != ActivityManager.START_SUCCESS) {
4847                return false;
4848            }
4849            return true;
4850        }
4851    }
4852
4853    @Override
4854    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4855        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4856            String msg = "Permission Denial: startActivityFromRecents called without " +
4857                    START_TASKS_FROM_RECENTS;
4858            Slog.w(TAG, msg);
4859            throw new SecurityException(msg);
4860        }
4861        final long origId = Binder.clearCallingIdentity();
4862        try {
4863            synchronized (this) {
4864                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4865            }
4866        } finally {
4867            Binder.restoreCallingIdentity(origId);
4868        }
4869    }
4870
4871    final int startActivityInPackage(int uid, String callingPackage,
4872            Intent intent, String resolvedType, IBinder resultTo,
4873            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4874            IActivityContainer container, TaskRecord inTask) {
4875
4876        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4877                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4878
4879        // TODO: Switch to user app stacks here.
4880        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4881                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4882                null, null, null, bOptions, false, userId, container, inTask);
4883        return ret;
4884    }
4885
4886    @Override
4887    public final int startActivities(IApplicationThread caller, String callingPackage,
4888            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4889            int userId) {
4890        enforceNotIsolatedCaller("startActivities");
4891        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4892                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4893        // TODO: Switch to user app stacks here.
4894        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4895                resolvedTypes, resultTo, bOptions, userId);
4896        return ret;
4897    }
4898
4899    final int startActivitiesInPackage(int uid, String callingPackage,
4900            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4901            Bundle bOptions, int userId) {
4902
4903        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4904                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4905        // TODO: Switch to user app stacks here.
4906        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4907                resultTo, bOptions, userId);
4908        return ret;
4909    }
4910
4911    @Override
4912    public void reportActivityFullyDrawn(IBinder token) {
4913        synchronized (this) {
4914            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4915            if (r == null) {
4916                return;
4917            }
4918            r.reportFullyDrawnLocked();
4919        }
4920    }
4921
4922    @Override
4923    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4924        synchronized (this) {
4925            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4926            if (r == null) {
4927                return;
4928            }
4929            final long origId = Binder.clearCallingIdentity();
4930            try {
4931                r.setRequestedOrientation(requestedOrientation);
4932            } finally {
4933                Binder.restoreCallingIdentity(origId);
4934            }
4935        }
4936    }
4937
4938    @Override
4939    public int getRequestedOrientation(IBinder token) {
4940        synchronized (this) {
4941            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4942            if (r == null) {
4943                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4944            }
4945            return r.getRequestedOrientation();
4946        }
4947    }
4948
4949    @Override
4950    public final void requestActivityRelaunch(IBinder token) {
4951        synchronized(this) {
4952            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4953            if (r == null) {
4954                return;
4955            }
4956            final long origId = Binder.clearCallingIdentity();
4957            try {
4958                r.forceNewConfig = true;
4959                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4960                        true /* preserveWindow */);
4961            } finally {
4962                Binder.restoreCallingIdentity(origId);
4963            }
4964        }
4965    }
4966
4967    /**
4968     * This is the internal entry point for handling Activity.finish().
4969     *
4970     * @param token The Binder token referencing the Activity we want to finish.
4971     * @param resultCode Result code, if any, from this Activity.
4972     * @param resultData Result data (Intent), if any, from this Activity.
4973     * @param finishTask Whether to finish the task associated with this Activity.
4974     *
4975     * @return Returns true if the activity successfully finished, or false if it is still running.
4976     */
4977    @Override
4978    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4979            int finishTask) {
4980        // Refuse possible leaked file descriptors
4981        if (resultData != null && resultData.hasFileDescriptors() == true) {
4982            throw new IllegalArgumentException("File descriptors passed in Intent");
4983        }
4984
4985        synchronized(this) {
4986            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4987            if (r == null) {
4988                return true;
4989            }
4990            // Keep track of the root activity of the task before we finish it
4991            TaskRecord tr = r.getTask();
4992            ActivityRecord rootR = tr.getRootActivity();
4993            if (rootR == null) {
4994                Slog.w(TAG, "Finishing task with all activities already finished");
4995            }
4996            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4997            // finish.
4998            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4999                    mStackSupervisor.isLastLockedTask(tr)) {
5000                Slog.i(TAG, "Not finishing task in lock task mode");
5001                mStackSupervisor.showLockTaskToast();
5002                return false;
5003            }
5004            if (mController != null) {
5005                // Find the first activity that is not finishing.
5006                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5007                if (next != null) {
5008                    // ask watcher if this is allowed
5009                    boolean resumeOK = true;
5010                    try {
5011                        resumeOK = mController.activityResuming(next.packageName);
5012                    } catch (RemoteException e) {
5013                        mController = null;
5014                        Watchdog.getInstance().setActivityController(null);
5015                    }
5016
5017                    if (!resumeOK) {
5018                        Slog.i(TAG, "Not finishing activity because controller resumed");
5019                        return false;
5020                    }
5021                }
5022            }
5023            final long origId = Binder.clearCallingIdentity();
5024            try {
5025                boolean res;
5026                final boolean finishWithRootActivity =
5027                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5028                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5029                        || (finishWithRootActivity && r == rootR)) {
5030                    // If requested, remove the task that is associated to this activity only if it
5031                    // was the root activity in the task. The result code and data is ignored
5032                    // because we don't support returning them across task boundaries. Also, to
5033                    // keep backwards compatibility we remove the task from recents when finishing
5034                    // task with root activity.
5035                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5036                    if (!res) {
5037                        Slog.i(TAG, "Removing task failed to finish activity");
5038                    }
5039                } else {
5040                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5041                            resultData, "app-request", true);
5042                    if (!res) {
5043                        Slog.i(TAG, "Failed to finish by app-request");
5044                    }
5045                }
5046                return res;
5047            } finally {
5048                Binder.restoreCallingIdentity(origId);
5049            }
5050        }
5051    }
5052
5053    @Override
5054    public final void finishHeavyWeightApp() {
5055        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5056                != PackageManager.PERMISSION_GRANTED) {
5057            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5058                    + Binder.getCallingPid()
5059                    + ", uid=" + Binder.getCallingUid()
5060                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5061            Slog.w(TAG, msg);
5062            throw new SecurityException(msg);
5063        }
5064
5065        synchronized(this) {
5066            if (mHeavyWeightProcess == null) {
5067                return;
5068            }
5069
5070            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5071            for (int i = 0; i < activities.size(); i++) {
5072                ActivityRecord r = activities.get(i);
5073                if (!r.finishing && r.isInStackLocked()) {
5074                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5075                            null, "finish-heavy", true);
5076                }
5077            }
5078
5079            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5080                    mHeavyWeightProcess.userId, 0));
5081            mHeavyWeightProcess = null;
5082        }
5083    }
5084
5085    @Override
5086    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5087            String message) {
5088        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5089                != PackageManager.PERMISSION_GRANTED) {
5090            String msg = "Permission Denial: crashApplication() from pid="
5091                    + Binder.getCallingPid()
5092                    + ", uid=" + Binder.getCallingUid()
5093                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5094            Slog.w(TAG, msg);
5095            throw new SecurityException(msg);
5096        }
5097
5098        synchronized(this) {
5099            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5100        }
5101    }
5102
5103    @Override
5104    public final void finishSubActivity(IBinder token, String resultWho,
5105            int requestCode) {
5106        synchronized(this) {
5107            final long origId = Binder.clearCallingIdentity();
5108            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5109            if (r != null) {
5110                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5111            }
5112            Binder.restoreCallingIdentity(origId);
5113        }
5114    }
5115
5116    @Override
5117    public boolean finishActivityAffinity(IBinder token) {
5118        synchronized(this) {
5119            final long origId = Binder.clearCallingIdentity();
5120            try {
5121                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5122                if (r == null) {
5123                    return false;
5124                }
5125
5126                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5127                // can finish.
5128                final TaskRecord task = r.getTask();
5129                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5130                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5131                    mStackSupervisor.showLockTaskToast();
5132                    return false;
5133                }
5134                return task.getStack().finishActivityAffinityLocked(r);
5135            } finally {
5136                Binder.restoreCallingIdentity(origId);
5137            }
5138        }
5139    }
5140
5141    @Override
5142    public void finishVoiceTask(IVoiceInteractionSession session) {
5143        synchronized (this) {
5144            final long origId = Binder.clearCallingIdentity();
5145            try {
5146                // TODO: VI Consider treating local voice interactions and voice tasks
5147                // differently here
5148                mStackSupervisor.finishVoiceTask(session);
5149            } finally {
5150                Binder.restoreCallingIdentity(origId);
5151            }
5152        }
5153
5154    }
5155
5156    @Override
5157    public boolean releaseActivityInstance(IBinder token) {
5158        synchronized(this) {
5159            final long origId = Binder.clearCallingIdentity();
5160            try {
5161                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5162                if (r == null) {
5163                    return false;
5164                }
5165                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5166            } finally {
5167                Binder.restoreCallingIdentity(origId);
5168            }
5169        }
5170    }
5171
5172    @Override
5173    public void releaseSomeActivities(IApplicationThread appInt) {
5174        synchronized(this) {
5175            final long origId = Binder.clearCallingIdentity();
5176            try {
5177                ProcessRecord app = getRecordForAppLocked(appInt);
5178                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5179            } finally {
5180                Binder.restoreCallingIdentity(origId);
5181            }
5182        }
5183    }
5184
5185    @Override
5186    public boolean willActivityBeVisible(IBinder token) {
5187        synchronized(this) {
5188            ActivityStack stack = ActivityRecord.getStackLocked(token);
5189            if (stack != null) {
5190                return stack.willActivityBeVisibleLocked(token);
5191            }
5192            return false;
5193        }
5194    }
5195
5196    @Override
5197    public void overridePendingTransition(IBinder token, String packageName,
5198            int enterAnim, int exitAnim) {
5199        synchronized(this) {
5200            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5201            if (self == null) {
5202                return;
5203            }
5204
5205            final long origId = Binder.clearCallingIdentity();
5206
5207            if (self.state == ActivityState.RESUMED
5208                    || self.state == ActivityState.PAUSING) {
5209                mWindowManager.overridePendingAppTransition(packageName,
5210                        enterAnim, exitAnim, null);
5211            }
5212
5213            Binder.restoreCallingIdentity(origId);
5214        }
5215    }
5216
5217    /**
5218     * Main function for removing an existing process from the activity manager
5219     * as a result of that process going away.  Clears out all connections
5220     * to the process.
5221     */
5222    private final void handleAppDiedLocked(ProcessRecord app,
5223            boolean restarting, boolean allowRestart) {
5224        int pid = app.pid;
5225        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5226                false /*replacingPid*/);
5227        if (!kept && !restarting) {
5228            removeLruProcessLocked(app);
5229            if (pid > 0) {
5230                ProcessList.remove(pid);
5231            }
5232        }
5233
5234        if (mProfileProc == app) {
5235            clearProfilerLocked();
5236        }
5237
5238        // Remove this application's activities from active lists.
5239        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5240
5241        app.activities.clear();
5242
5243        if (app.instr != null) {
5244            Slog.w(TAG, "Crash of app " + app.processName
5245                  + " running instrumentation " + app.instr.mClass);
5246            Bundle info = new Bundle();
5247            info.putString("shortMsg", "Process crashed.");
5248            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5249        }
5250
5251        mWindowManager.deferSurfaceLayout();
5252        try {
5253            if (!restarting && hasVisibleActivities
5254                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5255                // If there was nothing to resume, and we are not already restarting this process, but
5256                // there is a visible activity that is hosted by the process...  then make sure all
5257                // visible activities are running, taking care of restarting this process.
5258                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5259            }
5260        } finally {
5261            mWindowManager.continueSurfaceLayout();
5262        }
5263    }
5264
5265    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5266        final IBinder threadBinder = thread.asBinder();
5267        // Find the application record.
5268        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5269            final ProcessRecord rec = mLruProcesses.get(i);
5270            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5271                return i;
5272            }
5273        }
5274        return -1;
5275    }
5276
5277    final ProcessRecord getRecordForAppLocked(
5278            IApplicationThread thread) {
5279        if (thread == null) {
5280            return null;
5281        }
5282
5283        int appIndex = getLRURecordIndexForAppLocked(thread);
5284        if (appIndex >= 0) {
5285            return mLruProcesses.get(appIndex);
5286        }
5287
5288        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5289        // double-check that.
5290        final IBinder threadBinder = thread.asBinder();
5291        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5292        for (int i = pmap.size()-1; i >= 0; i--) {
5293            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5294            for (int j = procs.size()-1; j >= 0; j--) {
5295                final ProcessRecord proc = procs.valueAt(j);
5296                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5297                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5298                            + proc);
5299                    return proc;
5300                }
5301            }
5302        }
5303
5304        return null;
5305    }
5306
5307    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5308        // If there are no longer any background processes running,
5309        // and the app that died was not running instrumentation,
5310        // then tell everyone we are now low on memory.
5311        boolean haveBg = false;
5312        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5313            ProcessRecord rec = mLruProcesses.get(i);
5314            if (rec.thread != null
5315                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5316                haveBg = true;
5317                break;
5318            }
5319        }
5320
5321        if (!haveBg) {
5322            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5323            if (doReport) {
5324                long now = SystemClock.uptimeMillis();
5325                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5326                    doReport = false;
5327                } else {
5328                    mLastMemUsageReportTime = now;
5329                }
5330            }
5331            final ArrayList<ProcessMemInfo> memInfos
5332                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5333            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5334            long now = SystemClock.uptimeMillis();
5335            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5336                ProcessRecord rec = mLruProcesses.get(i);
5337                if (rec == dyingProc || rec.thread == null) {
5338                    continue;
5339                }
5340                if (doReport) {
5341                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5342                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5343                }
5344                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5345                    // The low memory report is overriding any current
5346                    // state for a GC request.  Make sure to do
5347                    // heavy/important/visible/foreground processes first.
5348                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5349                        rec.lastRequestedGc = 0;
5350                    } else {
5351                        rec.lastRequestedGc = rec.lastLowMemory;
5352                    }
5353                    rec.reportLowMemory = true;
5354                    rec.lastLowMemory = now;
5355                    mProcessesToGc.remove(rec);
5356                    addProcessToGcListLocked(rec);
5357                }
5358            }
5359            if (doReport) {
5360                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5361                mHandler.sendMessage(msg);
5362            }
5363            scheduleAppGcsLocked();
5364        }
5365    }
5366
5367    final void appDiedLocked(ProcessRecord app) {
5368       appDiedLocked(app, app.pid, app.thread, false);
5369    }
5370
5371    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5372            boolean fromBinderDied) {
5373        // First check if this ProcessRecord is actually active for the pid.
5374        synchronized (mPidsSelfLocked) {
5375            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5376            if (curProc != app) {
5377                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5378                return;
5379            }
5380        }
5381
5382        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5383        synchronized (stats) {
5384            stats.noteProcessDiedLocked(app.info.uid, pid);
5385        }
5386
5387        if (!app.killed) {
5388            if (!fromBinderDied) {
5389                killProcessQuiet(pid);
5390            }
5391            killProcessGroup(app.uid, pid);
5392            app.killed = true;
5393        }
5394
5395        // Clean up already done if the process has been re-started.
5396        if (app.pid == pid && app.thread != null &&
5397                app.thread.asBinder() == thread.asBinder()) {
5398            boolean doLowMem = app.instr == null;
5399            boolean doOomAdj = doLowMem;
5400            if (!app.killedByAm) {
5401                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5402                        + ") has died");
5403                mAllowLowerMemLevel = true;
5404            } else {
5405                // Note that we always want to do oom adj to update our state with the
5406                // new number of procs.
5407                mAllowLowerMemLevel = false;
5408                doLowMem = false;
5409            }
5410            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5411            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5412                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5413            handleAppDiedLocked(app, false, true);
5414
5415            if (doOomAdj) {
5416                updateOomAdjLocked();
5417            }
5418            if (doLowMem) {
5419                doLowMemReportIfNeededLocked(app);
5420            }
5421        } else if (app.pid != pid) {
5422            // A new process has already been started.
5423            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5424                    + ") has died and restarted (pid " + app.pid + ").");
5425            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5426        } else if (DEBUG_PROCESSES) {
5427            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5428                    + thread.asBinder());
5429        }
5430    }
5431
5432    /**
5433     * If a stack trace dump file is configured, dump process stack traces.
5434     * @param clearTraces causes the dump file to be erased prior to the new
5435     *    traces being written, if true; when false, the new traces will be
5436     *    appended to any existing file content.
5437     * @param firstPids of dalvik VM processes to dump stack traces for first
5438     * @param lastPids of dalvik VM processes to dump stack traces for last
5439     * @param nativePids optional list of native pids to dump stack crawls
5440     * @return file containing stack traces, or null if no dump file is configured
5441     */
5442    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5443            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5444            ArrayList<Integer> nativePids) {
5445        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5446        if (tracesPath == null || tracesPath.length() == 0) {
5447            return null;
5448        }
5449
5450        File tracesFile = new File(tracesPath);
5451        try {
5452            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5453            tracesFile.createNewFile();
5454            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5455        } catch (IOException e) {
5456            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5457            return null;
5458        }
5459
5460        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativePids);
5461        return tracesFile;
5462    }
5463
5464    public static class DumpStackFileObserver extends FileObserver {
5465        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5466        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5467        static final int TRACE_DUMP_TIMEOUT_SECONDS = TRACE_DUMP_TIMEOUT_MS / 1000;
5468
5469        private final String mTracesPath;
5470        private boolean mClosed;
5471
5472        public DumpStackFileObserver(String tracesPath) {
5473            super(tracesPath, FileObserver.CLOSE_WRITE);
5474            mTracesPath = tracesPath;
5475        }
5476
5477        @Override
5478        public synchronized void onEvent(int event, String path) {
5479            mClosed = true;
5480            notify();
5481        }
5482
5483        public void dumpWithTimeout(int pid) {
5484            sendSignal(pid, SIGNAL_QUIT);
5485            synchronized (this) {
5486                try {
5487                    wait(TRACE_DUMP_TIMEOUT_MS); // Wait for traces file to be closed.
5488                } catch (InterruptedException e) {
5489                    Slog.wtf(TAG, e);
5490                }
5491            }
5492            if (!mClosed) {
5493                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5494                       ". Attempting native stack collection.");
5495                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath, TRACE_DUMP_TIMEOUT_SECONDS);
5496            }
5497            mClosed = false;
5498        }
5499    }
5500
5501    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5502            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5503            ArrayList<Integer> nativePids) {
5504        // Use a FileObserver to detect when traces finish writing.
5505        // The order of traces is considered important to maintain for legibility.
5506        DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
5507        try {
5508            observer.startWatching();
5509
5510            // First collect all of the stacks of the most important pids.
5511            if (firstPids != null) {
5512                int num = firstPids.size();
5513                for (int i = 0; i < num; i++) {
5514                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5515                            + firstPids.get(i));
5516                    final long sime = SystemClock.elapsedRealtime();
5517                    observer.dumpWithTimeout(firstPids.get(i));
5518                    if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5519                            + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5520                }
5521            }
5522
5523            // Next collect the stacks of the native pids
5524            if (nativePids != null) {
5525                for (int pid : nativePids) {
5526                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5527                    final long sime = SystemClock.elapsedRealtime();
5528
5529                    Debug.dumpNativeBacktraceToFileTimeout(
5530                            pid, tracesPath, DumpStackFileObserver.TRACE_DUMP_TIMEOUT_SECONDS);
5531                    if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5532                            + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5533                }
5534            }
5535
5536            // Lastly, measure CPU usage.
5537            if (processCpuTracker != null) {
5538                processCpuTracker.init();
5539                System.gc();
5540                processCpuTracker.update();
5541                try {
5542                    synchronized (processCpuTracker) {
5543                        processCpuTracker.wait(500); // measure over 1/2 second.
5544                    }
5545                } catch (InterruptedException e) {
5546                }
5547                processCpuTracker.update();
5548
5549                // We'll take the stack crawls of just the top apps using CPU.
5550                final int N = processCpuTracker.countWorkingStats();
5551                int numProcs = 0;
5552                for (int i=0; i<N && numProcs<5; i++) {
5553                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5554                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5555                        numProcs++;
5556                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5557                                + stats.pid);
5558                        final long stime = SystemClock.elapsedRealtime();
5559                        observer.dumpWithTimeout(stats.pid);
5560                        if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5561                                + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5562                    } else if (DEBUG_ANR) {
5563                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5564                                + stats.pid);
5565                    }
5566                }
5567            }
5568        } finally {
5569            observer.stopWatching();
5570        }
5571    }
5572
5573    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5574        if (true || IS_USER_BUILD) {
5575            return;
5576        }
5577        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5578        if (tracesPath == null || tracesPath.length() == 0) {
5579            return;
5580        }
5581
5582        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5583        StrictMode.allowThreadDiskWrites();
5584        try {
5585            final File tracesFile = new File(tracesPath);
5586            final File tracesDir = tracesFile.getParentFile();
5587            final File tracesTmp = new File(tracesDir, "__tmp__");
5588            try {
5589                if (tracesFile.exists()) {
5590                    tracesTmp.delete();
5591                    tracesFile.renameTo(tracesTmp);
5592                }
5593                StringBuilder sb = new StringBuilder();
5594                Time tobj = new Time();
5595                tobj.set(System.currentTimeMillis());
5596                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5597                sb.append(": ");
5598                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5599                sb.append(" since ");
5600                sb.append(msg);
5601                FileOutputStream fos = new FileOutputStream(tracesFile);
5602                fos.write(sb.toString().getBytes());
5603                if (app == null) {
5604                    fos.write("\n*** No application process!".getBytes());
5605                }
5606                fos.close();
5607                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5608            } catch (IOException e) {
5609                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5610                return;
5611            }
5612
5613            if (app != null) {
5614                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5615                firstPids.add(app.pid);
5616                dumpStackTraces(tracesPath, firstPids, null, null, null);
5617            }
5618
5619            File lastTracesFile = null;
5620            File curTracesFile = null;
5621            for (int i=9; i>=0; i--) {
5622                String name = String.format(Locale.US, "slow%02d.txt", i);
5623                curTracesFile = new File(tracesDir, name);
5624                if (curTracesFile.exists()) {
5625                    if (lastTracesFile != null) {
5626                        curTracesFile.renameTo(lastTracesFile);
5627                    } else {
5628                        curTracesFile.delete();
5629                    }
5630                }
5631                lastTracesFile = curTracesFile;
5632            }
5633            tracesFile.renameTo(curTracesFile);
5634            if (tracesTmp.exists()) {
5635                tracesTmp.renameTo(tracesFile);
5636            }
5637        } finally {
5638            StrictMode.setThreadPolicy(oldPolicy);
5639        }
5640    }
5641
5642    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5643        if (!mLaunchWarningShown) {
5644            mLaunchWarningShown = true;
5645            mUiHandler.post(new Runnable() {
5646                @Override
5647                public void run() {
5648                    synchronized (ActivityManagerService.this) {
5649                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5650                        d.show();
5651                        mUiHandler.postDelayed(new Runnable() {
5652                            @Override
5653                            public void run() {
5654                                synchronized (ActivityManagerService.this) {
5655                                    d.dismiss();
5656                                    mLaunchWarningShown = false;
5657                                }
5658                            }
5659                        }, 4000);
5660                    }
5661                }
5662            });
5663        }
5664    }
5665
5666    @Override
5667    public boolean clearApplicationUserData(final String packageName,
5668            final IPackageDataObserver observer, int userId) {
5669        enforceNotIsolatedCaller("clearApplicationUserData");
5670        int uid = Binder.getCallingUid();
5671        int pid = Binder.getCallingPid();
5672        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5673                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5674
5675
5676        long callingId = Binder.clearCallingIdentity();
5677        try {
5678            IPackageManager pm = AppGlobals.getPackageManager();
5679            int pkgUid = -1;
5680            synchronized(this) {
5681                if (getPackageManagerInternalLocked().isPackageDataProtected(
5682                        userId, packageName)) {
5683                    throw new SecurityException(
5684                            "Cannot clear data for a protected package: " + packageName);
5685                }
5686
5687                try {
5688                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5689                } catch (RemoteException e) {
5690                }
5691                if (pkgUid == -1) {
5692                    Slog.w(TAG, "Invalid packageName: " + packageName);
5693                    if (observer != null) {
5694                        try {
5695                            observer.onRemoveCompleted(packageName, false);
5696                        } catch (RemoteException e) {
5697                            Slog.i(TAG, "Observer no longer exists.");
5698                        }
5699                    }
5700                    return false;
5701                }
5702                if (uid == pkgUid || checkComponentPermission(
5703                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5704                        pid, uid, -1, true)
5705                        == PackageManager.PERMISSION_GRANTED) {
5706                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5707                } else {
5708                    throw new SecurityException("PID " + pid + " does not have permission "
5709                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5710                                    + " of package " + packageName);
5711                }
5712
5713                // Remove all tasks match the cleared application package and user
5714                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5715                    final TaskRecord tr = mRecentTasks.get(i);
5716                    final String taskPackageName =
5717                            tr.getBaseIntent().getComponent().getPackageName();
5718                    if (tr.userId != userId) continue;
5719                    if (!taskPackageName.equals(packageName)) continue;
5720                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5721                }
5722            }
5723
5724            final int pkgUidF = pkgUid;
5725            final int userIdF = userId;
5726            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5727                @Override
5728                public void onRemoveCompleted(String packageName, boolean succeeded)
5729                        throws RemoteException {
5730                    synchronized (ActivityManagerService.this) {
5731                        finishForceStopPackageLocked(packageName, pkgUidF);
5732                    }
5733
5734                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5735                            Uri.fromParts("package", packageName, null));
5736                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5737                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5738                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5739                    broadcastIntentInPackage("android", SYSTEM_UID, intent,
5740                            null, null, 0, null, null, null, null, false, false, userIdF);
5741
5742                    if (observer != null) {
5743                        observer.onRemoveCompleted(packageName, succeeded);
5744                    }
5745                }
5746            };
5747
5748            try {
5749                // Clear application user data
5750                pm.clearApplicationUserData(packageName, localObserver, userId);
5751
5752                synchronized(this) {
5753                    // Remove all permissions granted from/to this package
5754                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5755                }
5756
5757                // Reset notification settings.
5758                INotificationManager inm = NotificationManager.getService();
5759                inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5760            } catch (RemoteException e) {
5761            }
5762        } finally {
5763            Binder.restoreCallingIdentity(callingId);
5764        }
5765        return true;
5766    }
5767
5768    @Override
5769    public void killBackgroundProcesses(final String packageName, int userId) {
5770        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5771                != PackageManager.PERMISSION_GRANTED &&
5772                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5773                        != PackageManager.PERMISSION_GRANTED) {
5774            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5775                    + Binder.getCallingPid()
5776                    + ", uid=" + Binder.getCallingUid()
5777                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5778            Slog.w(TAG, msg);
5779            throw new SecurityException(msg);
5780        }
5781
5782        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5783                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5784        long callingId = Binder.clearCallingIdentity();
5785        try {
5786            IPackageManager pm = AppGlobals.getPackageManager();
5787            synchronized(this) {
5788                int appId = -1;
5789                try {
5790                    appId = UserHandle.getAppId(
5791                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5792                } catch (RemoteException e) {
5793                }
5794                if (appId == -1) {
5795                    Slog.w(TAG, "Invalid packageName: " + packageName);
5796                    return;
5797                }
5798                killPackageProcessesLocked(packageName, appId, userId,
5799                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5800            }
5801        } finally {
5802            Binder.restoreCallingIdentity(callingId);
5803        }
5804    }
5805
5806    @Override
5807    public void killAllBackgroundProcesses() {
5808        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5809                != PackageManager.PERMISSION_GRANTED) {
5810            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5811                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5812                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5813            Slog.w(TAG, msg);
5814            throw new SecurityException(msg);
5815        }
5816
5817        final long callingId = Binder.clearCallingIdentity();
5818        try {
5819            synchronized (this) {
5820                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5821                final int NP = mProcessNames.getMap().size();
5822                for (int ip = 0; ip < NP; ip++) {
5823                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5824                    final int NA = apps.size();
5825                    for (int ia = 0; ia < NA; ia++) {
5826                        final ProcessRecord app = apps.valueAt(ia);
5827                        if (app.persistent) {
5828                            // We don't kill persistent processes.
5829                            continue;
5830                        }
5831                        if (app.removed) {
5832                            procs.add(app);
5833                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5834                            app.removed = true;
5835                            procs.add(app);
5836                        }
5837                    }
5838                }
5839
5840                final int N = procs.size();
5841                for (int i = 0; i < N; i++) {
5842                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5843                }
5844
5845                mAllowLowerMemLevel = true;
5846
5847                updateOomAdjLocked();
5848                doLowMemReportIfNeededLocked(null);
5849            }
5850        } finally {
5851            Binder.restoreCallingIdentity(callingId);
5852        }
5853    }
5854
5855    /**
5856     * Kills all background processes, except those matching any of the
5857     * specified properties.
5858     *
5859     * @param minTargetSdk the target SDK version at or above which to preserve
5860     *                     processes, or {@code -1} to ignore the target SDK
5861     * @param maxProcState the process state at or below which to preserve
5862     *                     processes, or {@code -1} to ignore the process state
5863     */
5864    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5865        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5866                != PackageManager.PERMISSION_GRANTED) {
5867            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5868                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5869                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5870            Slog.w(TAG, msg);
5871            throw new SecurityException(msg);
5872        }
5873
5874        final long callingId = Binder.clearCallingIdentity();
5875        try {
5876            synchronized (this) {
5877                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5878                final int NP = mProcessNames.getMap().size();
5879                for (int ip = 0; ip < NP; ip++) {
5880                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5881                    final int NA = apps.size();
5882                    for (int ia = 0; ia < NA; ia++) {
5883                        final ProcessRecord app = apps.valueAt(ia);
5884                        if (app.removed) {
5885                            procs.add(app);
5886                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5887                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5888                            app.removed = true;
5889                            procs.add(app);
5890                        }
5891                    }
5892                }
5893
5894                final int N = procs.size();
5895                for (int i = 0; i < N; i++) {
5896                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5897                }
5898            }
5899        } finally {
5900            Binder.restoreCallingIdentity(callingId);
5901        }
5902    }
5903
5904    @Override
5905    public void forceStopPackage(final String packageName, int userId) {
5906        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5907                != PackageManager.PERMISSION_GRANTED) {
5908            String msg = "Permission Denial: forceStopPackage() from pid="
5909                    + Binder.getCallingPid()
5910                    + ", uid=" + Binder.getCallingUid()
5911                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5912            Slog.w(TAG, msg);
5913            throw new SecurityException(msg);
5914        }
5915        final int callingPid = Binder.getCallingPid();
5916        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5917                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5918        long callingId = Binder.clearCallingIdentity();
5919        try {
5920            IPackageManager pm = AppGlobals.getPackageManager();
5921            synchronized(this) {
5922                int[] users = userId == UserHandle.USER_ALL
5923                        ? mUserController.getUsers() : new int[] { userId };
5924                for (int user : users) {
5925                    int pkgUid = -1;
5926                    try {
5927                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5928                                user);
5929                    } catch (RemoteException e) {
5930                    }
5931                    if (pkgUid == -1) {
5932                        Slog.w(TAG, "Invalid packageName: " + packageName);
5933                        continue;
5934                    }
5935                    try {
5936                        pm.setPackageStoppedState(packageName, true, user);
5937                    } catch (RemoteException e) {
5938                    } catch (IllegalArgumentException e) {
5939                        Slog.w(TAG, "Failed trying to unstop package "
5940                                + packageName + ": " + e);
5941                    }
5942                    if (mUserController.isUserRunningLocked(user, 0)) {
5943                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5944                        finishForceStopPackageLocked(packageName, pkgUid);
5945                    }
5946                }
5947            }
5948        } finally {
5949            Binder.restoreCallingIdentity(callingId);
5950        }
5951    }
5952
5953    @Override
5954    public void addPackageDependency(String packageName) {
5955        synchronized (this) {
5956            int callingPid = Binder.getCallingPid();
5957            if (callingPid == myPid()) {
5958                //  Yeah, um, no.
5959                return;
5960            }
5961            ProcessRecord proc;
5962            synchronized (mPidsSelfLocked) {
5963                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5964            }
5965            if (proc != null) {
5966                if (proc.pkgDeps == null) {
5967                    proc.pkgDeps = new ArraySet<String>(1);
5968                }
5969                proc.pkgDeps.add(packageName);
5970            }
5971        }
5972    }
5973
5974    /*
5975     * The pkg name and app id have to be specified.
5976     */
5977    @Override
5978    public void killApplication(String pkg, int appId, int userId, String reason) {
5979        if (pkg == null) {
5980            return;
5981        }
5982        // Make sure the uid is valid.
5983        if (appId < 0) {
5984            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5985            return;
5986        }
5987        int callerUid = Binder.getCallingUid();
5988        // Only the system server can kill an application
5989        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
5990            // Post an aysnc message to kill the application
5991            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5992            msg.arg1 = appId;
5993            msg.arg2 = userId;
5994            Bundle bundle = new Bundle();
5995            bundle.putString("pkg", pkg);
5996            bundle.putString("reason", reason);
5997            msg.obj = bundle;
5998            mHandler.sendMessage(msg);
5999        } else {
6000            throw new SecurityException(callerUid + " cannot kill pkg: " +
6001                    pkg);
6002        }
6003    }
6004
6005    @Override
6006    public void closeSystemDialogs(String reason) {
6007        enforceNotIsolatedCaller("closeSystemDialogs");
6008
6009        final int pid = Binder.getCallingPid();
6010        final int uid = Binder.getCallingUid();
6011        final long origId = Binder.clearCallingIdentity();
6012        try {
6013            synchronized (this) {
6014                // Only allow this from foreground processes, so that background
6015                // applications can't abuse it to prevent system UI from being shown.
6016                if (uid >= FIRST_APPLICATION_UID) {
6017                    ProcessRecord proc;
6018                    synchronized (mPidsSelfLocked) {
6019                        proc = mPidsSelfLocked.get(pid);
6020                    }
6021                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6022                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6023                                + " from background process " + proc);
6024                        return;
6025                    }
6026                }
6027                closeSystemDialogsLocked(reason);
6028            }
6029        } finally {
6030            Binder.restoreCallingIdentity(origId);
6031        }
6032    }
6033
6034    void closeSystemDialogsLocked(String reason) {
6035        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6036        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6037                | Intent.FLAG_RECEIVER_FOREGROUND);
6038        if (reason != null) {
6039            intent.putExtra("reason", reason);
6040        }
6041        mWindowManager.closeSystemDialogs(reason);
6042
6043        mStackSupervisor.closeSystemDialogsLocked();
6044
6045        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6046                AppOpsManager.OP_NONE, null, false, false,
6047                -1, SYSTEM_UID, UserHandle.USER_ALL);
6048    }
6049
6050    @Override
6051    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6052        enforceNotIsolatedCaller("getProcessMemoryInfo");
6053        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6054        for (int i=pids.length-1; i>=0; i--) {
6055            ProcessRecord proc;
6056            int oomAdj;
6057            synchronized (this) {
6058                synchronized (mPidsSelfLocked) {
6059                    proc = mPidsSelfLocked.get(pids[i]);
6060                    oomAdj = proc != null ? proc.setAdj : 0;
6061                }
6062            }
6063            infos[i] = new Debug.MemoryInfo();
6064            Debug.getMemoryInfo(pids[i], infos[i]);
6065            if (proc != null) {
6066                synchronized (this) {
6067                    if (proc.thread != null && proc.setAdj == oomAdj) {
6068                        // Record this for posterity if the process has been stable.
6069                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6070                                infos[i].getTotalUss(), false, proc.pkgList);
6071                    }
6072                }
6073            }
6074        }
6075        return infos;
6076    }
6077
6078    @Override
6079    public long[] getProcessPss(int[] pids) {
6080        enforceNotIsolatedCaller("getProcessPss");
6081        long[] pss = new long[pids.length];
6082        for (int i=pids.length-1; i>=0; i--) {
6083            ProcessRecord proc;
6084            int oomAdj;
6085            synchronized (this) {
6086                synchronized (mPidsSelfLocked) {
6087                    proc = mPidsSelfLocked.get(pids[i]);
6088                    oomAdj = proc != null ? proc.setAdj : 0;
6089                }
6090            }
6091            long[] tmpUss = new long[1];
6092            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6093            if (proc != null) {
6094                synchronized (this) {
6095                    if (proc.thread != null && proc.setAdj == oomAdj) {
6096                        // Record this for posterity if the process has been stable.
6097                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6098                    }
6099                }
6100            }
6101        }
6102        return pss;
6103    }
6104
6105    @Override
6106    public void killApplicationProcess(String processName, int uid) {
6107        if (processName == null) {
6108            return;
6109        }
6110
6111        int callerUid = Binder.getCallingUid();
6112        // Only the system server can kill an application
6113        if (callerUid == SYSTEM_UID) {
6114            synchronized (this) {
6115                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6116                if (app != null && app.thread != null) {
6117                    try {
6118                        app.thread.scheduleSuicide();
6119                    } catch (RemoteException e) {
6120                        // If the other end already died, then our work here is done.
6121                    }
6122                } else {
6123                    Slog.w(TAG, "Process/uid not found attempting kill of "
6124                            + processName + " / " + uid);
6125                }
6126            }
6127        } else {
6128            throw new SecurityException(callerUid + " cannot kill app process: " +
6129                    processName);
6130        }
6131    }
6132
6133    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6134        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6135                false, true, false, false, UserHandle.getUserId(uid), reason);
6136    }
6137
6138    private void finishForceStopPackageLocked(final String packageName, int uid) {
6139        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6140                Uri.fromParts("package", packageName, null));
6141        if (!mProcessesReady) {
6142            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6143                    | Intent.FLAG_RECEIVER_FOREGROUND);
6144        }
6145        intent.putExtra(Intent.EXTRA_UID, uid);
6146        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6147        broadcastIntentLocked(null, null, intent,
6148                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6149                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6150    }
6151
6152
6153    private final boolean killPackageProcessesLocked(String packageName, int appId,
6154            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6155            boolean doit, boolean evenPersistent, String reason) {
6156        ArrayList<ProcessRecord> procs = new ArrayList<>();
6157
6158        // Remove all processes this package may have touched: all with the
6159        // same UID (except for the system or root user), and all whose name
6160        // matches the package name.
6161        final int NP = mProcessNames.getMap().size();
6162        for (int ip=0; ip<NP; ip++) {
6163            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6164            final int NA = apps.size();
6165            for (int ia=0; ia<NA; ia++) {
6166                ProcessRecord app = apps.valueAt(ia);
6167                if (app.persistent && !evenPersistent) {
6168                    // we don't kill persistent processes
6169                    continue;
6170                }
6171                if (app.removed) {
6172                    if (doit) {
6173                        procs.add(app);
6174                    }
6175                    continue;
6176                }
6177
6178                // Skip process if it doesn't meet our oom adj requirement.
6179                if (app.setAdj < minOomAdj) {
6180                    continue;
6181                }
6182
6183                // If no package is specified, we call all processes under the
6184                // give user id.
6185                if (packageName == null) {
6186                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6187                        continue;
6188                    }
6189                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6190                        continue;
6191                    }
6192                // Package has been specified, we want to hit all processes
6193                // that match it.  We need to qualify this by the processes
6194                // that are running under the specified app and user ID.
6195                } else {
6196                    final boolean isDep = app.pkgDeps != null
6197                            && app.pkgDeps.contains(packageName);
6198                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6199                        continue;
6200                    }
6201                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6202                        continue;
6203                    }
6204                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6205                        continue;
6206                    }
6207                }
6208
6209                // Process has passed all conditions, kill it!
6210                if (!doit) {
6211                    return true;
6212                }
6213                app.removed = true;
6214                procs.add(app);
6215            }
6216        }
6217
6218        int N = procs.size();
6219        for (int i=0; i<N; i++) {
6220            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6221        }
6222        updateOomAdjLocked();
6223        return N > 0;
6224    }
6225
6226    private void cleanupDisabledPackageComponentsLocked(
6227            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6228
6229        Set<String> disabledClasses = null;
6230        boolean packageDisabled = false;
6231        IPackageManager pm = AppGlobals.getPackageManager();
6232
6233        if (changedClasses == null) {
6234            // Nothing changed...
6235            return;
6236        }
6237
6238        // Determine enable/disable state of the package and its components.
6239        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6240        for (int i = changedClasses.length - 1; i >= 0; i--) {
6241            final String changedClass = changedClasses[i];
6242
6243            if (changedClass.equals(packageName)) {
6244                try {
6245                    // Entire package setting changed
6246                    enabled = pm.getApplicationEnabledSetting(packageName,
6247                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6248                } catch (Exception e) {
6249                    // No such package/component; probably racing with uninstall.  In any
6250                    // event it means we have nothing further to do here.
6251                    return;
6252                }
6253                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6254                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6255                if (packageDisabled) {
6256                    // Entire package is disabled.
6257                    // No need to continue to check component states.
6258                    disabledClasses = null;
6259                    break;
6260                }
6261            } else {
6262                try {
6263                    enabled = pm.getComponentEnabledSetting(
6264                            new ComponentName(packageName, changedClass),
6265                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6266                } catch (Exception e) {
6267                    // As above, probably racing with uninstall.
6268                    return;
6269                }
6270                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6271                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6272                    if (disabledClasses == null) {
6273                        disabledClasses = new ArraySet<>(changedClasses.length);
6274                    }
6275                    disabledClasses.add(changedClass);
6276                }
6277            }
6278        }
6279
6280        if (!packageDisabled && disabledClasses == null) {
6281            // Nothing to do here...
6282            return;
6283        }
6284
6285        // Clean-up disabled activities.
6286        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6287                packageName, disabledClasses, true, false, userId) && mBooted) {
6288            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6289            mStackSupervisor.scheduleIdleLocked();
6290        }
6291
6292        // Clean-up disabled tasks
6293        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6294
6295        // Clean-up disabled services.
6296        mServices.bringDownDisabledPackageServicesLocked(
6297                packageName, disabledClasses, userId, false, killProcess, true);
6298
6299        // Clean-up disabled providers.
6300        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6301        mProviderMap.collectPackageProvidersLocked(
6302                packageName, disabledClasses, true, false, userId, providers);
6303        for (int i = providers.size() - 1; i >= 0; i--) {
6304            removeDyingProviderLocked(null, providers.get(i), true);
6305        }
6306
6307        // Clean-up disabled broadcast receivers.
6308        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6309            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6310                    packageName, disabledClasses, userId, true);
6311        }
6312
6313    }
6314
6315    final boolean clearBroadcastQueueForUserLocked(int userId) {
6316        boolean didSomething = false;
6317        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6318            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6319                    null, null, userId, true);
6320        }
6321        return didSomething;
6322    }
6323
6324    final boolean forceStopPackageLocked(String packageName, int appId,
6325            boolean callerWillRestart, boolean purgeCache, boolean doit,
6326            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6327        int i;
6328
6329        if (userId == UserHandle.USER_ALL && packageName == null) {
6330            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6331        }
6332
6333        if (appId < 0 && packageName != null) {
6334            try {
6335                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6336                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6337            } catch (RemoteException e) {
6338            }
6339        }
6340
6341        if (doit) {
6342            if (packageName != null) {
6343                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6344                        + " user=" + userId + ": " + reason);
6345            } else {
6346                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6347            }
6348
6349            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6350        }
6351
6352        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6353                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6354                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6355
6356        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6357
6358        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6359                packageName, null, doit, evenPersistent, userId)) {
6360            if (!doit) {
6361                return true;
6362            }
6363            didSomething = true;
6364        }
6365
6366        if (mServices.bringDownDisabledPackageServicesLocked(
6367                packageName, null, userId, evenPersistent, true, doit)) {
6368            if (!doit) {
6369                return true;
6370            }
6371            didSomething = true;
6372        }
6373
6374        if (packageName == null) {
6375            // Remove all sticky broadcasts from this user.
6376            mStickyBroadcasts.remove(userId);
6377        }
6378
6379        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6380        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6381                userId, providers)) {
6382            if (!doit) {
6383                return true;
6384            }
6385            didSomething = true;
6386        }
6387        for (i = providers.size() - 1; i >= 0; i--) {
6388            removeDyingProviderLocked(null, providers.get(i), true);
6389        }
6390
6391        // Remove transient permissions granted from/to this package/user
6392        removeUriPermissionsForPackageLocked(packageName, userId, false);
6393
6394        if (doit) {
6395            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6396                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6397                        packageName, null, userId, doit);
6398            }
6399        }
6400
6401        if (packageName == null || uninstalling) {
6402            // Remove pending intents.  For now we only do this when force
6403            // stopping users, because we have some problems when doing this
6404            // for packages -- app widgets are not currently cleaned up for
6405            // such packages, so they can be left with bad pending intents.
6406            if (mIntentSenderRecords.size() > 0) {
6407                Iterator<WeakReference<PendingIntentRecord>> it
6408                        = mIntentSenderRecords.values().iterator();
6409                while (it.hasNext()) {
6410                    WeakReference<PendingIntentRecord> wpir = it.next();
6411                    if (wpir == null) {
6412                        it.remove();
6413                        continue;
6414                    }
6415                    PendingIntentRecord pir = wpir.get();
6416                    if (pir == null) {
6417                        it.remove();
6418                        continue;
6419                    }
6420                    if (packageName == null) {
6421                        // Stopping user, remove all objects for the user.
6422                        if (pir.key.userId != userId) {
6423                            // Not the same user, skip it.
6424                            continue;
6425                        }
6426                    } else {
6427                        if (UserHandle.getAppId(pir.uid) != appId) {
6428                            // Different app id, skip it.
6429                            continue;
6430                        }
6431                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6432                            // Different user, skip it.
6433                            continue;
6434                        }
6435                        if (!pir.key.packageName.equals(packageName)) {
6436                            // Different package, skip it.
6437                            continue;
6438                        }
6439                    }
6440                    if (!doit) {
6441                        return true;
6442                    }
6443                    didSomething = true;
6444                    it.remove();
6445                    makeIntentSenderCanceledLocked(pir);
6446                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6447                        pir.key.activity.pendingResults.remove(pir.ref);
6448                    }
6449                }
6450            }
6451        }
6452
6453        if (doit) {
6454            if (purgeCache && packageName != null) {
6455                AttributeCache ac = AttributeCache.instance();
6456                if (ac != null) {
6457                    ac.removePackage(packageName);
6458                }
6459            }
6460            if (mBooted) {
6461                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6462                mStackSupervisor.scheduleIdleLocked();
6463            }
6464        }
6465
6466        return didSomething;
6467    }
6468
6469    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6470        return removeProcessNameLocked(name, uid, null);
6471    }
6472
6473    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6474            final ProcessRecord expecting) {
6475        ProcessRecord old = mProcessNames.get(name, uid);
6476        // Only actually remove when the currently recorded value matches the
6477        // record that we expected; if it doesn't match then we raced with a
6478        // newly created process and we don't want to destroy the new one.
6479        if ((expecting == null) || (old == expecting)) {
6480            mProcessNames.remove(name, uid);
6481        }
6482        if (old != null && old.uidRecord != null) {
6483            old.uidRecord.numProcs--;
6484            if (old.uidRecord.numProcs == 0) {
6485                // No more processes using this uid, tell clients it is gone.
6486                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6487                        "No more processes in " + old.uidRecord);
6488                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6489                mActiveUids.remove(uid);
6490                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6491            }
6492            old.uidRecord = null;
6493        }
6494        mIsolatedProcesses.remove(uid);
6495        return old;
6496    }
6497
6498    private final void addProcessNameLocked(ProcessRecord proc) {
6499        // We shouldn't already have a process under this name, but just in case we
6500        // need to clean up whatever may be there now.
6501        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6502        if (old == proc && proc.persistent) {
6503            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6504            Slog.w(TAG, "Re-adding persistent process " + proc);
6505        } else if (old != null) {
6506            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6507        }
6508        UidRecord uidRec = mActiveUids.get(proc.uid);
6509        if (uidRec == null) {
6510            uidRec = new UidRecord(proc.uid);
6511            // This is the first appearance of the uid, report it now!
6512            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6513                    "Creating new process uid: " + uidRec);
6514            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6515                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6516                uidRec.setWhitelist = uidRec.curWhitelist = true;
6517            }
6518            uidRec.updateHasInternetPermission();
6519            mActiveUids.put(proc.uid, uidRec);
6520            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6521            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6522        }
6523        proc.uidRecord = uidRec;
6524
6525        // Reset render thread tid if it was already set, so new process can set it again.
6526        proc.renderThreadTid = 0;
6527        uidRec.numProcs++;
6528        mProcessNames.put(proc.processName, proc.uid, proc);
6529        if (proc.isolated) {
6530            mIsolatedProcesses.put(proc.uid, proc);
6531        }
6532    }
6533
6534    boolean removeProcessLocked(ProcessRecord app,
6535            boolean callerWillRestart, boolean allowRestart, String reason) {
6536        final String name = app.processName;
6537        final int uid = app.uid;
6538        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6539            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6540
6541        ProcessRecord old = mProcessNames.get(name, uid);
6542        if (old != app) {
6543            // This process is no longer active, so nothing to do.
6544            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6545            return false;
6546        }
6547        removeProcessNameLocked(name, uid);
6548        if (mHeavyWeightProcess == app) {
6549            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6550                    mHeavyWeightProcess.userId, 0));
6551            mHeavyWeightProcess = null;
6552        }
6553        boolean needRestart = false;
6554        if (app.pid > 0 && app.pid != MY_PID) {
6555            int pid = app.pid;
6556            synchronized (mPidsSelfLocked) {
6557                mPidsSelfLocked.remove(pid);
6558                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6559            }
6560            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6561            if (app.isolated) {
6562                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6563                getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6564            }
6565            boolean willRestart = false;
6566            if (app.persistent && !app.isolated) {
6567                if (!callerWillRestart) {
6568                    willRestart = true;
6569                } else {
6570                    needRestart = true;
6571                }
6572            }
6573            app.kill(reason, true);
6574            handleAppDiedLocked(app, willRestart, allowRestart);
6575            if (willRestart) {
6576                removeLruProcessLocked(app);
6577                addAppLocked(app.info, null, false, null /* ABI override */);
6578            }
6579        } else {
6580            mRemovedProcesses.add(app);
6581        }
6582
6583        return needRestart;
6584    }
6585
6586    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6587        cleanupAppInLaunchingProvidersLocked(app, true);
6588        removeProcessLocked(app, false, true, "timeout publishing content providers");
6589    }
6590
6591    private final void processStartTimedOutLocked(ProcessRecord app) {
6592        final int pid = app.pid;
6593        boolean gone = false;
6594        synchronized (mPidsSelfLocked) {
6595            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6596            if (knownApp != null && knownApp.thread == null) {
6597                mPidsSelfLocked.remove(pid);
6598                gone = true;
6599            }
6600        }
6601
6602        if (gone) {
6603            Slog.w(TAG, "Process " + app + " failed to attach");
6604            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6605                    pid, app.uid, app.processName);
6606            removeProcessNameLocked(app.processName, app.uid);
6607            if (mHeavyWeightProcess == app) {
6608                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6609                        mHeavyWeightProcess.userId, 0));
6610                mHeavyWeightProcess = null;
6611            }
6612            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6613            if (app.isolated) {
6614                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6615            }
6616            // Take care of any launching providers waiting for this process.
6617            cleanupAppInLaunchingProvidersLocked(app, true);
6618            // Take care of any services that are waiting for the process.
6619            mServices.processStartTimedOutLocked(app);
6620            app.kill("start timeout", true);
6621            removeLruProcessLocked(app);
6622            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6623                Slog.w(TAG, "Unattached app died before backup, skipping");
6624                mHandler.post(new Runnable() {
6625                @Override
6626                    public void run(){
6627                        try {
6628                            IBackupManager bm = IBackupManager.Stub.asInterface(
6629                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6630                            bm.agentDisconnected(app.info.packageName);
6631                        } catch (RemoteException e) {
6632                            // Can't happen; the backup manager is local
6633                        }
6634                    }
6635                });
6636            }
6637            if (isPendingBroadcastProcessLocked(pid)) {
6638                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6639                skipPendingBroadcastLocked(pid);
6640            }
6641        } else {
6642            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6643        }
6644    }
6645
6646    private final boolean attachApplicationLocked(IApplicationThread thread,
6647            int pid) {
6648
6649        // Find the application record that is being attached...  either via
6650        // the pid if we are running in multiple processes, or just pull the
6651        // next app record if we are emulating process with anonymous threads.
6652        ProcessRecord app;
6653        long startTime = SystemClock.uptimeMillis();
6654        if (pid != MY_PID && pid >= 0) {
6655            synchronized (mPidsSelfLocked) {
6656                app = mPidsSelfLocked.get(pid);
6657            }
6658        } else {
6659            app = null;
6660        }
6661
6662        if (app == null) {
6663            Slog.w(TAG, "No pending application record for pid " + pid
6664                    + " (IApplicationThread " + thread + "); dropping process");
6665            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6666            if (pid > 0 && pid != MY_PID) {
6667                killProcessQuiet(pid);
6668                //TODO: killProcessGroup(app.info.uid, pid);
6669            } else {
6670                try {
6671                    thread.scheduleExit();
6672                } catch (Exception e) {
6673                    // Ignore exceptions.
6674                }
6675            }
6676            return false;
6677        }
6678
6679        // If this application record is still attached to a previous
6680        // process, clean it up now.
6681        if (app.thread != null) {
6682            handleAppDiedLocked(app, true, true);
6683        }
6684
6685        // Tell the process all about itself.
6686
6687        if (DEBUG_ALL) Slog.v(
6688                TAG, "Binding process pid " + pid + " to record " + app);
6689
6690        final String processName = app.processName;
6691        try {
6692            AppDeathRecipient adr = new AppDeathRecipient(
6693                    app, pid, thread);
6694            thread.asBinder().linkToDeath(adr, 0);
6695            app.deathRecipient = adr;
6696        } catch (RemoteException e) {
6697            app.resetPackageList(mProcessStats);
6698            startProcessLocked(app, "link fail", processName);
6699            return false;
6700        }
6701
6702        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6703
6704        app.makeActive(thread, mProcessStats);
6705        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6706        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6707        app.forcingToForeground = null;
6708        updateProcessForegroundLocked(app, false, false);
6709        app.hasShownUi = false;
6710        app.debugging = false;
6711        app.cached = false;
6712        app.killedByAm = false;
6713        app.killed = false;
6714
6715
6716        // We carefully use the same state that PackageManager uses for
6717        // filtering, since we use this flag to decide if we need to install
6718        // providers when user is unlocked later
6719        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6720
6721        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6722
6723        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6724        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6725
6726        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6727            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6728            msg.obj = app;
6729            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6730        }
6731
6732        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6733
6734        if (!normalMode) {
6735            Slog.i(TAG, "Launching preboot mode app: " + app);
6736        }
6737
6738        if (DEBUG_ALL) Slog.v(
6739            TAG, "New app record " + app
6740            + " thread=" + thread.asBinder() + " pid=" + pid);
6741        try {
6742            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6743            if (mDebugApp != null && mDebugApp.equals(processName)) {
6744                testMode = mWaitForDebugger
6745                    ? ApplicationThreadConstants.DEBUG_WAIT
6746                    : ApplicationThreadConstants.DEBUG_ON;
6747                app.debugging = true;
6748                if (mDebugTransient) {
6749                    mDebugApp = mOrigDebugApp;
6750                    mWaitForDebugger = mOrigWaitForDebugger;
6751                }
6752            }
6753            String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6754            ParcelFileDescriptor profileFd = null;
6755            int samplingInterval = 0;
6756            boolean profileAutoStop = false;
6757            boolean profileStreamingOutput = false;
6758            if (mProfileApp != null && mProfileApp.equals(processName)) {
6759                mProfileProc = app;
6760                profileFile = mProfileFile;
6761                profileFd = mProfileFd;
6762                samplingInterval = mSamplingInterval;
6763                profileAutoStop = mAutoStopProfiler;
6764                profileStreamingOutput = mStreamingOutput;
6765            }
6766            boolean enableTrackAllocation = false;
6767            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6768                enableTrackAllocation = true;
6769                mTrackAllocationApp = null;
6770            }
6771
6772            // If the app is being launched for restore or full backup, set it up specially
6773            boolean isRestrictedBackupMode = false;
6774            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6775                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6776                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6777                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6778                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6779            }
6780
6781            if (app.instr != null) {
6782                notifyPackageUse(app.instr.mClass.getPackageName(),
6783                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6784            }
6785            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6786                    + processName + " with config " + getGlobalConfiguration());
6787            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6788            app.compat = compatibilityInfoForPackageLocked(appInfo);
6789            if (profileFd != null) {
6790                profileFd = profileFd.dup();
6791            }
6792            ProfilerInfo profilerInfo = profileFile == null ? null
6793                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6794                                       profileStreamingOutput);
6795
6796            // We deprecated Build.SERIAL and it is not accessible to
6797            // apps that target the v2 security sandbox. Since access to
6798            // the serial is now behind a permission we push down the value.
6799            String buildSerial = Build.UNKNOWN;
6800            if (appInfo.targetSandboxVersion != 2) {
6801                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6802                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6803                        .getSerial();
6804            }
6805
6806            // Check if this is a secondary process that should be incorporated into some
6807            // currently active instrumentation.  (Note we do this AFTER all of the profiling
6808            // stuff above because profiling can currently happen only in the primary
6809            // instrumentation process.)
6810            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6811                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6812                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6813                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6814                        if (aInstr.mTargetProcesses.length == 0) {
6815                            // This is the wildcard mode, where every process brought up for
6816                            // the target instrumentation should be included.
6817                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6818                                app.instr = aInstr;
6819                                aInstr.mRunningProcesses.add(app);
6820                            }
6821                        } else {
6822                            for (String proc : aInstr.mTargetProcesses) {
6823                                if (proc.equals(app.processName)) {
6824                                    app.instr = aInstr;
6825                                    aInstr.mRunningProcesses.add(app);
6826                                    break;
6827                                }
6828                            }
6829                        }
6830                    }
6831                }
6832            }
6833
6834            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6835            if (app.instr != null) {
6836                thread.bindApplication(processName, appInfo, providers,
6837                        app.instr.mClass,
6838                        profilerInfo, app.instr.mArguments,
6839                        app.instr.mWatcher,
6840                        app.instr.mUiAutomationConnection, testMode,
6841                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6842                        isRestrictedBackupMode || !normalMode, app.persistent,
6843                        new Configuration(getGlobalConfiguration()), app.compat,
6844                        getCommonServicesLocked(app.isolated),
6845                        mCoreSettingsObserver.getCoreSettingsLocked(),
6846                        buildSerial);
6847            } else {
6848                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6849                        null, null, null, testMode,
6850                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6851                        isRestrictedBackupMode || !normalMode, app.persistent,
6852                        new Configuration(getGlobalConfiguration()), app.compat,
6853                        getCommonServicesLocked(app.isolated),
6854                        mCoreSettingsObserver.getCoreSettingsLocked(),
6855                        buildSerial);
6856            }
6857
6858            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6859            updateLruProcessLocked(app, false, null);
6860            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6861            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6862        } catch (Exception e) {
6863            // todo: Yikes!  What should we do?  For now we will try to
6864            // start another process, but that could easily get us in
6865            // an infinite loop of restarting processes...
6866            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6867
6868            app.resetPackageList(mProcessStats);
6869            app.unlinkDeathRecipient();
6870            startProcessLocked(app, "bind fail", processName);
6871            return false;
6872        }
6873
6874        // Remove this record from the list of starting applications.
6875        mPersistentStartingProcesses.remove(app);
6876        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6877                "Attach application locked removing on hold: " + app);
6878        mProcessesOnHold.remove(app);
6879
6880        boolean badApp = false;
6881        boolean didSomething = false;
6882
6883        // See if the top visible activity is waiting to run in this process...
6884        if (normalMode) {
6885            try {
6886                if (mStackSupervisor.attachApplicationLocked(app)) {
6887                    didSomething = true;
6888                }
6889            } catch (Exception e) {
6890                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6891                badApp = true;
6892            }
6893        }
6894
6895        // Find any services that should be running in this process...
6896        if (!badApp) {
6897            try {
6898                didSomething |= mServices.attachApplicationLocked(app, processName);
6899                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6900            } catch (Exception e) {
6901                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6902                badApp = true;
6903            }
6904        }
6905
6906        // Check if a next-broadcast receiver is in this process...
6907        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6908            try {
6909                didSomething |= sendPendingBroadcastsLocked(app);
6910                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6911            } catch (Exception e) {
6912                // If the app died trying to launch the receiver we declare it 'bad'
6913                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6914                badApp = true;
6915            }
6916        }
6917
6918        // Check whether the next backup agent is in this process...
6919        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6920            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6921                    "New app is backup target, launching agent for " + app);
6922            notifyPackageUse(mBackupTarget.appInfo.packageName,
6923                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6924            try {
6925                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6926                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6927                        mBackupTarget.backupMode);
6928            } catch (Exception e) {
6929                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6930                badApp = true;
6931            }
6932        }
6933
6934        if (badApp) {
6935            app.kill("error during init", true);
6936            handleAppDiedLocked(app, false, true);
6937            return false;
6938        }
6939
6940        if (!didSomething) {
6941            updateOomAdjLocked();
6942            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6943        }
6944
6945        return true;
6946    }
6947
6948    @Override
6949    public final void attachApplication(IApplicationThread thread) {
6950        synchronized (this) {
6951            int callingPid = Binder.getCallingPid();
6952            final long origId = Binder.clearCallingIdentity();
6953            attachApplicationLocked(thread, callingPid);
6954            Binder.restoreCallingIdentity(origId);
6955        }
6956    }
6957
6958    @Override
6959    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6960        final long origId = Binder.clearCallingIdentity();
6961        synchronized (this) {
6962            ActivityStack stack = ActivityRecord.getStackLocked(token);
6963            if (stack != null) {
6964                ActivityRecord r =
6965                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
6966                                false /* processPausingActivities */, config);
6967                if (stopProfiling) {
6968                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6969                        try {
6970                            mProfileFd.close();
6971                        } catch (IOException e) {
6972                        }
6973                        clearProfilerLocked();
6974                    }
6975                }
6976            }
6977        }
6978        Binder.restoreCallingIdentity(origId);
6979    }
6980
6981    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6982        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6983                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6984    }
6985
6986    void enableScreenAfterBoot() {
6987        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6988                SystemClock.uptimeMillis());
6989        mWindowManager.enableScreenAfterBoot();
6990
6991        synchronized (this) {
6992            updateEventDispatchingLocked();
6993        }
6994    }
6995
6996    @Override
6997    public void showBootMessage(final CharSequence msg, final boolean always) {
6998        if (Binder.getCallingUid() != myUid()) {
6999            throw new SecurityException();
7000        }
7001        mWindowManager.showBootMessage(msg, always);
7002    }
7003
7004    @Override
7005    public void keyguardGoingAway(int flags) {
7006        enforceNotIsolatedCaller("keyguardGoingAway");
7007        final long token = Binder.clearCallingIdentity();
7008        try {
7009            synchronized (this) {
7010                mKeyguardController.keyguardGoingAway(flags);
7011            }
7012        } finally {
7013            Binder.restoreCallingIdentity(token);
7014        }
7015    }
7016
7017    /**
7018     * @return whther the keyguard is currently locked.
7019     */
7020    boolean isKeyguardLocked() {
7021        return mKeyguardController.isKeyguardLocked();
7022    }
7023
7024    final void finishBooting() {
7025        synchronized (this) {
7026            if (!mBootAnimationComplete) {
7027                mCallFinishBooting = true;
7028                return;
7029            }
7030            mCallFinishBooting = false;
7031        }
7032
7033        ArraySet<String> completedIsas = new ArraySet<String>();
7034        for (String abi : Build.SUPPORTED_ABIS) {
7035            zygoteProcess.establishZygoteConnectionForAbi(abi);
7036            final String instructionSet = VMRuntime.getInstructionSet(abi);
7037            if (!completedIsas.contains(instructionSet)) {
7038                try {
7039                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7040                } catch (InstallerException e) {
7041                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7042                            e.getMessage() +")");
7043                }
7044                completedIsas.add(instructionSet);
7045            }
7046        }
7047
7048        IntentFilter pkgFilter = new IntentFilter();
7049        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7050        pkgFilter.addDataScheme("package");
7051        mContext.registerReceiver(new BroadcastReceiver() {
7052            @Override
7053            public void onReceive(Context context, Intent intent) {
7054                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7055                if (pkgs != null) {
7056                    for (String pkg : pkgs) {
7057                        synchronized (ActivityManagerService.this) {
7058                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7059                                    0, "query restart")) {
7060                                setResultCode(Activity.RESULT_OK);
7061                                return;
7062                            }
7063                        }
7064                    }
7065                }
7066            }
7067        }, pkgFilter);
7068
7069        IntentFilter dumpheapFilter = new IntentFilter();
7070        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7071        mContext.registerReceiver(new BroadcastReceiver() {
7072            @Override
7073            public void onReceive(Context context, Intent intent) {
7074                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7075                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7076                } else {
7077                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7078                }
7079            }
7080        }, dumpheapFilter);
7081
7082        // Let system services know.
7083        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7084
7085        synchronized (this) {
7086            // Ensure that any processes we had put on hold are now started
7087            // up.
7088            final int NP = mProcessesOnHold.size();
7089            if (NP > 0) {
7090                ArrayList<ProcessRecord> procs =
7091                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7092                for (int ip=0; ip<NP; ip++) {
7093                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7094                            + procs.get(ip));
7095                    startProcessLocked(procs.get(ip), "on-hold", null);
7096                }
7097            }
7098
7099            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7100                // Start looking for apps that are abusing wake locks.
7101                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7102                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7103                // Tell anyone interested that we are done booting!
7104                SystemProperties.set("sys.boot_completed", "1");
7105
7106                // And trigger dev.bootcomplete if we are not showing encryption progress
7107                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7108                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7109                    SystemProperties.set("dev.bootcomplete", "1");
7110                }
7111                mUserController.sendBootCompletedLocked(
7112                        new IIntentReceiver.Stub() {
7113                            @Override
7114                            public void performReceive(Intent intent, int resultCode,
7115                                    String data, Bundle extras, boolean ordered,
7116                                    boolean sticky, int sendingUser) {
7117                                synchronized (ActivityManagerService.this) {
7118                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7119                                            true, false);
7120                                }
7121                            }
7122                        });
7123                scheduleStartProfilesLocked();
7124            }
7125        }
7126    }
7127
7128    @Override
7129    public void bootAnimationComplete() {
7130        final boolean callFinishBooting;
7131        synchronized (this) {
7132            callFinishBooting = mCallFinishBooting;
7133            mBootAnimationComplete = true;
7134        }
7135        if (callFinishBooting) {
7136            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7137            finishBooting();
7138            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7139        }
7140    }
7141
7142    final void ensureBootCompleted() {
7143        boolean booting;
7144        boolean enableScreen;
7145        synchronized (this) {
7146            booting = mBooting;
7147            mBooting = false;
7148            enableScreen = !mBooted;
7149            mBooted = true;
7150        }
7151
7152        if (booting) {
7153            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7154            finishBooting();
7155            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7156        }
7157
7158        if (enableScreen) {
7159            enableScreenAfterBoot();
7160        }
7161    }
7162
7163    @Override
7164    public final void activityResumed(IBinder token) {
7165        final long origId = Binder.clearCallingIdentity();
7166        synchronized(this) {
7167            ActivityRecord.activityResumedLocked(token);
7168            mWindowManager.notifyAppResumedFinished(token);
7169        }
7170        Binder.restoreCallingIdentity(origId);
7171    }
7172
7173    @Override
7174    public final void activityPaused(IBinder token) {
7175        final long origId = Binder.clearCallingIdentity();
7176        synchronized(this) {
7177            ActivityStack stack = ActivityRecord.getStackLocked(token);
7178            if (stack != null) {
7179                stack.activityPausedLocked(token, false);
7180            }
7181        }
7182        Binder.restoreCallingIdentity(origId);
7183    }
7184
7185    @Override
7186    public final void activityStopped(IBinder token, Bundle icicle,
7187            PersistableBundle persistentState, CharSequence description) {
7188        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7189
7190        // Refuse possible leaked file descriptors
7191        if (icicle != null && icicle.hasFileDescriptors()) {
7192            throw new IllegalArgumentException("File descriptors passed in Bundle");
7193        }
7194
7195        final long origId = Binder.clearCallingIdentity();
7196
7197        synchronized (this) {
7198            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7199            if (r != null) {
7200                r.activityStoppedLocked(icicle, persistentState, description);
7201            }
7202        }
7203
7204        trimApplications();
7205
7206        Binder.restoreCallingIdentity(origId);
7207    }
7208
7209    @Override
7210    public final void activityDestroyed(IBinder token) {
7211        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7212        synchronized (this) {
7213            ActivityStack stack = ActivityRecord.getStackLocked(token);
7214            if (stack != null) {
7215                stack.activityDestroyedLocked(token, "activityDestroyed");
7216            }
7217        }
7218    }
7219
7220    @Override
7221    public final void activityRelaunched(IBinder token) {
7222        final long origId = Binder.clearCallingIdentity();
7223        synchronized (this) {
7224            mStackSupervisor.activityRelaunchedLocked(token);
7225        }
7226        Binder.restoreCallingIdentity(origId);
7227    }
7228
7229    @Override
7230    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7231            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7232        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7233                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7234        synchronized (this) {
7235            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7236            if (record == null) {
7237                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7238                        + "found for: " + token);
7239            }
7240            record.setSizeConfigurations(horizontalSizeConfiguration,
7241                    verticalSizeConfigurations, smallestSizeConfigurations);
7242        }
7243    }
7244
7245    @Override
7246    public final void backgroundResourcesReleased(IBinder token) {
7247        final long origId = Binder.clearCallingIdentity();
7248        try {
7249            synchronized (this) {
7250                ActivityStack stack = ActivityRecord.getStackLocked(token);
7251                if (stack != null) {
7252                    stack.backgroundResourcesReleased();
7253                }
7254            }
7255        } finally {
7256            Binder.restoreCallingIdentity(origId);
7257        }
7258    }
7259
7260    @Override
7261    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7262        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7263    }
7264
7265    @Override
7266    public final void notifyEnterAnimationComplete(IBinder token) {
7267        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7268    }
7269
7270    @Override
7271    public String getCallingPackage(IBinder token) {
7272        synchronized (this) {
7273            ActivityRecord r = getCallingRecordLocked(token);
7274            return r != null ? r.info.packageName : null;
7275        }
7276    }
7277
7278    @Override
7279    public ComponentName getCallingActivity(IBinder token) {
7280        synchronized (this) {
7281            ActivityRecord r = getCallingRecordLocked(token);
7282            return r != null ? r.intent.getComponent() : null;
7283        }
7284    }
7285
7286    private ActivityRecord getCallingRecordLocked(IBinder token) {
7287        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7288        if (r == null) {
7289            return null;
7290        }
7291        return r.resultTo;
7292    }
7293
7294    @Override
7295    public ComponentName getActivityClassForToken(IBinder token) {
7296        synchronized(this) {
7297            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7298            if (r == null) {
7299                return null;
7300            }
7301            return r.intent.getComponent();
7302        }
7303    }
7304
7305    @Override
7306    public String getPackageForToken(IBinder token) {
7307        synchronized(this) {
7308            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7309            if (r == null) {
7310                return null;
7311            }
7312            return r.packageName;
7313        }
7314    }
7315
7316    @Override
7317    public boolean isRootVoiceInteraction(IBinder token) {
7318        synchronized(this) {
7319            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7320            if (r == null) {
7321                return false;
7322            }
7323            return r.rootVoiceInteraction;
7324        }
7325    }
7326
7327    @Override
7328    public IIntentSender getIntentSender(int type,
7329            String packageName, IBinder token, String resultWho,
7330            int requestCode, Intent[] intents, String[] resolvedTypes,
7331            int flags, Bundle bOptions, int userId) {
7332        enforceNotIsolatedCaller("getIntentSender");
7333        // Refuse possible leaked file descriptors
7334        if (intents != null) {
7335            if (intents.length < 1) {
7336                throw new IllegalArgumentException("Intents array length must be >= 1");
7337            }
7338            for (int i=0; i<intents.length; i++) {
7339                Intent intent = intents[i];
7340                if (intent != null) {
7341                    if (intent.hasFileDescriptors()) {
7342                        throw new IllegalArgumentException("File descriptors passed in Intent");
7343                    }
7344                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7345                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7346                        throw new IllegalArgumentException(
7347                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7348                    }
7349                    intents[i] = new Intent(intent);
7350                }
7351            }
7352            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7353                throw new IllegalArgumentException(
7354                        "Intent array length does not match resolvedTypes length");
7355            }
7356        }
7357        if (bOptions != null) {
7358            if (bOptions.hasFileDescriptors()) {
7359                throw new IllegalArgumentException("File descriptors passed in options");
7360            }
7361        }
7362
7363        synchronized(this) {
7364            int callingUid = Binder.getCallingUid();
7365            int origUserId = userId;
7366            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7367                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7368                    ALLOW_NON_FULL, "getIntentSender", null);
7369            if (origUserId == UserHandle.USER_CURRENT) {
7370                // We don't want to evaluate this until the pending intent is
7371                // actually executed.  However, we do want to always do the
7372                // security checking for it above.
7373                userId = UserHandle.USER_CURRENT;
7374            }
7375            try {
7376                if (callingUid != 0 && callingUid != SYSTEM_UID) {
7377                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7378                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7379                    if (!UserHandle.isSameApp(callingUid, uid)) {
7380                        String msg = "Permission Denial: getIntentSender() from pid="
7381                            + Binder.getCallingPid()
7382                            + ", uid=" + Binder.getCallingUid()
7383                            + ", (need uid=" + uid + ")"
7384                            + " is not allowed to send as package " + packageName;
7385                        Slog.w(TAG, msg);
7386                        throw new SecurityException(msg);
7387                    }
7388                }
7389
7390                return getIntentSenderLocked(type, packageName, callingUid, userId,
7391                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7392
7393            } catch (RemoteException e) {
7394                throw new SecurityException(e);
7395            }
7396        }
7397    }
7398
7399    IIntentSender getIntentSenderLocked(int type, String packageName,
7400            int callingUid, int userId, IBinder token, String resultWho,
7401            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7402            Bundle bOptions) {
7403        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7404        ActivityRecord activity = null;
7405        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7406            activity = ActivityRecord.isInStackLocked(token);
7407            if (activity == null) {
7408                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7409                return null;
7410            }
7411            if (activity.finishing) {
7412                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7413                return null;
7414            }
7415        }
7416
7417        // We're going to be splicing together extras before sending, so we're
7418        // okay poking into any contained extras.
7419        if (intents != null) {
7420            for (int i = 0; i < intents.length; i++) {
7421                intents[i].setDefusable(true);
7422            }
7423        }
7424        Bundle.setDefusable(bOptions, true);
7425
7426        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7427        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7428        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7429        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7430                |PendingIntent.FLAG_UPDATE_CURRENT);
7431
7432        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7433                type, packageName, activity, resultWho,
7434                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7435        WeakReference<PendingIntentRecord> ref;
7436        ref = mIntentSenderRecords.get(key);
7437        PendingIntentRecord rec = ref != null ? ref.get() : null;
7438        if (rec != null) {
7439            if (!cancelCurrent) {
7440                if (updateCurrent) {
7441                    if (rec.key.requestIntent != null) {
7442                        rec.key.requestIntent.replaceExtras(intents != null ?
7443                                intents[intents.length - 1] : null);
7444                    }
7445                    if (intents != null) {
7446                        intents[intents.length-1] = rec.key.requestIntent;
7447                        rec.key.allIntents = intents;
7448                        rec.key.allResolvedTypes = resolvedTypes;
7449                    } else {
7450                        rec.key.allIntents = null;
7451                        rec.key.allResolvedTypes = null;
7452                    }
7453                }
7454                return rec;
7455            }
7456            makeIntentSenderCanceledLocked(rec);
7457            mIntentSenderRecords.remove(key);
7458        }
7459        if (noCreate) {
7460            return rec;
7461        }
7462        rec = new PendingIntentRecord(this, key, callingUid);
7463        mIntentSenderRecords.put(key, rec.ref);
7464        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7465            if (activity.pendingResults == null) {
7466                activity.pendingResults
7467                        = new HashSet<WeakReference<PendingIntentRecord>>();
7468            }
7469            activity.pendingResults.add(rec.ref);
7470        }
7471        return rec;
7472    }
7473
7474    @Override
7475    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7476            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7477        if (target instanceof PendingIntentRecord) {
7478            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7479                    finishedReceiver, requiredPermission, options);
7480        } else {
7481            if (intent == null) {
7482                // Weird case: someone has given us their own custom IIntentSender, and now
7483                // they have someone else trying to send to it but of course this isn't
7484                // really a PendingIntent, so there is no base Intent, and the caller isn't
7485                // supplying an Intent... but we never want to dispatch a null Intent to
7486                // a receiver, so um...  let's make something up.
7487                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7488                intent = new Intent(Intent.ACTION_MAIN);
7489            }
7490            try {
7491                target.send(code, intent, resolvedType, null, requiredPermission, options);
7492            } catch (RemoteException e) {
7493            }
7494            // Platform code can rely on getting a result back when the send is done, but if
7495            // this intent sender is from outside of the system we can't rely on it doing that.
7496            // So instead we don't give it the result receiver, and instead just directly
7497            // report the finish immediately.
7498            if (finishedReceiver != null) {
7499                try {
7500                    finishedReceiver.performReceive(intent, 0,
7501                            null, null, false, false, UserHandle.getCallingUserId());
7502                } catch (RemoteException e) {
7503                }
7504            }
7505            return 0;
7506        }
7507    }
7508
7509    @Override
7510    public void cancelIntentSender(IIntentSender sender) {
7511        if (!(sender instanceof PendingIntentRecord)) {
7512            return;
7513        }
7514        synchronized(this) {
7515            PendingIntentRecord rec = (PendingIntentRecord)sender;
7516            try {
7517                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7518                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7519                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7520                    String msg = "Permission Denial: cancelIntentSender() from pid="
7521                        + Binder.getCallingPid()
7522                        + ", uid=" + Binder.getCallingUid()
7523                        + " is not allowed to cancel package "
7524                        + rec.key.packageName;
7525                    Slog.w(TAG, msg);
7526                    throw new SecurityException(msg);
7527                }
7528            } catch (RemoteException e) {
7529                throw new SecurityException(e);
7530            }
7531            cancelIntentSenderLocked(rec, true);
7532        }
7533    }
7534
7535    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7536        makeIntentSenderCanceledLocked(rec);
7537        mIntentSenderRecords.remove(rec.key);
7538        if (cleanActivity && rec.key.activity != null) {
7539            rec.key.activity.pendingResults.remove(rec.ref);
7540        }
7541    }
7542
7543    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7544        rec.canceled = true;
7545        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7546        if (callbacks != null) {
7547            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7548        }
7549    }
7550
7551    @Override
7552    public String getPackageForIntentSender(IIntentSender pendingResult) {
7553        if (!(pendingResult instanceof PendingIntentRecord)) {
7554            return null;
7555        }
7556        try {
7557            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7558            return res.key.packageName;
7559        } catch (ClassCastException e) {
7560        }
7561        return null;
7562    }
7563
7564    @Override
7565    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7566        if (!(sender instanceof PendingIntentRecord)) {
7567            return;
7568        }
7569        synchronized(this) {
7570            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7571        }
7572    }
7573
7574    @Override
7575    public void unregisterIntentSenderCancelListener(IIntentSender sender,
7576            IResultReceiver receiver) {
7577        if (!(sender instanceof PendingIntentRecord)) {
7578            return;
7579        }
7580        synchronized(this) {
7581            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7582        }
7583    }
7584
7585    @Override
7586    public int getUidForIntentSender(IIntentSender sender) {
7587        if (sender instanceof PendingIntentRecord) {
7588            try {
7589                PendingIntentRecord res = (PendingIntentRecord)sender;
7590                return res.uid;
7591            } catch (ClassCastException e) {
7592            }
7593        }
7594        return -1;
7595    }
7596
7597    @Override
7598    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7599        if (!(pendingResult instanceof PendingIntentRecord)) {
7600            return false;
7601        }
7602        try {
7603            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7604            if (res.key.allIntents == null) {
7605                return false;
7606            }
7607            for (int i=0; i<res.key.allIntents.length; i++) {
7608                Intent intent = res.key.allIntents[i];
7609                if (intent.getPackage() != null && intent.getComponent() != null) {
7610                    return false;
7611                }
7612            }
7613            return true;
7614        } catch (ClassCastException e) {
7615        }
7616        return false;
7617    }
7618
7619    @Override
7620    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7621        if (!(pendingResult instanceof PendingIntentRecord)) {
7622            return false;
7623        }
7624        try {
7625            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7626            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7627                return true;
7628            }
7629            return false;
7630        } catch (ClassCastException e) {
7631        }
7632        return false;
7633    }
7634
7635    @Override
7636    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7637        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7638                "getIntentForIntentSender()");
7639        if (!(pendingResult instanceof PendingIntentRecord)) {
7640            return null;
7641        }
7642        try {
7643            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7644            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7645        } catch (ClassCastException e) {
7646        }
7647        return null;
7648    }
7649
7650    @Override
7651    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7652        if (!(pendingResult instanceof PendingIntentRecord)) {
7653            return null;
7654        }
7655        try {
7656            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7657            synchronized (this) {
7658                return getTagForIntentSenderLocked(res, prefix);
7659            }
7660        } catch (ClassCastException e) {
7661        }
7662        return null;
7663    }
7664
7665    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7666        final Intent intent = res.key.requestIntent;
7667        if (intent != null) {
7668            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7669                    || res.lastTagPrefix.equals(prefix))) {
7670                return res.lastTag;
7671            }
7672            res.lastTagPrefix = prefix;
7673            final StringBuilder sb = new StringBuilder(128);
7674            if (prefix != null) {
7675                sb.append(prefix);
7676            }
7677            if (intent.getAction() != null) {
7678                sb.append(intent.getAction());
7679            } else if (intent.getComponent() != null) {
7680                intent.getComponent().appendShortString(sb);
7681            } else {
7682                sb.append("?");
7683            }
7684            return res.lastTag = sb.toString();
7685        }
7686        return null;
7687    }
7688
7689    @Override
7690    public void setProcessLimit(int max) {
7691        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7692                "setProcessLimit()");
7693        synchronized (this) {
7694            mConstants.setOverrideMaxCachedProcesses(max);
7695        }
7696        trimApplications();
7697    }
7698
7699    @Override
7700    public int getProcessLimit() {
7701        synchronized (this) {
7702            return mConstants.getOverrideMaxCachedProcesses();
7703        }
7704    }
7705
7706    void foregroundTokenDied(ForegroundToken token) {
7707        synchronized (ActivityManagerService.this) {
7708            synchronized (mPidsSelfLocked) {
7709                ForegroundToken cur
7710                    = mForegroundProcesses.get(token.pid);
7711                if (cur != token) {
7712                    return;
7713                }
7714                mForegroundProcesses.remove(token.pid);
7715                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7716                if (pr == null) {
7717                    return;
7718                }
7719                pr.forcingToForeground = null;
7720                updateProcessForegroundLocked(pr, false, false);
7721            }
7722            updateOomAdjLocked();
7723        }
7724    }
7725
7726    @Override
7727    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7728        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7729                "setProcessForeground()");
7730        synchronized(this) {
7731            boolean changed = false;
7732
7733            synchronized (mPidsSelfLocked) {
7734                ProcessRecord pr = mPidsSelfLocked.get(pid);
7735                if (pr == null && isForeground) {
7736                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7737                    return;
7738                }
7739                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7740                if (oldToken != null) {
7741                    oldToken.token.unlinkToDeath(oldToken, 0);
7742                    mForegroundProcesses.remove(pid);
7743                    if (pr != null) {
7744                        pr.forcingToForeground = null;
7745                    }
7746                    changed = true;
7747                }
7748                if (isForeground && token != null) {
7749                    ForegroundToken newToken = new ForegroundToken() {
7750                        @Override
7751                        public void binderDied() {
7752                            foregroundTokenDied(this);
7753                        }
7754                    };
7755                    newToken.pid = pid;
7756                    newToken.token = token;
7757                    try {
7758                        token.linkToDeath(newToken, 0);
7759                        mForegroundProcesses.put(pid, newToken);
7760                        pr.forcingToForeground = token;
7761                        changed = true;
7762                    } catch (RemoteException e) {
7763                        // If the process died while doing this, we will later
7764                        // do the cleanup with the process death link.
7765                    }
7766                }
7767            }
7768
7769            if (changed) {
7770                updateOomAdjLocked();
7771            }
7772        }
7773    }
7774
7775    @Override
7776    public boolean isAppForeground(int uid) throws RemoteException {
7777        synchronized (this) {
7778            UidRecord uidRec = mActiveUids.get(uid);
7779            if (uidRec == null || uidRec.idle) {
7780                return false;
7781            }
7782            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7783        }
7784    }
7785
7786    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7787    // be guarded by permission checking.
7788    int getUidState(int uid) {
7789        synchronized (this) {
7790            UidRecord uidRec = mActiveUids.get(uid);
7791            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7792        }
7793    }
7794
7795    @Override
7796    public boolean isInMultiWindowMode(IBinder token) {
7797        final long origId = Binder.clearCallingIdentity();
7798        try {
7799            synchronized(this) {
7800                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7801                if (r == null) {
7802                    return false;
7803                }
7804                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7805                return !r.getTask().mFullscreen;
7806            }
7807        } finally {
7808            Binder.restoreCallingIdentity(origId);
7809        }
7810    }
7811
7812    @Override
7813    public boolean isInPictureInPictureMode(IBinder token) {
7814        final long origId = Binder.clearCallingIdentity();
7815        try {
7816            synchronized(this) {
7817                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7818                if (stack == null) {
7819                    return false;
7820                }
7821                return stack.mStackId == PINNED_STACK_ID;
7822            }
7823        } finally {
7824            Binder.restoreCallingIdentity(origId);
7825        }
7826    }
7827
7828    @Override
7829    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureArgs args) {
7830        final long origId = Binder.clearCallingIdentity();
7831        try {
7832            synchronized(this) {
7833                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7834                        "enterPictureInPictureMode", token, args);
7835
7836                // Activity supports picture-in-picture, now check that we can enter PiP at this
7837                // point, if it is
7838                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7839                        false /* noThrow */, false /* beforeStopping */)) {
7840                    return false;
7841                }
7842
7843                final Runnable enterPipRunnable = () -> {
7844                    // Only update the saved args from the args that are set
7845                    r.pictureInPictureArgs.copyOnlySet(args);
7846                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
7847                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
7848                    // Adjust the source bounds by the insets for the transition down
7849                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
7850                    final Rect insets = r.pictureInPictureArgs.getSourceRectHintInsets();
7851                    if (insets != null) {
7852                        sourceBounds.offsetTo(Math.max(0, sourceBounds.left - insets.left),
7853                                Math.max(0, sourceBounds.top - insets.top));
7854                    }
7855
7856                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
7857                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
7858                    final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
7859                    stack.setPictureInPictureAspectRatio(aspectRatio);
7860                    stack.setPictureInPictureActions(actions);
7861
7862                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
7863                            r.supportsPictureInPictureWhilePausing);
7864                    logPictureInPictureArgs(args);
7865                };
7866
7867                if (isKeyguardLocked()) {
7868                    // If the keyguard is showing or occluded, then try and dismiss it before
7869                    // entering picture-in-picture (this will prompt the user to authenticate if the
7870                    // device is currently locked).
7871                    try {
7872                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7873                            @Override
7874                            public void onDismissError() throws RemoteException {
7875                                // Do nothing
7876                            }
7877
7878                            @Override
7879                            public void onDismissSucceeded() throws RemoteException {
7880                                mHandler.post(enterPipRunnable);
7881                            }
7882
7883                            @Override
7884                            public void onDismissCancelled() throws RemoteException {
7885                                // Do nothing
7886                            }
7887                        });
7888                    } catch (RemoteException e) {
7889                        // Local call
7890                    }
7891                } else {
7892                    // Enter picture in picture immediately otherwise
7893                    enterPipRunnable.run();
7894                }
7895                return true;
7896            }
7897        } finally {
7898            Binder.restoreCallingIdentity(origId);
7899        }
7900    }
7901
7902    @Override
7903    public void setPictureInPictureArgs(IBinder token, final PictureInPictureArgs args) {
7904        final long origId = Binder.clearCallingIdentity();
7905        try {
7906            synchronized(this) {
7907                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7908                        "setPictureInPictureArgs", token, args);
7909
7910                // Only update the saved args from the args that are set
7911                r.pictureInPictureArgs.copyOnlySet(args);
7912                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7913                    // If the activity is already in picture-in-picture, update the pinned stack now
7914                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
7915                    // be used the next time the activity enters PiP
7916                    final PinnedActivityStack stack = r.getStack();
7917                    if (!stack.isAnimatingBoundsToFullscreen()) {
7918                        stack.setPictureInPictureAspectRatio(
7919                                r.pictureInPictureArgs.getAspectRatio());
7920                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
7921                    }
7922                }
7923                logPictureInPictureArgs(args);
7924            }
7925        } finally {
7926            Binder.restoreCallingIdentity(origId);
7927        }
7928    }
7929
7930    private void logPictureInPictureArgs(PictureInPictureArgs args) {
7931        if (args.hasSetActions()) {
7932            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
7933                    args.getActions().size());
7934        }
7935        if (args.hasSetAspectRatio()) {
7936            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
7937            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, args.getAspectRatio());
7938            MetricsLogger.action(lm);
7939        }
7940    }
7941
7942    /**
7943     * Checks the state of the system and the activity associated with the given {@param token} to
7944     * verify that picture-in-picture is supported for that activity.
7945     *
7946     * @return the activity record for the given {@param token} if all the checks pass.
7947     */
7948    private ActivityRecord ensureValidPictureInPictureActivityArgsLocked(String caller,
7949            IBinder token, PictureInPictureArgs args) {
7950        if (!mSupportsPictureInPicture) {
7951            throw new IllegalStateException(caller
7952                    + ": Device doesn't support picture-in-picture mode.");
7953        }
7954
7955        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7956        if (r == null) {
7957            throw new IllegalStateException(caller
7958                    + ": Can't find activity for token=" + token);
7959        }
7960
7961        if (!r.supportsPictureInPicture()) {
7962            throw new IllegalStateException(caller
7963                    + ": Current activity does not support picture-in-picture.");
7964        }
7965
7966        if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
7967            throw new IllegalStateException(caller
7968                    + ": Activities on the home, assistant, or recents stack not supported");
7969        }
7970
7971        if (args.hasSetAspectRatio()
7972                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
7973                        args.getAspectRatio())) {
7974            final float minAspectRatio = mContext.getResources().getFloat(
7975                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
7976            final float maxAspectRatio = mContext.getResources().getFloat(
7977                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
7978            throw new IllegalArgumentException(String.format(caller
7979                    + ": Aspect ratio is too extreme (must be between %f and %f).",
7980                            minAspectRatio, maxAspectRatio));
7981        }
7982
7983        if (args.hasSetActions()
7984                && args.getActions().size() > ActivityManager.getMaxNumPictureInPictureActions()) {
7985            throw new IllegalArgumentException(String.format(caller + ": Invalid number of"
7986                    + "picture-in-picture actions.  Only a maximum of %d actions allowed",
7987                            ActivityManager.getMaxNumPictureInPictureActions()));
7988        }
7989
7990        return r;
7991    }
7992
7993    // =========================================================
7994    // PROCESS INFO
7995    // =========================================================
7996
7997    static class ProcessInfoService extends IProcessInfoService.Stub {
7998        final ActivityManagerService mActivityManagerService;
7999        ProcessInfoService(ActivityManagerService activityManagerService) {
8000            mActivityManagerService = activityManagerService;
8001        }
8002
8003        @Override
8004        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8005            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8006                    /*in*/ pids, /*out*/ states, null);
8007        }
8008
8009        @Override
8010        public void getProcessStatesAndOomScoresFromPids(
8011                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8012            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8013                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8014        }
8015    }
8016
8017    /**
8018     * For each PID in the given input array, write the current process state
8019     * for that process into the states array, or -1 to indicate that no
8020     * process with the given PID exists. If scores array is provided, write
8021     * the oom score for the process into the scores array, with INVALID_ADJ
8022     * indicating the PID doesn't exist.
8023     */
8024    public void getProcessStatesAndOomScoresForPIDs(
8025            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8026        if (scores != null) {
8027            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8028                    "getProcessStatesAndOomScoresForPIDs()");
8029        }
8030
8031        if (pids == null) {
8032            throw new NullPointerException("pids");
8033        } else if (states == null) {
8034            throw new NullPointerException("states");
8035        } else if (pids.length != states.length) {
8036            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8037        } else if (scores != null && pids.length != scores.length) {
8038            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8039        }
8040
8041        synchronized (mPidsSelfLocked) {
8042            for (int i = 0; i < pids.length; i++) {
8043                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8044                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8045                        pr.curProcState;
8046                if (scores != null) {
8047                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8048                }
8049            }
8050        }
8051    }
8052
8053    // =========================================================
8054    // PERMISSIONS
8055    // =========================================================
8056
8057    static class PermissionController extends IPermissionController.Stub {
8058        ActivityManagerService mActivityManagerService;
8059        PermissionController(ActivityManagerService activityManagerService) {
8060            mActivityManagerService = activityManagerService;
8061        }
8062
8063        @Override
8064        public boolean checkPermission(String permission, int pid, int uid) {
8065            return mActivityManagerService.checkPermission(permission, pid,
8066                    uid) == PackageManager.PERMISSION_GRANTED;
8067        }
8068
8069        @Override
8070        public String[] getPackagesForUid(int uid) {
8071            return mActivityManagerService.mContext.getPackageManager()
8072                    .getPackagesForUid(uid);
8073        }
8074
8075        @Override
8076        public boolean isRuntimePermission(String permission) {
8077            try {
8078                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8079                        .getPermissionInfo(permission, 0);
8080                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8081                        == PermissionInfo.PROTECTION_DANGEROUS;
8082            } catch (NameNotFoundException nnfe) {
8083                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8084            }
8085            return false;
8086        }
8087    }
8088
8089    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8090        @Override
8091        public int checkComponentPermission(String permission, int pid, int uid,
8092                int owningUid, boolean exported) {
8093            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8094                    owningUid, exported);
8095        }
8096
8097        @Override
8098        public Object getAMSLock() {
8099            return ActivityManagerService.this;
8100        }
8101    }
8102
8103    /**
8104     * This can be called with or without the global lock held.
8105     */
8106    int checkComponentPermission(String permission, int pid, int uid,
8107            int owningUid, boolean exported) {
8108        if (pid == MY_PID) {
8109            return PackageManager.PERMISSION_GRANTED;
8110        }
8111        return ActivityManager.checkComponentPermission(permission, uid,
8112                owningUid, exported);
8113    }
8114
8115    /**
8116     * As the only public entry point for permissions checking, this method
8117     * can enforce the semantic that requesting a check on a null global
8118     * permission is automatically denied.  (Internally a null permission
8119     * string is used when calling {@link #checkComponentPermission} in cases
8120     * when only uid-based security is needed.)
8121     *
8122     * This can be called with or without the global lock held.
8123     */
8124    @Override
8125    public int checkPermission(String permission, int pid, int uid) {
8126        if (permission == null) {
8127            return PackageManager.PERMISSION_DENIED;
8128        }
8129        return checkComponentPermission(permission, pid, uid, -1, true);
8130    }
8131
8132    @Override
8133    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8134        if (permission == null) {
8135            return PackageManager.PERMISSION_DENIED;
8136        }
8137
8138        // We might be performing an operation on behalf of an indirect binder
8139        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8140        // client identity accordingly before proceeding.
8141        Identity tlsIdentity = sCallerIdentity.get();
8142        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8143            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8144                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8145            uid = tlsIdentity.uid;
8146            pid = tlsIdentity.pid;
8147        }
8148
8149        return checkComponentPermission(permission, pid, uid, -1, true);
8150    }
8151
8152    /**
8153     * Binder IPC calls go through the public entry point.
8154     * This can be called with or without the global lock held.
8155     */
8156    int checkCallingPermission(String permission) {
8157        return checkPermission(permission,
8158                Binder.getCallingPid(),
8159                UserHandle.getAppId(Binder.getCallingUid()));
8160    }
8161
8162    /**
8163     * This can be called with or without the global lock held.
8164     */
8165    void enforceCallingPermission(String permission, String func) {
8166        if (checkCallingPermission(permission)
8167                == PackageManager.PERMISSION_GRANTED) {
8168            return;
8169        }
8170
8171        String msg = "Permission Denial: " + func + " from pid="
8172                + Binder.getCallingPid()
8173                + ", uid=" + Binder.getCallingUid()
8174                + " requires " + permission;
8175        Slog.w(TAG, msg);
8176        throw new SecurityException(msg);
8177    }
8178
8179    /**
8180     * Determine if UID is holding permissions required to access {@link Uri} in
8181     * the given {@link ProviderInfo}. Final permission checking is always done
8182     * in {@link ContentProvider}.
8183     */
8184    private final boolean checkHoldingPermissionsLocked(
8185            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8186        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8187                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8188        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8189            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8190                    != PERMISSION_GRANTED) {
8191                return false;
8192            }
8193        }
8194        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8195    }
8196
8197    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8198            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8199        if (pi.applicationInfo.uid == uid) {
8200            return true;
8201        } else if (!pi.exported) {
8202            return false;
8203        }
8204
8205        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8206        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8207        try {
8208            // check if target holds top-level <provider> permissions
8209            if (!readMet && pi.readPermission != null && considerUidPermissions
8210                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8211                readMet = true;
8212            }
8213            if (!writeMet && pi.writePermission != null && considerUidPermissions
8214                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8215                writeMet = true;
8216            }
8217
8218            // track if unprotected read/write is allowed; any denied
8219            // <path-permission> below removes this ability
8220            boolean allowDefaultRead = pi.readPermission == null;
8221            boolean allowDefaultWrite = pi.writePermission == null;
8222
8223            // check if target holds any <path-permission> that match uri
8224            final PathPermission[] pps = pi.pathPermissions;
8225            if (pps != null) {
8226                final String path = grantUri.uri.getPath();
8227                int i = pps.length;
8228                while (i > 0 && (!readMet || !writeMet)) {
8229                    i--;
8230                    PathPermission pp = pps[i];
8231                    if (pp.match(path)) {
8232                        if (!readMet) {
8233                            final String pprperm = pp.getReadPermission();
8234                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8235                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8236                                    + ": match=" + pp.match(path)
8237                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8238                            if (pprperm != null) {
8239                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8240                                        == PERMISSION_GRANTED) {
8241                                    readMet = true;
8242                                } else {
8243                                    allowDefaultRead = false;
8244                                }
8245                            }
8246                        }
8247                        if (!writeMet) {
8248                            final String ppwperm = pp.getWritePermission();
8249                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8250                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8251                                    + ": match=" + pp.match(path)
8252                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8253                            if (ppwperm != null) {
8254                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8255                                        == PERMISSION_GRANTED) {
8256                                    writeMet = true;
8257                                } else {
8258                                    allowDefaultWrite = false;
8259                                }
8260                            }
8261                        }
8262                    }
8263                }
8264            }
8265
8266            // grant unprotected <provider> read/write, if not blocked by
8267            // <path-permission> above
8268            if (allowDefaultRead) readMet = true;
8269            if (allowDefaultWrite) writeMet = true;
8270
8271        } catch (RemoteException e) {
8272            return false;
8273        }
8274
8275        return readMet && writeMet;
8276    }
8277
8278    public boolean isAppStartModeDisabled(int uid, String packageName) {
8279        synchronized (this) {
8280            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8281                    == ActivityManager.APP_START_MODE_DISABLED;
8282        }
8283    }
8284
8285    // Unified app-op and target sdk check
8286    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8287        // Apps that target O+ are always subject to background check
8288        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8289            if (DEBUG_BACKGROUND_CHECK) {
8290                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8291            }
8292            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8293        }
8294        // ...and legacy apps get an AppOp check
8295        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8296                uid, packageName);
8297        if (DEBUG_BACKGROUND_CHECK) {
8298            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8299        }
8300        switch (appop) {
8301            case AppOpsManager.MODE_ALLOWED:
8302                return ActivityManager.APP_START_MODE_NORMAL;
8303            case AppOpsManager.MODE_IGNORED:
8304                return ActivityManager.APP_START_MODE_DELAYED;
8305            default:
8306                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8307        }
8308    }
8309
8310    // Service launch is available to apps with run-in-background exemptions but
8311    // some other background operations are not.  If we're doing a check
8312    // of service-launch policy, allow those callers to proceed unrestricted.
8313    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8314        // Persistent app?
8315        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8316            if (DEBUG_BACKGROUND_CHECK) {
8317                Slog.i(TAG, "App " + uid + "/" + packageName
8318                        + " is persistent; not restricted in background");
8319            }
8320            return ActivityManager.APP_START_MODE_NORMAL;
8321        }
8322
8323        // Non-persistent but background whitelisted?
8324        if (uidOnBackgroundWhitelist(uid)) {
8325            if (DEBUG_BACKGROUND_CHECK) {
8326                Slog.i(TAG, "App " + uid + "/" + packageName
8327                        + " on background whitelist; not restricted in background");
8328            }
8329            return ActivityManager.APP_START_MODE_NORMAL;
8330        }
8331
8332        // Is this app on the battery whitelist?
8333        if (isOnDeviceIdleWhitelistLocked(uid)) {
8334            if (DEBUG_BACKGROUND_CHECK) {
8335                Slog.i(TAG, "App " + uid + "/" + packageName
8336                        + " on idle whitelist; not restricted in background");
8337            }
8338            return ActivityManager.APP_START_MODE_NORMAL;
8339        }
8340
8341        // None of the service-policy criteria apply, so we apply the common criteria
8342        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8343    }
8344
8345    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8346            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8347        UidRecord uidRec = mActiveUids.get(uid);
8348        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8349                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8350                + (uidRec != null ? uidRec.idle : false));
8351        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8352            boolean ephemeral;
8353            if (uidRec == null) {
8354                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8355                        UserHandle.getUserId(uid), packageName);
8356            } else {
8357                ephemeral = uidRec.ephemeral;
8358            }
8359
8360            if (ephemeral) {
8361                // We are hard-core about ephemeral apps not running in the background.
8362                return ActivityManager.APP_START_MODE_DISABLED;
8363            } else {
8364                if (disabledOnly) {
8365                    // The caller is only interested in whether app starts are completely
8366                    // disabled for the given package (that is, it is an instant app).  So
8367                    // we don't need to go further, which is all just seeing if we should
8368                    // apply a "delayed" mode for a regular app.
8369                    return ActivityManager.APP_START_MODE_NORMAL;
8370                }
8371                final int startMode = (alwaysRestrict)
8372                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8373                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8374                                packageTargetSdk);
8375                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8376                        + " pkg=" + packageName + " startMode=" + startMode
8377                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8378                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8379                    // This is an old app that has been forced into a "compatible as possible"
8380                    // mode of background check.  To increase compatibility, we will allow other
8381                    // foreground apps to cause its services to start.
8382                    if (callingPid >= 0) {
8383                        ProcessRecord proc;
8384                        synchronized (mPidsSelfLocked) {
8385                            proc = mPidsSelfLocked.get(callingPid);
8386                        }
8387                        if (proc != null && proc.curProcState
8388                                < ActivityManager.PROCESS_STATE_RECEIVER) {
8389                            // Whoever is instigating this is in the foreground, so we will allow it
8390                            // to go through.
8391                            return ActivityManager.APP_START_MODE_NORMAL;
8392                        }
8393                    }
8394                }
8395                return startMode;
8396            }
8397        }
8398        return ActivityManager.APP_START_MODE_NORMAL;
8399    }
8400
8401    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8402        final int appId = UserHandle.getAppId(uid);
8403        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8404                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8405                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8406    }
8407
8408    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8409        ProviderInfo pi = null;
8410        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8411        if (cpr != null) {
8412            pi = cpr.info;
8413        } else {
8414            try {
8415                pi = AppGlobals.getPackageManager().resolveContentProvider(
8416                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8417                        userHandle);
8418            } catch (RemoteException ex) {
8419            }
8420        }
8421        return pi;
8422    }
8423
8424    void grantEphemeralAccessLocked(int userId, Intent intent,
8425            int targetAppId, int ephemeralAppId) {
8426        getPackageManagerInternalLocked().
8427                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8428    }
8429
8430    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8431        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8432        if (targetUris != null) {
8433            return targetUris.get(grantUri);
8434        }
8435        return null;
8436    }
8437
8438    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8439            String targetPkg, int targetUid, GrantUri grantUri) {
8440        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8441        if (targetUris == null) {
8442            targetUris = Maps.newArrayMap();
8443            mGrantedUriPermissions.put(targetUid, targetUris);
8444        }
8445
8446        UriPermission perm = targetUris.get(grantUri);
8447        if (perm == null) {
8448            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8449            targetUris.put(grantUri, perm);
8450        }
8451
8452        return perm;
8453    }
8454
8455    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8456            final int modeFlags) {
8457        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8458        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8459                : UriPermission.STRENGTH_OWNED;
8460
8461        // Root gets to do everything.
8462        if (uid == 0) {
8463            return true;
8464        }
8465
8466        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8467        if (perms == null) return false;
8468
8469        // First look for exact match
8470        final UriPermission exactPerm = perms.get(grantUri);
8471        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8472            return true;
8473        }
8474
8475        // No exact match, look for prefixes
8476        final int N = perms.size();
8477        for (int i = 0; i < N; i++) {
8478            final UriPermission perm = perms.valueAt(i);
8479            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8480                    && perm.getStrength(modeFlags) >= minStrength) {
8481                return true;
8482            }
8483        }
8484
8485        return false;
8486    }
8487
8488    /**
8489     * @param uri This uri must NOT contain an embedded userId.
8490     * @param userId The userId in which the uri is to be resolved.
8491     */
8492    @Override
8493    public int checkUriPermission(Uri uri, int pid, int uid,
8494            final int modeFlags, int userId, IBinder callerToken) {
8495        enforceNotIsolatedCaller("checkUriPermission");
8496
8497        // Another redirected-binder-call permissions check as in
8498        // {@link checkPermissionWithToken}.
8499        Identity tlsIdentity = sCallerIdentity.get();
8500        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8501            uid = tlsIdentity.uid;
8502            pid = tlsIdentity.pid;
8503        }
8504
8505        // Our own process gets to do everything.
8506        if (pid == MY_PID) {
8507            return PackageManager.PERMISSION_GRANTED;
8508        }
8509        synchronized (this) {
8510            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8511                    ? PackageManager.PERMISSION_GRANTED
8512                    : PackageManager.PERMISSION_DENIED;
8513        }
8514    }
8515
8516    /**
8517     * Check if the targetPkg can be granted permission to access uri by
8518     * the callingUid using the given modeFlags.  Throws a security exception
8519     * if callingUid is not allowed to do this.  Returns the uid of the target
8520     * if the URI permission grant should be performed; returns -1 if it is not
8521     * needed (for example targetPkg already has permission to access the URI).
8522     * If you already know the uid of the target, you can supply it in
8523     * lastTargetUid else set that to -1.
8524     */
8525    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8526            final int modeFlags, int lastTargetUid) {
8527        if (!Intent.isAccessUriMode(modeFlags)) {
8528            return -1;
8529        }
8530
8531        if (targetPkg != null) {
8532            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8533                    "Checking grant " + targetPkg + " permission to " + grantUri);
8534        }
8535
8536        final IPackageManager pm = AppGlobals.getPackageManager();
8537
8538        // If this is not a content: uri, we can't do anything with it.
8539        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8540            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8541                    "Can't grant URI permission for non-content URI: " + grantUri);
8542            return -1;
8543        }
8544
8545        final String authority = grantUri.uri.getAuthority();
8546        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8547                MATCH_DEBUG_TRIAGED_MISSING);
8548        if (pi == null) {
8549            Slog.w(TAG, "No content provider found for permission check: " +
8550                    grantUri.uri.toSafeString());
8551            return -1;
8552        }
8553
8554        int targetUid = lastTargetUid;
8555        if (targetUid < 0 && targetPkg != null) {
8556            try {
8557                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8558                        UserHandle.getUserId(callingUid));
8559                if (targetUid < 0) {
8560                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8561                            "Can't grant URI permission no uid for: " + targetPkg);
8562                    return -1;
8563                }
8564            } catch (RemoteException ex) {
8565                return -1;
8566            }
8567        }
8568
8569        // If we're extending a persistable grant, then we always need to create
8570        // the grant data structure so that take/release APIs work
8571        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8572            return targetUid;
8573        }
8574
8575        if (targetUid >= 0) {
8576            // First...  does the target actually need this permission?
8577            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8578                // No need to grant the target this permission.
8579                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8580                        "Target " + targetPkg + " already has full permission to " + grantUri);
8581                return -1;
8582            }
8583        } else {
8584            // First...  there is no target package, so can anyone access it?
8585            boolean allowed = pi.exported;
8586            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8587                if (pi.readPermission != null) {
8588                    allowed = false;
8589                }
8590            }
8591            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8592                if (pi.writePermission != null) {
8593                    allowed = false;
8594                }
8595            }
8596            if (allowed) {
8597                return -1;
8598            }
8599        }
8600
8601        /* There is a special cross user grant if:
8602         * - The target is on another user.
8603         * - Apps on the current user can access the uri without any uid permissions.
8604         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8605         * grant uri permissions.
8606         */
8607        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8608                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8609                modeFlags, false /*without considering the uid permissions*/);
8610
8611        // Second...  is the provider allowing granting of URI permissions?
8612        if (!specialCrossUserGrant) {
8613            if (!pi.grantUriPermissions) {
8614                throw new SecurityException("Provider " + pi.packageName
8615                        + "/" + pi.name
8616                        + " does not allow granting of Uri permissions (uri "
8617                        + grantUri + ")");
8618            }
8619            if (pi.uriPermissionPatterns != null) {
8620                final int N = pi.uriPermissionPatterns.length;
8621                boolean allowed = false;
8622                for (int i=0; i<N; i++) {
8623                    if (pi.uriPermissionPatterns[i] != null
8624                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8625                        allowed = true;
8626                        break;
8627                    }
8628                }
8629                if (!allowed) {
8630                    throw new SecurityException("Provider " + pi.packageName
8631                            + "/" + pi.name
8632                            + " does not allow granting of permission to path of Uri "
8633                            + grantUri);
8634                }
8635            }
8636        }
8637
8638        // Third...  does the caller itself have permission to access
8639        // this uri?
8640        final int callingAppId = UserHandle.getAppId(callingUid);
8641        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8642            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8643                // Exempted authority for cropping user photos in Settings app
8644            } else {
8645                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8646                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8647                return -1;
8648            }
8649        }
8650        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8651            // Require they hold a strong enough Uri permission
8652            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8653                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8654                    throw new SecurityException(
8655                            "UID " + callingUid + " does not have permission to " + grantUri
8656                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8657                                    + "or related APIs");
8658                } else {
8659                    throw new SecurityException(
8660                            "UID " + callingUid + " does not have permission to " + grantUri);
8661                }
8662            }
8663        }
8664        return targetUid;
8665    }
8666
8667    /**
8668     * @param uri This uri must NOT contain an embedded userId.
8669     * @param userId The userId in which the uri is to be resolved.
8670     */
8671    @Override
8672    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8673            final int modeFlags, int userId) {
8674        enforceNotIsolatedCaller("checkGrantUriPermission");
8675        synchronized(this) {
8676            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8677                    new GrantUri(userId, uri, false), modeFlags, -1);
8678        }
8679    }
8680
8681    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8682            final int modeFlags, UriPermissionOwner owner) {
8683        if (!Intent.isAccessUriMode(modeFlags)) {
8684            return;
8685        }
8686
8687        // So here we are: the caller has the assumed permission
8688        // to the uri, and the target doesn't.  Let's now give this to
8689        // the target.
8690
8691        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8692                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8693
8694        final String authority = grantUri.uri.getAuthority();
8695        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8696                MATCH_DEBUG_TRIAGED_MISSING);
8697        if (pi == null) {
8698            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8699            return;
8700        }
8701
8702        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8703            grantUri.prefix = true;
8704        }
8705        final UriPermission perm = findOrCreateUriPermissionLocked(
8706                pi.packageName, targetPkg, targetUid, grantUri);
8707        perm.grantModes(modeFlags, owner);
8708    }
8709
8710    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8711            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8712        if (targetPkg == null) {
8713            throw new NullPointerException("targetPkg");
8714        }
8715        int targetUid;
8716        final IPackageManager pm = AppGlobals.getPackageManager();
8717        try {
8718            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8719        } catch (RemoteException ex) {
8720            return;
8721        }
8722
8723        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8724                targetUid);
8725        if (targetUid < 0) {
8726            return;
8727        }
8728
8729        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8730                owner);
8731    }
8732
8733    static class NeededUriGrants extends ArrayList<GrantUri> {
8734        final String targetPkg;
8735        final int targetUid;
8736        final int flags;
8737
8738        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8739            this.targetPkg = targetPkg;
8740            this.targetUid = targetUid;
8741            this.flags = flags;
8742        }
8743    }
8744
8745    /**
8746     * Like checkGrantUriPermissionLocked, but takes an Intent.
8747     */
8748    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8749            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8750        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8751                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8752                + " clip=" + (intent != null ? intent.getClipData() : null)
8753                + " from " + intent + "; flags=0x"
8754                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8755
8756        if (targetPkg == null) {
8757            throw new NullPointerException("targetPkg");
8758        }
8759
8760        if (intent == null) {
8761            return null;
8762        }
8763        Uri data = intent.getData();
8764        ClipData clip = intent.getClipData();
8765        if (data == null && clip == null) {
8766            return null;
8767        }
8768        // Default userId for uris in the intent (if they don't specify it themselves)
8769        int contentUserHint = intent.getContentUserHint();
8770        if (contentUserHint == UserHandle.USER_CURRENT) {
8771            contentUserHint = UserHandle.getUserId(callingUid);
8772        }
8773        final IPackageManager pm = AppGlobals.getPackageManager();
8774        int targetUid;
8775        if (needed != null) {
8776            targetUid = needed.targetUid;
8777        } else {
8778            try {
8779                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8780                        targetUserId);
8781            } catch (RemoteException ex) {
8782                return null;
8783            }
8784            if (targetUid < 0) {
8785                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8786                        "Can't grant URI permission no uid for: " + targetPkg
8787                        + " on user " + targetUserId);
8788                return null;
8789            }
8790        }
8791        if (data != null) {
8792            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8793            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8794                    targetUid);
8795            if (targetUid > 0) {
8796                if (needed == null) {
8797                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8798                }
8799                needed.add(grantUri);
8800            }
8801        }
8802        if (clip != null) {
8803            for (int i=0; i<clip.getItemCount(); i++) {
8804                Uri uri = clip.getItemAt(i).getUri();
8805                if (uri != null) {
8806                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8807                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8808                            targetUid);
8809                    if (targetUid > 0) {
8810                        if (needed == null) {
8811                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8812                        }
8813                        needed.add(grantUri);
8814                    }
8815                } else {
8816                    Intent clipIntent = clip.getItemAt(i).getIntent();
8817                    if (clipIntent != null) {
8818                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8819                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8820                        if (newNeeded != null) {
8821                            needed = newNeeded;
8822                        }
8823                    }
8824                }
8825            }
8826        }
8827
8828        return needed;
8829    }
8830
8831    /**
8832     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8833     */
8834    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8835            UriPermissionOwner owner) {
8836        if (needed != null) {
8837            for (int i=0; i<needed.size(); i++) {
8838                GrantUri grantUri = needed.get(i);
8839                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8840                        grantUri, needed.flags, owner);
8841            }
8842        }
8843    }
8844
8845    void grantUriPermissionFromIntentLocked(int callingUid,
8846            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8847        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8848                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8849        if (needed == null) {
8850            return;
8851        }
8852
8853        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8854    }
8855
8856    /**
8857     * @param uri This uri must NOT contain an embedded userId.
8858     * @param userId The userId in which the uri is to be resolved.
8859     */
8860    @Override
8861    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8862            final int modeFlags, int userId) {
8863        enforceNotIsolatedCaller("grantUriPermission");
8864        GrantUri grantUri = new GrantUri(userId, uri, false);
8865        synchronized(this) {
8866            final ProcessRecord r = getRecordForAppLocked(caller);
8867            if (r == null) {
8868                throw new SecurityException("Unable to find app for caller "
8869                        + caller
8870                        + " when granting permission to uri " + grantUri);
8871            }
8872            if (targetPkg == null) {
8873                throw new IllegalArgumentException("null target");
8874            }
8875            if (grantUri == null) {
8876                throw new IllegalArgumentException("null uri");
8877            }
8878
8879            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8880                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8881                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8882                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8883
8884            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8885                    UserHandle.getUserId(r.uid));
8886        }
8887    }
8888
8889    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8890        if (perm.modeFlags == 0) {
8891            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8892                    perm.targetUid);
8893            if (perms != null) {
8894                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8895                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8896
8897                perms.remove(perm.uri);
8898                if (perms.isEmpty()) {
8899                    mGrantedUriPermissions.remove(perm.targetUid);
8900                }
8901            }
8902        }
8903    }
8904
8905    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
8906            final int modeFlags) {
8907        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8908                "Revoking all granted permissions to " + grantUri);
8909
8910        final IPackageManager pm = AppGlobals.getPackageManager();
8911        final String authority = grantUri.uri.getAuthority();
8912        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8913                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8914        if (pi == null) {
8915            Slog.w(TAG, "No content provider found for permission revoke: "
8916                    + grantUri.toSafeString());
8917            return;
8918        }
8919
8920        // Does the caller have this permission on the URI?
8921        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8922            // If they don't have direct access to the URI, then revoke any
8923            // ownerless URI permissions that have been granted to them.
8924            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8925            if (perms != null) {
8926                boolean persistChanged = false;
8927                for (int i = perms.size()-1; i >= 0; i--) {
8928                    final UriPermission perm = perms.valueAt(i);
8929                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
8930                        continue;
8931                    }
8932                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8933                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8934                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8935                                "Revoking non-owned " + perm.targetUid
8936                                + " permission to " + perm.uri);
8937                        persistChanged |= perm.revokeModes(
8938                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8939                        if (perm.modeFlags == 0) {
8940                            perms.removeAt(i);
8941                        }
8942                    }
8943                }
8944                if (perms.isEmpty()) {
8945                    mGrantedUriPermissions.remove(callingUid);
8946                }
8947                if (persistChanged) {
8948                    schedulePersistUriGrants();
8949                }
8950            }
8951            return;
8952        }
8953
8954        boolean persistChanged = false;
8955
8956        // Go through all of the permissions and remove any that match.
8957        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
8958            final int targetUid = mGrantedUriPermissions.keyAt(i);
8959            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8960
8961            for (int j = perms.size()-1; j >= 0; j--) {
8962                final UriPermission perm = perms.valueAt(j);
8963                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
8964                    continue;
8965                }
8966                if (perm.uri.sourceUserId == grantUri.sourceUserId
8967                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8968                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8969                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8970                    persistChanged |= perm.revokeModes(
8971                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
8972                            targetPackage == null);
8973                    if (perm.modeFlags == 0) {
8974                        perms.removeAt(j);
8975                    }
8976                }
8977            }
8978
8979            if (perms.isEmpty()) {
8980                mGrantedUriPermissions.removeAt(i);
8981            }
8982        }
8983
8984        if (persistChanged) {
8985            schedulePersistUriGrants();
8986        }
8987    }
8988
8989    /**
8990     * @param uri This uri must NOT contain an embedded userId.
8991     * @param userId The userId in which the uri is to be resolved.
8992     */
8993    @Override
8994    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
8995            final int modeFlags, int userId) {
8996        enforceNotIsolatedCaller("revokeUriPermission");
8997        synchronized(this) {
8998            final ProcessRecord r = getRecordForAppLocked(caller);
8999            if (r == null) {
9000                throw new SecurityException("Unable to find app for caller "
9001                        + caller
9002                        + " when revoking permission to uri " + uri);
9003            }
9004            if (uri == null) {
9005                Slog.w(TAG, "revokeUriPermission: null uri");
9006                return;
9007            }
9008
9009            if (!Intent.isAccessUriMode(modeFlags)) {
9010                return;
9011            }
9012
9013            final String authority = uri.getAuthority();
9014            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9015                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9016            if (pi == null) {
9017                Slog.w(TAG, "No content provider found for permission revoke: "
9018                        + uri.toSafeString());
9019                return;
9020            }
9021
9022            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9023                    modeFlags);
9024        }
9025    }
9026
9027    /**
9028     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9029     * given package.
9030     *
9031     * @param packageName Package name to match, or {@code null} to apply to all
9032     *            packages.
9033     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9034     *            to all users.
9035     * @param persistable If persistable grants should be removed.
9036     */
9037    private void removeUriPermissionsForPackageLocked(
9038            String packageName, int userHandle, boolean persistable) {
9039        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9040            throw new IllegalArgumentException("Must narrow by either package or user");
9041        }
9042
9043        boolean persistChanged = false;
9044
9045        int N = mGrantedUriPermissions.size();
9046        for (int i = 0; i < N; i++) {
9047            final int targetUid = mGrantedUriPermissions.keyAt(i);
9048            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9049
9050            // Only inspect grants matching user
9051            if (userHandle == UserHandle.USER_ALL
9052                    || userHandle == UserHandle.getUserId(targetUid)) {
9053                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9054                    final UriPermission perm = it.next();
9055
9056                    // Only inspect grants matching package
9057                    if (packageName == null || perm.sourcePkg.equals(packageName)
9058                            || perm.targetPkg.equals(packageName)) {
9059                        // Hacky solution as part of fixing a security bug; ignore
9060                        // grants associated with DownloadManager so we don't have
9061                        // to immediately launch it to regrant the permissions
9062                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9063                                && !persistable) continue;
9064
9065                        persistChanged |= perm.revokeModes(persistable
9066                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9067
9068                        // Only remove when no modes remain; any persisted grants
9069                        // will keep this alive.
9070                        if (perm.modeFlags == 0) {
9071                            it.remove();
9072                        }
9073                    }
9074                }
9075
9076                if (perms.isEmpty()) {
9077                    mGrantedUriPermissions.remove(targetUid);
9078                    N--;
9079                    i--;
9080                }
9081            }
9082        }
9083
9084        if (persistChanged) {
9085            schedulePersistUriGrants();
9086        }
9087    }
9088
9089    @Override
9090    public IBinder newUriPermissionOwner(String name) {
9091        enforceNotIsolatedCaller("newUriPermissionOwner");
9092        synchronized(this) {
9093            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9094            return owner.getExternalTokenLocked();
9095        }
9096    }
9097
9098    @Override
9099    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9100        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9101        synchronized(this) {
9102            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9103            if (r == null) {
9104                throw new IllegalArgumentException("Activity does not exist; token="
9105                        + activityToken);
9106            }
9107            return r.getUriPermissionsLocked().getExternalTokenLocked();
9108        }
9109    }
9110    /**
9111     * @param uri This uri must NOT contain an embedded userId.
9112     * @param sourceUserId The userId in which the uri is to be resolved.
9113     * @param targetUserId The userId of the app that receives the grant.
9114     */
9115    @Override
9116    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9117            final int modeFlags, int sourceUserId, int targetUserId) {
9118        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9119                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9120                "grantUriPermissionFromOwner", null);
9121        synchronized(this) {
9122            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9123            if (owner == null) {
9124                throw new IllegalArgumentException("Unknown owner: " + token);
9125            }
9126            if (fromUid != Binder.getCallingUid()) {
9127                if (Binder.getCallingUid() != myUid()) {
9128                    // Only system code can grant URI permissions on behalf
9129                    // of other users.
9130                    throw new SecurityException("nice try");
9131                }
9132            }
9133            if (targetPkg == null) {
9134                throw new IllegalArgumentException("null target");
9135            }
9136            if (uri == null) {
9137                throw new IllegalArgumentException("null uri");
9138            }
9139
9140            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9141                    modeFlags, owner, targetUserId);
9142        }
9143    }
9144
9145    /**
9146     * @param uri This uri must NOT contain an embedded userId.
9147     * @param userId The userId in which the uri is to be resolved.
9148     */
9149    @Override
9150    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9151        synchronized(this) {
9152            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9153            if (owner == null) {
9154                throw new IllegalArgumentException("Unknown owner: " + token);
9155            }
9156
9157            if (uri == null) {
9158                owner.removeUriPermissionsLocked(mode);
9159            } else {
9160                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9161                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9162            }
9163        }
9164    }
9165
9166    private void schedulePersistUriGrants() {
9167        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9168            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9169                    10 * DateUtils.SECOND_IN_MILLIS);
9170        }
9171    }
9172
9173    private void writeGrantedUriPermissions() {
9174        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9175
9176        // Snapshot permissions so we can persist without lock
9177        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9178        synchronized (this) {
9179            final int size = mGrantedUriPermissions.size();
9180            for (int i = 0; i < size; i++) {
9181                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9182                for (UriPermission perm : perms.values()) {
9183                    if (perm.persistedModeFlags != 0) {
9184                        persist.add(perm.snapshot());
9185                    }
9186                }
9187            }
9188        }
9189
9190        FileOutputStream fos = null;
9191        try {
9192            fos = mGrantFile.startWrite();
9193
9194            XmlSerializer out = new FastXmlSerializer();
9195            out.setOutput(fos, StandardCharsets.UTF_8.name());
9196            out.startDocument(null, true);
9197            out.startTag(null, TAG_URI_GRANTS);
9198            for (UriPermission.Snapshot perm : persist) {
9199                out.startTag(null, TAG_URI_GRANT);
9200                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9201                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9202                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9203                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9204                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9205                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9206                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9207                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9208                out.endTag(null, TAG_URI_GRANT);
9209            }
9210            out.endTag(null, TAG_URI_GRANTS);
9211            out.endDocument();
9212
9213            mGrantFile.finishWrite(fos);
9214        } catch (IOException e) {
9215            if (fos != null) {
9216                mGrantFile.failWrite(fos);
9217            }
9218        }
9219    }
9220
9221    private void readGrantedUriPermissionsLocked() {
9222        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9223
9224        final long now = System.currentTimeMillis();
9225
9226        FileInputStream fis = null;
9227        try {
9228            fis = mGrantFile.openRead();
9229            final XmlPullParser in = Xml.newPullParser();
9230            in.setInput(fis, StandardCharsets.UTF_8.name());
9231
9232            int type;
9233            while ((type = in.next()) != END_DOCUMENT) {
9234                final String tag = in.getName();
9235                if (type == START_TAG) {
9236                    if (TAG_URI_GRANT.equals(tag)) {
9237                        final int sourceUserId;
9238                        final int targetUserId;
9239                        final int userHandle = readIntAttribute(in,
9240                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9241                        if (userHandle != UserHandle.USER_NULL) {
9242                            // For backwards compatibility.
9243                            sourceUserId = userHandle;
9244                            targetUserId = userHandle;
9245                        } else {
9246                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9247                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9248                        }
9249                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9250                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9251                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9252                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9253                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9254                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9255
9256                        // Sanity check that provider still belongs to source package
9257                        // Both direct boot aware and unaware packages are fine as we
9258                        // will do filtering at query time to avoid multiple parsing.
9259                        final ProviderInfo pi = getProviderInfoLocked(
9260                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9261                                        | MATCH_DIRECT_BOOT_UNAWARE);
9262                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9263                            int targetUid = -1;
9264                            try {
9265                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9266                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9267                            } catch (RemoteException e) {
9268                            }
9269                            if (targetUid != -1) {
9270                                final UriPermission perm = findOrCreateUriPermissionLocked(
9271                                        sourcePkg, targetPkg, targetUid,
9272                                        new GrantUri(sourceUserId, uri, prefix));
9273                                perm.initPersistedModes(modeFlags, createdTime);
9274                            }
9275                        } else {
9276                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9277                                    + " but instead found " + pi);
9278                        }
9279                    }
9280                }
9281            }
9282        } catch (FileNotFoundException e) {
9283            // Missing grants is okay
9284        } catch (IOException e) {
9285            Slog.wtf(TAG, "Failed reading Uri grants", e);
9286        } catch (XmlPullParserException e) {
9287            Slog.wtf(TAG, "Failed reading Uri grants", e);
9288        } finally {
9289            IoUtils.closeQuietly(fis);
9290        }
9291    }
9292
9293    /**
9294     * @param uri This uri must NOT contain an embedded userId.
9295     * @param userId The userId in which the uri is to be resolved.
9296     */
9297    @Override
9298    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9299        enforceNotIsolatedCaller("takePersistableUriPermission");
9300
9301        Preconditions.checkFlagsArgument(modeFlags,
9302                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9303
9304        synchronized (this) {
9305            final int callingUid = Binder.getCallingUid();
9306            boolean persistChanged = false;
9307            GrantUri grantUri = new GrantUri(userId, uri, false);
9308
9309            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9310                    new GrantUri(userId, uri, false));
9311            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9312                    new GrantUri(userId, uri, true));
9313
9314            final boolean exactValid = (exactPerm != null)
9315                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9316            final boolean prefixValid = (prefixPerm != null)
9317                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9318
9319            if (!(exactValid || prefixValid)) {
9320                throw new SecurityException("No persistable permission grants found for UID "
9321                        + callingUid + " and Uri " + grantUri.toSafeString());
9322            }
9323
9324            if (exactValid) {
9325                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9326            }
9327            if (prefixValid) {
9328                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9329            }
9330
9331            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9332
9333            if (persistChanged) {
9334                schedulePersistUriGrants();
9335            }
9336        }
9337    }
9338
9339    /**
9340     * @param uri This uri must NOT contain an embedded userId.
9341     * @param userId The userId in which the uri is to be resolved.
9342     */
9343    @Override
9344    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9345        enforceNotIsolatedCaller("releasePersistableUriPermission");
9346
9347        Preconditions.checkFlagsArgument(modeFlags,
9348                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9349
9350        synchronized (this) {
9351            final int callingUid = Binder.getCallingUid();
9352            boolean persistChanged = false;
9353
9354            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9355                    new GrantUri(userId, uri, false));
9356            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9357                    new GrantUri(userId, uri, true));
9358            if (exactPerm == null && prefixPerm == null) {
9359                throw new SecurityException("No permission grants found for UID " + callingUid
9360                        + " and Uri " + uri.toSafeString());
9361            }
9362
9363            if (exactPerm != null) {
9364                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9365                removeUriPermissionIfNeededLocked(exactPerm);
9366            }
9367            if (prefixPerm != null) {
9368                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9369                removeUriPermissionIfNeededLocked(prefixPerm);
9370            }
9371
9372            if (persistChanged) {
9373                schedulePersistUriGrants();
9374            }
9375        }
9376    }
9377
9378    /**
9379     * Prune any older {@link UriPermission} for the given UID until outstanding
9380     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9381     *
9382     * @return if any mutations occured that require persisting.
9383     */
9384    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9385        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9386        if (perms == null) return false;
9387        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9388
9389        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9390        for (UriPermission perm : perms.values()) {
9391            if (perm.persistedModeFlags != 0) {
9392                persisted.add(perm);
9393            }
9394        }
9395
9396        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9397        if (trimCount <= 0) return false;
9398
9399        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9400        for (int i = 0; i < trimCount; i++) {
9401            final UriPermission perm = persisted.get(i);
9402
9403            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9404                    "Trimming grant created at " + perm.persistedCreateTime);
9405
9406            perm.releasePersistableModes(~0);
9407            removeUriPermissionIfNeededLocked(perm);
9408        }
9409
9410        return true;
9411    }
9412
9413    @Override
9414    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9415            String packageName, boolean incoming) {
9416        enforceNotIsolatedCaller("getPersistedUriPermissions");
9417        Preconditions.checkNotNull(packageName, "packageName");
9418
9419        final int callingUid = Binder.getCallingUid();
9420        final int callingUserId = UserHandle.getUserId(callingUid);
9421        final IPackageManager pm = AppGlobals.getPackageManager();
9422        try {
9423            final int packageUid = pm.getPackageUid(packageName,
9424                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9425            if (packageUid != callingUid) {
9426                throw new SecurityException(
9427                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9428            }
9429        } catch (RemoteException e) {
9430            throw new SecurityException("Failed to verify package name ownership");
9431        }
9432
9433        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9434        synchronized (this) {
9435            if (incoming) {
9436                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9437                        callingUid);
9438                if (perms == null) {
9439                    Slog.w(TAG, "No permission grants found for " + packageName);
9440                } else {
9441                    for (UriPermission perm : perms.values()) {
9442                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9443                            result.add(perm.buildPersistedPublicApiObject());
9444                        }
9445                    }
9446                }
9447            } else {
9448                final int size = mGrantedUriPermissions.size();
9449                for (int i = 0; i < size; i++) {
9450                    final ArrayMap<GrantUri, UriPermission> perms =
9451                            mGrantedUriPermissions.valueAt(i);
9452                    for (UriPermission perm : perms.values()) {
9453                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9454                            result.add(perm.buildPersistedPublicApiObject());
9455                        }
9456                    }
9457                }
9458            }
9459        }
9460        return new ParceledListSlice<android.content.UriPermission>(result);
9461    }
9462
9463    @Override
9464    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9465            String packageName, int userId) {
9466        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9467                "getGrantedUriPermissions");
9468
9469        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9470        synchronized (this) {
9471            final int size = mGrantedUriPermissions.size();
9472            for (int i = 0; i < size; i++) {
9473                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9474                for (UriPermission perm : perms.values()) {
9475                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9476                            && perm.persistedModeFlags != 0) {
9477                        result.add(perm.buildPersistedPublicApiObject());
9478                    }
9479                }
9480            }
9481        }
9482        return new ParceledListSlice<android.content.UriPermission>(result);
9483    }
9484
9485    @Override
9486    public void clearGrantedUriPermissions(String packageName, int userId) {
9487        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9488                "clearGrantedUriPermissions");
9489        removeUriPermissionsForPackageLocked(packageName, userId, true);
9490    }
9491
9492    @Override
9493    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9494        synchronized (this) {
9495            ProcessRecord app =
9496                who != null ? getRecordForAppLocked(who) : null;
9497            if (app == null) return;
9498
9499            Message msg = Message.obtain();
9500            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9501            msg.obj = app;
9502            msg.arg1 = waiting ? 1 : 0;
9503            mUiHandler.sendMessage(msg);
9504        }
9505    }
9506
9507    @Override
9508    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9509        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9510        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9511        outInfo.availMem = getFreeMemory();
9512        outInfo.totalMem = getTotalMemory();
9513        outInfo.threshold = homeAppMem;
9514        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9515        outInfo.hiddenAppThreshold = cachedAppMem;
9516        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9517                ProcessList.SERVICE_ADJ);
9518        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9519                ProcessList.VISIBLE_APP_ADJ);
9520        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9521                ProcessList.FOREGROUND_APP_ADJ);
9522    }
9523
9524    // =========================================================
9525    // TASK MANAGEMENT
9526    // =========================================================
9527
9528    @Override
9529    public List<IBinder> getAppTasks(String callingPackage) {
9530        int callingUid = Binder.getCallingUid();
9531        long ident = Binder.clearCallingIdentity();
9532
9533        synchronized(this) {
9534            ArrayList<IBinder> list = new ArrayList<IBinder>();
9535            try {
9536                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9537
9538                final int N = mRecentTasks.size();
9539                for (int i = 0; i < N; i++) {
9540                    TaskRecord tr = mRecentTasks.get(i);
9541                    // Skip tasks that do not match the caller.  We don't need to verify
9542                    // callingPackage, because we are also limiting to callingUid and know
9543                    // that will limit to the correct security sandbox.
9544                    if (tr.effectiveUid != callingUid) {
9545                        continue;
9546                    }
9547                    Intent intent = tr.getBaseIntent();
9548                    if (intent == null ||
9549                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9550                        continue;
9551                    }
9552                    ActivityManager.RecentTaskInfo taskInfo =
9553                            createRecentTaskInfoFromTaskRecord(tr);
9554                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9555                    list.add(taskImpl.asBinder());
9556                }
9557            } finally {
9558                Binder.restoreCallingIdentity(ident);
9559            }
9560            return list;
9561        }
9562    }
9563
9564    @Override
9565    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9566        final int callingUid = Binder.getCallingUid();
9567        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9568
9569        synchronized(this) {
9570            if (DEBUG_ALL) Slog.v(
9571                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9572
9573            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9574                    callingUid);
9575
9576            // TODO: Improve with MRU list from all ActivityStacks.
9577            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9578        }
9579
9580        return list;
9581    }
9582
9583    /**
9584     * Creates a new RecentTaskInfo from a TaskRecord.
9585     */
9586    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9587        // Update the task description to reflect any changes in the task stack
9588        tr.updateTaskDescription();
9589
9590        // Compose the recent task info
9591        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9592        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9593        rti.persistentId = tr.taskId;
9594        rti.baseIntent = new Intent(tr.getBaseIntent());
9595        rti.origActivity = tr.origActivity;
9596        rti.realActivity = tr.realActivity;
9597        rti.description = tr.lastDescription;
9598        rti.stackId = tr.getStackId();
9599        rti.userId = tr.userId;
9600        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9601        rti.firstActiveTime = tr.firstActiveTime;
9602        rti.lastActiveTime = tr.lastActiveTime;
9603        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9604        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9605        rti.numActivities = 0;
9606        if (tr.mBounds != null) {
9607            rti.bounds = new Rect(tr.mBounds);
9608        }
9609        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9610        rti.resizeMode = tr.mResizeMode;
9611
9612        ActivityRecord base = null;
9613        ActivityRecord top = null;
9614        ActivityRecord tmp;
9615
9616        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9617            tmp = tr.mActivities.get(i);
9618            if (tmp.finishing) {
9619                continue;
9620            }
9621            base = tmp;
9622            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9623                top = base;
9624            }
9625            rti.numActivities++;
9626        }
9627
9628        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9629        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9630
9631        return rti;
9632    }
9633
9634    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9635        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9636                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9637        if (!allowed) {
9638            if (checkPermission(android.Manifest.permission.GET_TASKS,
9639                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9640                // Temporary compatibility: some existing apps on the system image may
9641                // still be requesting the old permission and not switched to the new
9642                // one; if so, we'll still allow them full access.  This means we need
9643                // to see if they are holding the old permission and are a system app.
9644                try {
9645                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9646                        allowed = true;
9647                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9648                                + " is using old GET_TASKS but privileged; allowing");
9649                    }
9650                } catch (RemoteException e) {
9651                }
9652            }
9653        }
9654        if (!allowed) {
9655            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9656                    + " does not hold REAL_GET_TASKS; limiting output");
9657        }
9658        return allowed;
9659    }
9660
9661    @Override
9662    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9663            int userId) {
9664        final int callingUid = Binder.getCallingUid();
9665        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9666                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9667
9668        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9669        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9670        synchronized (this) {
9671            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9672                    callingUid);
9673            final boolean detailed = checkCallingPermission(
9674                    android.Manifest.permission.GET_DETAILED_TASKS)
9675                    == PackageManager.PERMISSION_GRANTED;
9676
9677            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9678                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9679                return ParceledListSlice.emptyList();
9680            }
9681            mRecentTasks.loadUserRecentsLocked(userId);
9682
9683            final int recentsCount = mRecentTasks.size();
9684            ArrayList<ActivityManager.RecentTaskInfo> res =
9685                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9686
9687            final Set<Integer> includedUsers;
9688            if (includeProfiles) {
9689                includedUsers = mUserController.getProfileIds(userId);
9690            } else {
9691                includedUsers = new HashSet<>();
9692            }
9693            includedUsers.add(Integer.valueOf(userId));
9694
9695            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9696                TaskRecord tr = mRecentTasks.get(i);
9697                // Only add calling user or related users recent tasks
9698                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9699                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9700                    continue;
9701                }
9702
9703                if (tr.realActivitySuspended) {
9704                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9705                    continue;
9706                }
9707
9708                // Return the entry if desired by the caller.  We always return
9709                // the first entry, because callers always expect this to be the
9710                // foreground app.  We may filter others if the caller has
9711                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9712                // we should exclude the entry.
9713
9714                if (i == 0
9715                        || withExcluded
9716                        || (tr.intent == null)
9717                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9718                                == 0)) {
9719                    if (!allowed) {
9720                        // If the caller doesn't have the GET_TASKS permission, then only
9721                        // allow them to see a small subset of tasks -- their own and home.
9722                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9723                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9724                            continue;
9725                        }
9726                    }
9727                    final ActivityStack stack = tr.getStack();
9728                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9729                        if (stack != null && stack.isHomeOrRecentsStack()) {
9730                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9731                                    "Skipping, home or recents stack task: " + tr);
9732                            continue;
9733                        }
9734                    }
9735                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9736                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9737                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9738                                    "Skipping, top task in docked stack: " + tr);
9739                            continue;
9740                        }
9741                    }
9742                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9743                        if (stack != null && stack.isPinnedStack()) {
9744                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9745                                    "Skipping, pinned stack task: " + tr);
9746                            continue;
9747                        }
9748                    }
9749                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9750                        // Don't include auto remove tasks that are finished or finishing.
9751                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9752                                "Skipping, auto-remove without activity: " + tr);
9753                        continue;
9754                    }
9755                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9756                            && !tr.isAvailable) {
9757                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9758                                "Skipping, unavail real act: " + tr);
9759                        continue;
9760                    }
9761
9762                    if (!tr.mUserSetupComplete) {
9763                        // Don't include task launched while user is not done setting-up.
9764                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9765                                "Skipping, user setup not complete: " + tr);
9766                        continue;
9767                    }
9768
9769                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9770                    if (!detailed) {
9771                        rti.baseIntent.replaceExtras((Bundle)null);
9772                    }
9773
9774                    res.add(rti);
9775                    maxNum--;
9776                }
9777            }
9778            return new ParceledListSlice<>(res);
9779        }
9780    }
9781
9782    @Override
9783    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9784        synchronized (this) {
9785            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9786                    "getTaskThumbnail()");
9787            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9788                    id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9789            if (tr != null) {
9790                return tr.getTaskThumbnailLocked();
9791            }
9792        }
9793        return null;
9794    }
9795
9796    @Override
9797    public ActivityManager.TaskDescription getTaskDescription(int id) {
9798        synchronized (this) {
9799            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9800                    "getTaskDescription()");
9801            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9802                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9803            if (tr != null) {
9804                return tr.lastTaskDescription;
9805            }
9806        }
9807        return null;
9808    }
9809
9810    @Override
9811    public int addAppTask(IBinder activityToken, Intent intent,
9812            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9813        final int callingUid = Binder.getCallingUid();
9814        final long callingIdent = Binder.clearCallingIdentity();
9815
9816        try {
9817            synchronized (this) {
9818                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9819                if (r == null) {
9820                    throw new IllegalArgumentException("Activity does not exist; token="
9821                            + activityToken);
9822                }
9823                ComponentName comp = intent.getComponent();
9824                if (comp == null) {
9825                    throw new IllegalArgumentException("Intent " + intent
9826                            + " must specify explicit component");
9827                }
9828                if (thumbnail.getWidth() != mThumbnailWidth
9829                        || thumbnail.getHeight() != mThumbnailHeight) {
9830                    throw new IllegalArgumentException("Bad thumbnail size: got "
9831                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9832                            + mThumbnailWidth + "x" + mThumbnailHeight);
9833                }
9834                if (intent.getSelector() != null) {
9835                    intent.setSelector(null);
9836                }
9837                if (intent.getSourceBounds() != null) {
9838                    intent.setSourceBounds(null);
9839                }
9840                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9841                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9842                        // The caller has added this as an auto-remove task...  that makes no
9843                        // sense, so turn off auto-remove.
9844                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9845                    }
9846                }
9847                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9848                    mLastAddedTaskActivity = null;
9849                }
9850                ActivityInfo ainfo = mLastAddedTaskActivity;
9851                if (ainfo == null) {
9852                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9853                            comp, 0, UserHandle.getUserId(callingUid));
9854                    if (ainfo.applicationInfo.uid != callingUid) {
9855                        throw new SecurityException(
9856                                "Can't add task for another application: target uid="
9857                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9858                    }
9859                }
9860
9861                TaskRecord task = new TaskRecord(this,
9862                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9863                        ainfo, intent, description, new TaskThumbnailInfo());
9864
9865                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9866                if (trimIdx >= 0) {
9867                    // If this would have caused a trim, then we'll abort because that
9868                    // means it would be added at the end of the list but then just removed.
9869                    return INVALID_TASK_ID;
9870                }
9871
9872                final int N = mRecentTasks.size();
9873                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9874                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9875                    tr.removedFromRecents();
9876                }
9877
9878                task.inRecents = true;
9879                mRecentTasks.add(task);
9880                r.getStack().addTask(task, false, "addAppTask");
9881
9882                task.setLastThumbnailLocked(thumbnail);
9883                task.freeLastThumbnail();
9884                return task.taskId;
9885            }
9886        } finally {
9887            Binder.restoreCallingIdentity(callingIdent);
9888        }
9889    }
9890
9891    @Override
9892    public Point getAppTaskThumbnailSize() {
9893        synchronized (this) {
9894            return new Point(mThumbnailWidth,  mThumbnailHeight);
9895        }
9896    }
9897
9898    @Override
9899    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9900        synchronized (this) {
9901            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9902            if (r != null) {
9903                r.setTaskDescription(td);
9904                final TaskRecord task = r.getTask();
9905                task.updateTaskDescription();
9906                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
9907            }
9908        }
9909    }
9910
9911    @Override
9912    public void setTaskResizeable(int taskId, int resizeableMode) {
9913        synchronized (this) {
9914            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9915                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9916            if (task == null) {
9917                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9918                return;
9919            }
9920            task.setResizeMode(resizeableMode);
9921        }
9922    }
9923
9924    @Override
9925    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9926        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9927        long ident = Binder.clearCallingIdentity();
9928        try {
9929            synchronized (this) {
9930                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9931                if (task == null) {
9932                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9933                    return;
9934                }
9935                // Place the task in the right stack if it isn't there already based on
9936                // the requested bounds.
9937                // The stack transition logic is:
9938                // - a null bounds on a freeform task moves that task to fullscreen
9939                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9940                //   that task to freeform
9941                // - otherwise the task is not moved
9942                int stackId = task.getStackId();
9943                if (!StackId.isTaskResizeAllowed(stackId)) {
9944                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9945                }
9946                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9947                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9948                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9949                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9950                }
9951
9952                // Reparent the task to the right stack if necessary
9953                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9954                if (stackId != task.getStackId()) {
9955                    // Defer resume until the task is resized below
9956                    task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
9957                            DEFER_RESUME, "resizeTask");
9958                    preserveWindow = false;
9959                }
9960
9961                // After reparenting (which only resizes the task to the stack bounds), resize the
9962                // task to the actual bounds provided
9963                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
9964            }
9965        } finally {
9966            Binder.restoreCallingIdentity(ident);
9967        }
9968    }
9969
9970    @Override
9971    public Rect getTaskBounds(int taskId) {
9972        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9973        long ident = Binder.clearCallingIdentity();
9974        Rect rect = new Rect();
9975        try {
9976            synchronized (this) {
9977                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
9978                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9979                if (task == null) {
9980                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9981                    return rect;
9982                }
9983                if (task.getStack() != null) {
9984                    // Return the bounds from window manager since it will be adjusted for various
9985                    // things like the presense of a docked stack for tasks that aren't resizeable.
9986                    task.getWindowContainerBounds(rect);
9987                } else {
9988                    // Task isn't in window manager yet since it isn't associated with a stack.
9989                    // Return the persist value from activity manager
9990                    if (task.mBounds != null) {
9991                        rect.set(task.mBounds);
9992                    } else if (task.mLastNonFullscreenBounds != null) {
9993                        rect.set(task.mLastNonFullscreenBounds);
9994                    }
9995                }
9996            }
9997        } finally {
9998            Binder.restoreCallingIdentity(ident);
9999        }
10000        return rect;
10001    }
10002
10003    @Override
10004    public void cancelTaskWindowTransition(int taskId) {
10005        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10006        final long ident = Binder.clearCallingIdentity();
10007        try {
10008            synchronized (this) {
10009                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10010                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10011                if (task == null) {
10012                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10013                    return;
10014                }
10015                task.cancelWindowTransition();
10016            }
10017        } finally {
10018            Binder.restoreCallingIdentity(ident);
10019        }
10020    }
10021
10022    @Override
10023    public void cancelTaskThumbnailTransition(int taskId) {
10024        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10025        final long ident = Binder.clearCallingIdentity();
10026        try {
10027            synchronized (this) {
10028                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10029                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10030                if (task == null) {
10031                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10032                    return;
10033                }
10034                task.cancelThumbnailTransition();
10035            }
10036        } finally {
10037            Binder.restoreCallingIdentity(ident);
10038        }
10039    }
10040
10041    @Override
10042    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10043        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10044        final long ident = Binder.clearCallingIdentity();
10045        try {
10046            final TaskRecord task;
10047            synchronized (this) {
10048                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10049                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10050                if (task == null) {
10051                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10052                    return null;
10053                }
10054            }
10055            // Don't call this while holding the lock as this operation might hit the disk.
10056            return task.getSnapshot(reducedResolution);
10057        } finally {
10058            Binder.restoreCallingIdentity(ident);
10059        }
10060    }
10061
10062    @Override
10063    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10064        if (userId != UserHandle.getCallingUserId()) {
10065            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10066                    "getTaskDescriptionIcon");
10067        }
10068        final File passedIconFile = new File(filePath);
10069        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10070                passedIconFile.getName());
10071        if (!legitIconFile.getPath().equals(filePath)
10072                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10073            throw new IllegalArgumentException("Bad file path: " + filePath
10074                    + " passed for userId " + userId);
10075        }
10076        return mRecentTasks.getTaskDescriptionIcon(filePath);
10077    }
10078
10079    @Override
10080    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10081            throws RemoteException {
10082        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10083        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10084                activityOptions.getCustomInPlaceResId() == 0) {
10085            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10086                    "with valid animation");
10087        }
10088        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10089        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10090                activityOptions.getCustomInPlaceResId());
10091        mWindowManager.executeAppTransition();
10092    }
10093
10094    private void removeTasksByPackageNameLocked(String packageName, int userId) {
10095        // Remove all tasks with activities in the specified package from the list of recent tasks
10096        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10097            TaskRecord tr = mRecentTasks.get(i);
10098            if (tr.userId != userId) continue;
10099
10100            ComponentName cn = tr.intent.getComponent();
10101            if (cn != null && cn.getPackageName().equals(packageName)) {
10102                // If the package name matches, remove the task.
10103                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10104            }
10105        }
10106    }
10107
10108    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10109            int userId) {
10110
10111        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10112            TaskRecord tr = mRecentTasks.get(i);
10113            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10114                continue;
10115            }
10116
10117            ComponentName cn = tr.intent.getComponent();
10118            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10119                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10120            if (sameComponent) {
10121                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10122            }
10123        }
10124    }
10125
10126    @Override
10127    public void removeStack(int stackId) {
10128        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10129        if (StackId.isHomeOrRecentsStack(stackId)) {
10130            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10131        }
10132
10133        synchronized (this) {
10134            final long ident = Binder.clearCallingIdentity();
10135            try {
10136                mStackSupervisor.removeStackLocked(stackId);
10137            } finally {
10138                Binder.restoreCallingIdentity(ident);
10139            }
10140        }
10141    }
10142
10143    @Override
10144    public void moveStackToDisplay(int stackId, int displayId) {
10145        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
10146
10147        synchronized (this) {
10148            final long ident = Binder.clearCallingIdentity();
10149            try {
10150                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10151                        + " to displayId=" + displayId);
10152                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10153            } finally {
10154                Binder.restoreCallingIdentity(ident);
10155            }
10156        }
10157    }
10158
10159    @Override
10160    public boolean removeTask(int taskId) {
10161        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10162        synchronized (this) {
10163            final long ident = Binder.clearCallingIdentity();
10164            try {
10165                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10166            } finally {
10167                Binder.restoreCallingIdentity(ident);
10168            }
10169        }
10170    }
10171
10172    /**
10173     * TODO: Add mController hook
10174     */
10175    @Override
10176    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10177        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10178
10179        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10180        synchronized(this) {
10181            moveTaskToFrontLocked(taskId, flags, bOptions);
10182        }
10183    }
10184
10185    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
10186        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10187
10188        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10189                Binder.getCallingUid(), -1, -1, "Task to front")) {
10190            ActivityOptions.abort(options);
10191            return;
10192        }
10193        final long origId = Binder.clearCallingIdentity();
10194        try {
10195            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10196            if (task == null) {
10197                Slog.d(TAG, "Could not find task for id: "+ taskId);
10198                return;
10199            }
10200            if (mStackSupervisor.isLockTaskModeViolation(task)) {
10201                mStackSupervisor.showLockTaskToast();
10202                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10203                return;
10204            }
10205            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10206            if (prev != null) {
10207                task.setTaskToReturnTo(prev);
10208            }
10209            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10210                    false /* forceNonResizable */);
10211
10212            final ActivityRecord topActivity = task.getTopActivity();
10213            if (topActivity != null) {
10214
10215                // We are reshowing a task, use a starting window to hide the initial draw delay
10216                // so the transition can start earlier.
10217                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10218                        true /* taskSwitch */);
10219            }
10220        } finally {
10221            Binder.restoreCallingIdentity(origId);
10222        }
10223        ActivityOptions.abort(options);
10224    }
10225
10226    /**
10227     * Attempts to move a task backwards in z-order (the order of activities within the task is
10228     * unchanged).
10229     *
10230     * There are several possible results of this call:
10231     * - if the task is locked, then we will show the lock toast
10232     * - if there is a task behind the provided task, then that task is made visible and resumed as
10233     *   this task is moved to the back
10234     * - otherwise, if there are no other tasks in the stack:
10235     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10236     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10237     *       (depending on whether it is visible)
10238     *     - otherwise, we simply return home and hide this task
10239     *
10240     * @param token A reference to the activity we wish to move
10241     * @param nonRoot If false then this only works if the activity is the root
10242     *                of a task; if true it will work for any activity in a task.
10243     * @return Returns true if the move completed, false if not.
10244     */
10245    @Override
10246    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10247        enforceNotIsolatedCaller("moveActivityTaskToBack");
10248        synchronized(this) {
10249            final long origId = Binder.clearCallingIdentity();
10250            try {
10251                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10252                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10253                if (task != null) {
10254                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10255                }
10256            } finally {
10257                Binder.restoreCallingIdentity(origId);
10258            }
10259        }
10260        return false;
10261    }
10262
10263    @Override
10264    public void moveTaskBackwards(int task) {
10265        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10266                "moveTaskBackwards()");
10267
10268        synchronized(this) {
10269            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10270                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10271                return;
10272            }
10273            final long origId = Binder.clearCallingIdentity();
10274            moveTaskBackwardsLocked(task);
10275            Binder.restoreCallingIdentity(origId);
10276        }
10277    }
10278
10279    private final void moveTaskBackwardsLocked(int task) {
10280        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10281    }
10282
10283    @Override
10284    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10285            IActivityContainerCallback callback) throws RemoteException {
10286        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10287        synchronized (this) {
10288            if (parentActivityToken == null) {
10289                throw new IllegalArgumentException("parent token must not be null");
10290            }
10291            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10292            if (r == null) {
10293                return null;
10294            }
10295            if (callback == null) {
10296                throw new IllegalArgumentException("callback must not be null");
10297            }
10298            return mStackSupervisor.createVirtualActivityContainer(r, callback);
10299        }
10300    }
10301
10302    @Override
10303    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10304        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10305        synchronized (this) {
10306            final int stackId = mStackSupervisor.getNextStackId();
10307            final ActivityStack stack =
10308                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10309            if (stack == null) {
10310                return null;
10311            }
10312            return stack.mActivityContainer;
10313        }
10314    }
10315
10316    @Override
10317    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10318        synchronized (this) {
10319            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10320            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10321                return stack.mActivityContainer.getDisplayId();
10322            }
10323            return DEFAULT_DISPLAY;
10324        }
10325    }
10326
10327    @Override
10328    public int getActivityStackId(IBinder token) throws RemoteException {
10329        synchronized (this) {
10330            ActivityStack stack = ActivityRecord.getStackLocked(token);
10331            if (stack == null) {
10332                return INVALID_STACK_ID;
10333            }
10334            return stack.mStackId;
10335        }
10336    }
10337
10338    @Override
10339    public void exitFreeformMode(IBinder token) throws RemoteException {
10340        synchronized (this) {
10341            long ident = Binder.clearCallingIdentity();
10342            try {
10343                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10344                if (r == null) {
10345                    throw new IllegalArgumentException(
10346                            "exitFreeformMode: No activity record matching token=" + token);
10347                }
10348
10349                final ActivityStack stack = r.getStack();
10350                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10351                    throw new IllegalStateException(
10352                            "exitFreeformMode: You can only go fullscreen from freeform.");
10353                }
10354
10355                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10356                r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10357                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10358            } finally {
10359                Binder.restoreCallingIdentity(ident);
10360            }
10361        }
10362    }
10363
10364    @Override
10365    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10366        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10367        if (StackId.isHomeOrRecentsStack(stackId)) {
10368            throw new IllegalArgumentException(
10369                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10370        }
10371        synchronized (this) {
10372            long ident = Binder.clearCallingIdentity();
10373            try {
10374                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10375                if (task == null) {
10376                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10377                    return;
10378                }
10379
10380                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10381                        + " to stackId=" + stackId + " toTop=" + toTop);
10382                if (stackId == DOCKED_STACK_ID) {
10383                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10384                            null /* initialBounds */);
10385                }
10386                task.reparent(stackId, toTop,
10387                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10388            } finally {
10389                Binder.restoreCallingIdentity(ident);
10390            }
10391        }
10392    }
10393
10394    @Override
10395    public void swapDockedAndFullscreenStack() throws RemoteException {
10396        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10397        synchronized (this) {
10398            long ident = Binder.clearCallingIdentity();
10399            try {
10400                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10401                        FULLSCREEN_WORKSPACE_STACK_ID);
10402                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10403                        : null;
10404                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10405                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10406                        : null;
10407                if (topTask == null || tasks == null || tasks.size() == 0) {
10408                    Slog.w(TAG,
10409                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10410                    return;
10411                }
10412
10413                // TODO: App transition
10414                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10415
10416                // Defer the resume until we move all the docked tasks to the fullscreen stack below
10417                topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10418                        DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10419                final int size = tasks.size();
10420                for (int i = 0; i < size; i++) {
10421                    final int id = tasks.get(i).taskId;
10422                    if (id == topTask.taskId) {
10423                        continue;
10424                    }
10425
10426                    // Defer the resume until after all the tasks have been moved
10427                    tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10428                            REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10429                            "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10430                }
10431
10432                // Because we deferred the resume to avoid conflicts with stack switches while
10433                // resuming, we need to do it after all the tasks are moved.
10434                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10435                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10436
10437                mWindowManager.executeAppTransition();
10438            } finally {
10439                Binder.restoreCallingIdentity(ident);
10440            }
10441        }
10442    }
10443
10444    /**
10445     * Moves the input task to the docked stack.
10446     *
10447     * @param taskId Id of task to move.
10448     * @param createMode The mode the docked stack should be created in if it doesn't exist
10449     *                   already. See
10450     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10451     *                   and
10452     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10453     * @param toTop If the task and stack should be moved to the top.
10454     * @param animate Whether we should play an animation for the moving the task
10455     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10456     *                      docked stack. Pass {@code null} to use default bounds.
10457     */
10458    @Override
10459    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10460            Rect initialBounds) {
10461        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10462        synchronized (this) {
10463            long ident = Binder.clearCallingIdentity();
10464            try {
10465                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10466                if (task == null) {
10467                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10468                    return false;
10469                }
10470
10471                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10472                        + " to createMode=" + createMode + " toTop=" + toTop);
10473                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10474
10475                // Defer resuming until we move the home stack to the front below
10476                final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10477                        REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10478                        "moveTaskToDockedStack");
10479                if (moved) {
10480                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10481                }
10482                return moved;
10483            } finally {
10484                Binder.restoreCallingIdentity(ident);
10485            }
10486        }
10487    }
10488
10489    /**
10490     * Moves the top activity in the input stackId to the pinned stack.
10491     *
10492     * @param stackId Id of stack to move the top activity to pinned stack.
10493     * @param bounds Bounds to use for pinned stack.
10494     *
10495     * @return True if the top activity of the input stack was successfully moved to the pinned
10496     *          stack.
10497     */
10498    @Override
10499    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10500        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10501        synchronized (this) {
10502            if (!mSupportsPictureInPicture) {
10503                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10504                        + "Device doesn't support picture-in-picture mode");
10505            }
10506
10507            long ident = Binder.clearCallingIdentity();
10508            try {
10509                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10510            } finally {
10511                Binder.restoreCallingIdentity(ident);
10512            }
10513        }
10514    }
10515
10516    @Override
10517    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10518            boolean preserveWindows, boolean animate, int animationDuration) {
10519        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10520        long ident = Binder.clearCallingIdentity();
10521        try {
10522            synchronized (this) {
10523                if (animate) {
10524                    if (stackId == PINNED_STACK_ID) {
10525                        final PinnedActivityStack pinnedStack =
10526                                mStackSupervisor.getStack(PINNED_STACK_ID);
10527                        if (pinnedStack != null) {
10528                            pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10529                                    destBounds, animationDuration,
10530                                    false /* schedulePipModeChangedOnAnimationEnd */);
10531                        }
10532                    } else {
10533                        throw new IllegalArgumentException("Stack: " + stackId
10534                                + " doesn't support animated resize.");
10535                    }
10536                } else {
10537                    mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10538                            null /* tempTaskInsetBounds */, preserveWindows,
10539                            allowResizeInDockedMode, !DEFER_RESUME);
10540                }
10541            }
10542        } finally {
10543            Binder.restoreCallingIdentity(ident);
10544        }
10545    }
10546
10547    @Override
10548    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10549            Rect tempDockedTaskInsetBounds,
10550            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10551        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10552                "resizeDockedStack()");
10553        long ident = Binder.clearCallingIdentity();
10554        try {
10555            synchronized (this) {
10556                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10557                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10558                        PRESERVE_WINDOWS);
10559            }
10560        } finally {
10561            Binder.restoreCallingIdentity(ident);
10562        }
10563    }
10564
10565    @Override
10566    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10567        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10568                "resizePinnedStack()");
10569        final long ident = Binder.clearCallingIdentity();
10570        try {
10571            synchronized (this) {
10572                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10573            }
10574        } finally {
10575            Binder.restoreCallingIdentity(ident);
10576        }
10577    }
10578
10579    /**
10580     * Try to place task to provided position. The final position might be different depending on
10581     * current user and stacks state. The task will be moved to target stack if it's currently in
10582     * different stack.
10583     */
10584    @Override
10585    public void positionTaskInStack(int taskId, int stackId, int position) {
10586        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10587        if (StackId.isHomeOrRecentsStack(stackId)) {
10588            throw new IllegalArgumentException(
10589                    "positionTaskInStack: Attempt to change the position of task "
10590                    + taskId + " in/to home/recents stack");
10591        }
10592        synchronized (this) {
10593            long ident = Binder.clearCallingIdentity();
10594            try {
10595                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10596                        + taskId + " in stackId=" + stackId + " at position=" + position);
10597                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10598                if (task == null) {
10599                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10600                            + taskId);
10601                }
10602
10603                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10604                        !ON_TOP);
10605
10606                // TODO: Have the callers of this API call a separate reparent method if that is
10607                // what they intended to do vs. having this method also do reparenting.
10608                if (task.getStack() == stack) {
10609                    // Change position in current stack.
10610                    stack.positionChildAt(task, position);
10611                } else {
10612                    // Reparent to new stack.
10613                    task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10614                            !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10615                }
10616            } finally {
10617                Binder.restoreCallingIdentity(ident);
10618            }
10619        }
10620    }
10621
10622    @Override
10623    public List<StackInfo> getAllStackInfos() {
10624        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10625        long ident = Binder.clearCallingIdentity();
10626        try {
10627            synchronized (this) {
10628                return mStackSupervisor.getAllStackInfosLocked();
10629            }
10630        } finally {
10631            Binder.restoreCallingIdentity(ident);
10632        }
10633    }
10634
10635    @Override
10636    public StackInfo getStackInfo(int stackId) {
10637        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10638        long ident = Binder.clearCallingIdentity();
10639        try {
10640            synchronized (this) {
10641                return mStackSupervisor.getStackInfoLocked(stackId);
10642            }
10643        } finally {
10644            Binder.restoreCallingIdentity(ident);
10645        }
10646    }
10647
10648    @Override
10649    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10650        synchronized(this) {
10651            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10652        }
10653    }
10654
10655    @Override
10656    public void updateDeviceOwner(String packageName) {
10657        final int callingUid = Binder.getCallingUid();
10658        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10659            throw new SecurityException("updateDeviceOwner called from non-system process");
10660        }
10661        synchronized (this) {
10662            mDeviceOwnerName = packageName;
10663        }
10664    }
10665
10666    @Override
10667    public void updateLockTaskPackages(int userId, String[] packages) {
10668        final int callingUid = Binder.getCallingUid();
10669        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10670            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10671                    "updateLockTaskPackages()");
10672        }
10673        synchronized (this) {
10674            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10675                    Arrays.toString(packages));
10676            mLockTaskPackages.put(userId, packages);
10677            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10678        }
10679    }
10680
10681
10682    void startLockTaskModeLocked(TaskRecord task) {
10683        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10684        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10685            return;
10686        }
10687
10688        // When a task is locked, dismiss the pinned stack if it exists
10689        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10690                PINNED_STACK_ID);
10691        if (pinnedStack != null) {
10692            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10693        }
10694
10695        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10696        // is initiated by system after the pinning request was shown and locked mode is initiated
10697        // by an authorized app directly
10698        final int callingUid = Binder.getCallingUid();
10699        boolean isSystemInitiated = callingUid == SYSTEM_UID;
10700        long ident = Binder.clearCallingIdentity();
10701        try {
10702            if (!isSystemInitiated) {
10703                task.mLockTaskUid = callingUid;
10704                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10705                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10706                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10707                    StatusBarManagerInternal statusBarManager =
10708                            LocalServices.getService(StatusBarManagerInternal.class);
10709                    if (statusBarManager != null) {
10710                        statusBarManager.showScreenPinningRequest(task.taskId);
10711                    }
10712                    return;
10713                }
10714
10715                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10716                if (stack == null || task != stack.topTask()) {
10717                    throw new IllegalArgumentException("Invalid task, not in foreground");
10718                }
10719            }
10720            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10721                    "Locking fully");
10722            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10723                    ActivityManager.LOCK_TASK_MODE_PINNED :
10724                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10725                    "startLockTask", true);
10726        } finally {
10727            Binder.restoreCallingIdentity(ident);
10728        }
10729    }
10730
10731    @Override
10732    public void startLockTaskModeById(int taskId) {
10733        synchronized (this) {
10734            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10735            if (task != null) {
10736                startLockTaskModeLocked(task);
10737            }
10738        }
10739    }
10740
10741    @Override
10742    public void startLockTaskModeByToken(IBinder token) {
10743        synchronized (this) {
10744            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10745            if (r == null) {
10746                return;
10747            }
10748            final TaskRecord task = r.getTask();
10749            if (task != null) {
10750                startLockTaskModeLocked(task);
10751            }
10752        }
10753    }
10754
10755    @Override
10756    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10757        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10758        // This makes inner call to look as if it was initiated by system.
10759        long ident = Binder.clearCallingIdentity();
10760        try {
10761            synchronized (this) {
10762                startLockTaskModeById(taskId);
10763            }
10764        } finally {
10765            Binder.restoreCallingIdentity(ident);
10766        }
10767    }
10768
10769    @Override
10770    public void stopLockTaskMode() {
10771        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10772        if (lockTask == null) {
10773            // Our work here is done.
10774            return;
10775        }
10776
10777        final int callingUid = Binder.getCallingUid();
10778        final int lockTaskUid = lockTask.mLockTaskUid;
10779        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10780        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10781            // Done.
10782            return;
10783        } else {
10784            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10785            // It is possible lockTaskMode was started by the system process because
10786            // android:lockTaskMode is set to a locking value in the application manifest
10787            // instead of the app calling startLockTaskMode. In this case
10788            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10789            // {@link TaskRecord.effectiveUid} instead. Also caller with
10790            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10791            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10792                    && callingUid != lockTaskUid
10793                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10794                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10795                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10796            }
10797        }
10798        long ident = Binder.clearCallingIdentity();
10799        try {
10800            Log.d(TAG, "stopLockTaskMode");
10801            // Stop lock task
10802            synchronized (this) {
10803                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10804                        "stopLockTask", true);
10805            }
10806            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10807            if (tm != null) {
10808                tm.showInCallScreen(false);
10809            }
10810        } finally {
10811            Binder.restoreCallingIdentity(ident);
10812        }
10813    }
10814
10815    /**
10816     * This API should be called by SystemUI only when user perform certain action to dismiss
10817     * lock task mode. We should only dismiss pinned lock task mode in this case.
10818     */
10819    @Override
10820    public void stopSystemLockTaskMode() throws RemoteException {
10821        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10822            stopLockTaskMode();
10823        } else {
10824            mStackSupervisor.showLockTaskToast();
10825        }
10826    }
10827
10828    @Override
10829    public boolean isInLockTaskMode() {
10830        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10831    }
10832
10833    @Override
10834    public int getLockTaskModeState() {
10835        synchronized (this) {
10836            return mStackSupervisor.getLockTaskModeState();
10837        }
10838    }
10839
10840    @Override
10841    public void showLockTaskEscapeMessage(IBinder token) {
10842        synchronized (this) {
10843            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10844            if (r == null) {
10845                return;
10846            }
10847            mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
10848        }
10849    }
10850
10851    @Override
10852    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
10853            throws RemoteException {
10854        synchronized (this) {
10855            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10856            if (r == null) {
10857                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
10858                        + token);
10859                return;
10860            }
10861            final long origId = Binder.clearCallingIdentity();
10862            try {
10863                r.setDisablePreviewScreenshots(disable);
10864            } finally {
10865                Binder.restoreCallingIdentity(origId);
10866            }
10867        }
10868    }
10869
10870    // =========================================================
10871    // CONTENT PROVIDERS
10872    // =========================================================
10873
10874    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10875        List<ProviderInfo> providers = null;
10876        try {
10877            providers = AppGlobals.getPackageManager()
10878                    .queryContentProviders(app.processName, app.uid,
10879                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10880                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
10881                    .getList();
10882        } catch (RemoteException ex) {
10883        }
10884        if (DEBUG_MU) Slog.v(TAG_MU,
10885                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10886        int userId = app.userId;
10887        if (providers != null) {
10888            int N = providers.size();
10889            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10890            for (int i=0; i<N; i++) {
10891                // TODO: keep logic in sync with installEncryptionUnawareProviders
10892                ProviderInfo cpi =
10893                    (ProviderInfo)providers.get(i);
10894                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10895                        cpi.name, cpi.flags);
10896                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10897                    // This is a singleton provider, but a user besides the
10898                    // default user is asking to initialize a process it runs
10899                    // in...  well, no, it doesn't actually run in this process,
10900                    // it runs in the process of the default user.  Get rid of it.
10901                    providers.remove(i);
10902                    N--;
10903                    i--;
10904                    continue;
10905                }
10906
10907                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10908                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10909                if (cpr == null) {
10910                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10911                    mProviderMap.putProviderByClass(comp, cpr);
10912                }
10913                if (DEBUG_MU) Slog.v(TAG_MU,
10914                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10915                app.pubProviders.put(cpi.name, cpr);
10916                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10917                    // Don't add this if it is a platform component that is marked
10918                    // to run in multiple processes, because this is actually
10919                    // part of the framework so doesn't make sense to track as a
10920                    // separate apk in the process.
10921                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10922                            mProcessStats);
10923                }
10924                notifyPackageUse(cpi.applicationInfo.packageName,
10925                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10926            }
10927        }
10928        return providers;
10929    }
10930
10931    /**
10932     * Check if the calling UID has a possible chance at accessing the provider
10933     * at the given authority and user.
10934     */
10935    public String checkContentProviderAccess(String authority, int userId) {
10936        if (userId == UserHandle.USER_ALL) {
10937            mContext.enforceCallingOrSelfPermission(
10938                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10939            userId = UserHandle.getCallingUserId();
10940        }
10941
10942        ProviderInfo cpi = null;
10943        try {
10944            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10945                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10946                            | PackageManager.MATCH_DISABLED_COMPONENTS
10947                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10948                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10949                    userId);
10950        } catch (RemoteException ignored) {
10951        }
10952        if (cpi == null) {
10953            return "Failed to find provider " + authority + " for user " + userId
10954                    + "; expected to find a valid ContentProvider for this authority";
10955        }
10956
10957        ProcessRecord r = null;
10958        synchronized (mPidsSelfLocked) {
10959            r = mPidsSelfLocked.get(Binder.getCallingPid());
10960        }
10961        if (r == null) {
10962            return "Failed to find PID " + Binder.getCallingPid();
10963        }
10964
10965        synchronized (this) {
10966            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10967        }
10968    }
10969
10970    /**
10971     * Check if {@link ProcessRecord} has a possible chance at accessing the
10972     * given {@link ProviderInfo}. Final permission checking is always done
10973     * in {@link ContentProvider}.
10974     */
10975    private final String checkContentProviderPermissionLocked(
10976            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10977        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10978        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10979        boolean checkedGrants = false;
10980        if (checkUser) {
10981            // Looking for cross-user grants before enforcing the typical cross-users permissions
10982            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10983            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10984                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10985                    return null;
10986                }
10987                checkedGrants = true;
10988            }
10989            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10990                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10991            if (userId != tmpTargetUserId) {
10992                // When we actually went to determine the final targer user ID, this ended
10993                // up different than our initial check for the authority.  This is because
10994                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10995                // SELF.  So we need to re-check the grants again.
10996                checkedGrants = false;
10997            }
10998        }
10999        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11000                cpi.applicationInfo.uid, cpi.exported)
11001                == PackageManager.PERMISSION_GRANTED) {
11002            return null;
11003        }
11004        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11005                cpi.applicationInfo.uid, cpi.exported)
11006                == PackageManager.PERMISSION_GRANTED) {
11007            return null;
11008        }
11009
11010        PathPermission[] pps = cpi.pathPermissions;
11011        if (pps != null) {
11012            int i = pps.length;
11013            while (i > 0) {
11014                i--;
11015                PathPermission pp = pps[i];
11016                String pprperm = pp.getReadPermission();
11017                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11018                        cpi.applicationInfo.uid, cpi.exported)
11019                        == PackageManager.PERMISSION_GRANTED) {
11020                    return null;
11021                }
11022                String ppwperm = pp.getWritePermission();
11023                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11024                        cpi.applicationInfo.uid, cpi.exported)
11025                        == PackageManager.PERMISSION_GRANTED) {
11026                    return null;
11027                }
11028            }
11029        }
11030        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11031            return null;
11032        }
11033
11034        final String suffix;
11035        if (!cpi.exported) {
11036            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11037        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11038            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11039        } else {
11040            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11041        }
11042        final String msg = "Permission Denial: opening provider " + cpi.name
11043                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11044                + ", uid=" + callingUid + ")" + suffix;
11045        Slog.w(TAG, msg);
11046        return msg;
11047    }
11048
11049    /**
11050     * Returns if the ContentProvider has granted a uri to callingUid
11051     */
11052    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11053        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11054        if (perms != null) {
11055            for (int i=perms.size()-1; i>=0; i--) {
11056                GrantUri grantUri = perms.keyAt(i);
11057                if (grantUri.sourceUserId == userId || !checkUser) {
11058                    if (matchesProvider(grantUri.uri, cpi)) {
11059                        return true;
11060                    }
11061                }
11062            }
11063        }
11064        return false;
11065    }
11066
11067    /**
11068     * Returns true if the uri authority is one of the authorities specified in the provider.
11069     */
11070    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11071        String uriAuth = uri.getAuthority();
11072        String cpiAuth = cpi.authority;
11073        if (cpiAuth.indexOf(';') == -1) {
11074            return cpiAuth.equals(uriAuth);
11075        }
11076        String[] cpiAuths = cpiAuth.split(";");
11077        int length = cpiAuths.length;
11078        for (int i = 0; i < length; i++) {
11079            if (cpiAuths[i].equals(uriAuth)) return true;
11080        }
11081        return false;
11082    }
11083
11084    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11085            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11086        if (r != null) {
11087            for (int i=0; i<r.conProviders.size(); i++) {
11088                ContentProviderConnection conn = r.conProviders.get(i);
11089                if (conn.provider == cpr) {
11090                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11091                            "Adding provider requested by "
11092                            + r.processName + " from process "
11093                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11094                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11095                    if (stable) {
11096                        conn.stableCount++;
11097                        conn.numStableIncs++;
11098                    } else {
11099                        conn.unstableCount++;
11100                        conn.numUnstableIncs++;
11101                    }
11102                    return conn;
11103                }
11104            }
11105            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11106            if (stable) {
11107                conn.stableCount = 1;
11108                conn.numStableIncs = 1;
11109            } else {
11110                conn.unstableCount = 1;
11111                conn.numUnstableIncs = 1;
11112            }
11113            cpr.connections.add(conn);
11114            r.conProviders.add(conn);
11115            startAssociationLocked(r.uid, r.processName, r.curProcState,
11116                    cpr.uid, cpr.name, cpr.info.processName);
11117            return conn;
11118        }
11119        cpr.addExternalProcessHandleLocked(externalProcessToken);
11120        return null;
11121    }
11122
11123    boolean decProviderCountLocked(ContentProviderConnection conn,
11124            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11125        if (conn != null) {
11126            cpr = conn.provider;
11127            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11128                    "Removing provider requested by "
11129                    + conn.client.processName + " from process "
11130                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11131                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11132            if (stable) {
11133                conn.stableCount--;
11134            } else {
11135                conn.unstableCount--;
11136            }
11137            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11138                cpr.connections.remove(conn);
11139                conn.client.conProviders.remove(conn);
11140                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11141                    // The client is more important than last activity -- note the time this
11142                    // is happening, so we keep the old provider process around a bit as last
11143                    // activity to avoid thrashing it.
11144                    if (cpr.proc != null) {
11145                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11146                    }
11147                }
11148                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11149                return true;
11150            }
11151            return false;
11152        }
11153        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11154        return false;
11155    }
11156
11157    private void checkTime(long startTime, String where) {
11158        long now = SystemClock.uptimeMillis();
11159        if ((now-startTime) > 50) {
11160            // If we are taking more than 50ms, log about it.
11161            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11162        }
11163    }
11164
11165    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11166            PROC_SPACE_TERM,
11167            PROC_SPACE_TERM|PROC_PARENS,
11168            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11169    };
11170
11171    private final long[] mProcessStateStatsLongs = new long[1];
11172
11173    boolean isProcessAliveLocked(ProcessRecord proc) {
11174        if (proc.procStatFile == null) {
11175            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11176        }
11177        mProcessStateStatsLongs[0] = 0;
11178        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11179                mProcessStateStatsLongs, null)) {
11180            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11181            return false;
11182        }
11183        final long state = mProcessStateStatsLongs[0];
11184        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11185                + (char)state);
11186        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11187    }
11188
11189    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11190            String name, IBinder token, boolean stable, int userId) {
11191        ContentProviderRecord cpr;
11192        ContentProviderConnection conn = null;
11193        ProviderInfo cpi = null;
11194
11195        synchronized(this) {
11196            long startTime = SystemClock.uptimeMillis();
11197
11198            ProcessRecord r = null;
11199            if (caller != null) {
11200                r = getRecordForAppLocked(caller);
11201                if (r == null) {
11202                    throw new SecurityException(
11203                            "Unable to find app for caller " + caller
11204                          + " (pid=" + Binder.getCallingPid()
11205                          + ") when getting content provider " + name);
11206                }
11207            }
11208
11209            boolean checkCrossUser = true;
11210
11211            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11212
11213            // First check if this content provider has been published...
11214            cpr = mProviderMap.getProviderByName(name, userId);
11215            // If that didn't work, check if it exists for user 0 and then
11216            // verify that it's a singleton provider before using it.
11217            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11218                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11219                if (cpr != null) {
11220                    cpi = cpr.info;
11221                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11222                            cpi.name, cpi.flags)
11223                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11224                        userId = UserHandle.USER_SYSTEM;
11225                        checkCrossUser = false;
11226                    } else {
11227                        cpr = null;
11228                        cpi = null;
11229                    }
11230                }
11231            }
11232
11233            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11234            if (providerRunning) {
11235                cpi = cpr.info;
11236                String msg;
11237                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11238                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11239                        != null) {
11240                    throw new SecurityException(msg);
11241                }
11242                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11243
11244                if (r != null && cpr.canRunHere(r)) {
11245                    // This provider has been published or is in the process
11246                    // of being published...  but it is also allowed to run
11247                    // in the caller's process, so don't make a connection
11248                    // and just let the caller instantiate its own instance.
11249                    ContentProviderHolder holder = cpr.newHolder(null);
11250                    // don't give caller the provider object, it needs
11251                    // to make its own.
11252                    holder.provider = null;
11253                    return holder;
11254                }
11255
11256                final long origId = Binder.clearCallingIdentity();
11257
11258                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11259
11260                // In this case the provider instance already exists, so we can
11261                // return it right away.
11262                conn = incProviderCountLocked(r, cpr, token, stable);
11263                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11264                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11265                        // If this is a perceptible app accessing the provider,
11266                        // make sure to count it as being accessed and thus
11267                        // back up on the LRU list.  This is good because
11268                        // content providers are often expensive to start.
11269                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11270                        updateLruProcessLocked(cpr.proc, false, null);
11271                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11272                    }
11273                }
11274
11275                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11276                final int verifiedAdj = cpr.proc.verifiedAdj;
11277                boolean success = updateOomAdjLocked(cpr.proc);
11278                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11279                // if the process has been successfully adjusted.  So to reduce races with
11280                // it, we will check whether the process still exists.  Note that this doesn't
11281                // completely get rid of races with LMK killing the process, but should make
11282                // them much smaller.
11283                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11284                    success = false;
11285                }
11286                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11287                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11288                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11289                // NOTE: there is still a race here where a signal could be
11290                // pending on the process even though we managed to update its
11291                // adj level.  Not sure what to do about this, but at least
11292                // the race is now smaller.
11293                if (!success) {
11294                    // Uh oh...  it looks like the provider's process
11295                    // has been killed on us.  We need to wait for a new
11296                    // process to be started, and make sure its death
11297                    // doesn't kill our process.
11298                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11299                            + " is crashing; detaching " + r);
11300                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11301                    checkTime(startTime, "getContentProviderImpl: before appDied");
11302                    appDiedLocked(cpr.proc);
11303                    checkTime(startTime, "getContentProviderImpl: after appDied");
11304                    if (!lastRef) {
11305                        // This wasn't the last ref our process had on
11306                        // the provider...  we have now been killed, bail.
11307                        return null;
11308                    }
11309                    providerRunning = false;
11310                    conn = null;
11311                } else {
11312                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11313                }
11314
11315                Binder.restoreCallingIdentity(origId);
11316            }
11317
11318            if (!providerRunning) {
11319                try {
11320                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11321                    cpi = AppGlobals.getPackageManager().
11322                        resolveContentProvider(name,
11323                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11324                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11325                } catch (RemoteException ex) {
11326                }
11327                if (cpi == null) {
11328                    return null;
11329                }
11330                // If the provider is a singleton AND
11331                // (it's a call within the same user || the provider is a
11332                // privileged app)
11333                // Then allow connecting to the singleton provider
11334                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11335                        cpi.name, cpi.flags)
11336                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11337                if (singleton) {
11338                    userId = UserHandle.USER_SYSTEM;
11339                }
11340                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11341                checkTime(startTime, "getContentProviderImpl: got app info for user");
11342
11343                String msg;
11344                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11345                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11346                        != null) {
11347                    throw new SecurityException(msg);
11348                }
11349                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11350
11351                if (!mProcessesReady
11352                        && !cpi.processName.equals("system")) {
11353                    // If this content provider does not run in the system
11354                    // process, and the system is not yet ready to run other
11355                    // processes, then fail fast instead of hanging.
11356                    throw new IllegalArgumentException(
11357                            "Attempt to launch content provider before system ready");
11358                }
11359
11360                // Make sure that the user who owns this provider is running.  If not,
11361                // we don't want to allow it to run.
11362                if (!mUserController.isUserRunningLocked(userId, 0)) {
11363                    Slog.w(TAG, "Unable to launch app "
11364                            + cpi.applicationInfo.packageName + "/"
11365                            + cpi.applicationInfo.uid + " for provider "
11366                            + name + ": user " + userId + " is stopped");
11367                    return null;
11368                }
11369
11370                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11371                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11372                cpr = mProviderMap.getProviderByClass(comp, userId);
11373                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11374                final boolean firstClass = cpr == null;
11375                if (firstClass) {
11376                    final long ident = Binder.clearCallingIdentity();
11377
11378                    // If permissions need a review before any of the app components can run,
11379                    // we return no provider and launch a review activity if the calling app
11380                    // is in the foreground.
11381                    if (mPermissionReviewRequired) {
11382                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11383                            return null;
11384                        }
11385                    }
11386
11387                    try {
11388                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11389                        ApplicationInfo ai =
11390                            AppGlobals.getPackageManager().
11391                                getApplicationInfo(
11392                                        cpi.applicationInfo.packageName,
11393                                        STOCK_PM_FLAGS, userId);
11394                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11395                        if (ai == null) {
11396                            Slog.w(TAG, "No package info for content provider "
11397                                    + cpi.name);
11398                            return null;
11399                        }
11400                        ai = getAppInfoForUser(ai, userId);
11401                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11402                    } catch (RemoteException ex) {
11403                        // pm is in same process, this will never happen.
11404                    } finally {
11405                        Binder.restoreCallingIdentity(ident);
11406                    }
11407                }
11408
11409                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11410
11411                if (r != null && cpr.canRunHere(r)) {
11412                    // If this is a multiprocess provider, then just return its
11413                    // info and allow the caller to instantiate it.  Only do
11414                    // this if the provider is the same user as the caller's
11415                    // process, or can run as root (so can be in any process).
11416                    return cpr.newHolder(null);
11417                }
11418
11419                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11420                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11421                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11422
11423                // This is single process, and our app is now connecting to it.
11424                // See if we are already in the process of launching this
11425                // provider.
11426                final int N = mLaunchingProviders.size();
11427                int i;
11428                for (i = 0; i < N; i++) {
11429                    if (mLaunchingProviders.get(i) == cpr) {
11430                        break;
11431                    }
11432                }
11433
11434                // If the provider is not already being launched, then get it
11435                // started.
11436                if (i >= N) {
11437                    final long origId = Binder.clearCallingIdentity();
11438
11439                    try {
11440                        // Content provider is now in use, its package can't be stopped.
11441                        try {
11442                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11443                            AppGlobals.getPackageManager().setPackageStoppedState(
11444                                    cpr.appInfo.packageName, false, userId);
11445                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11446                        } catch (RemoteException e) {
11447                        } catch (IllegalArgumentException e) {
11448                            Slog.w(TAG, "Failed trying to unstop package "
11449                                    + cpr.appInfo.packageName + ": " + e);
11450                        }
11451
11452                        // Use existing process if already started
11453                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11454                        ProcessRecord proc = getProcessRecordLocked(
11455                                cpi.processName, cpr.appInfo.uid, false);
11456                        if (proc != null && proc.thread != null && !proc.killed) {
11457                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11458                                    "Installing in existing process " + proc);
11459                            if (!proc.pubProviders.containsKey(cpi.name)) {
11460                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11461                                proc.pubProviders.put(cpi.name, cpr);
11462                                try {
11463                                    proc.thread.scheduleInstallProvider(cpi);
11464                                } catch (RemoteException e) {
11465                                }
11466                            }
11467                        } else {
11468                            checkTime(startTime, "getContentProviderImpl: before start process");
11469                            proc = startProcessLocked(cpi.processName,
11470                                    cpr.appInfo, false, 0, "content provider",
11471                                    new ComponentName(cpi.applicationInfo.packageName,
11472                                            cpi.name), false, false, false);
11473                            checkTime(startTime, "getContentProviderImpl: after start process");
11474                            if (proc == null) {
11475                                Slog.w(TAG, "Unable to launch app "
11476                                        + cpi.applicationInfo.packageName + "/"
11477                                        + cpi.applicationInfo.uid + " for provider "
11478                                        + name + ": process is bad");
11479                                return null;
11480                            }
11481                        }
11482                        cpr.launchingApp = proc;
11483                        mLaunchingProviders.add(cpr);
11484                    } finally {
11485                        Binder.restoreCallingIdentity(origId);
11486                    }
11487                }
11488
11489                checkTime(startTime, "getContentProviderImpl: updating data structures");
11490
11491                // Make sure the provider is published (the same provider class
11492                // may be published under multiple names).
11493                if (firstClass) {
11494                    mProviderMap.putProviderByClass(comp, cpr);
11495                }
11496
11497                mProviderMap.putProviderByName(name, cpr);
11498                conn = incProviderCountLocked(r, cpr, token, stable);
11499                if (conn != null) {
11500                    conn.waiting = true;
11501                }
11502            }
11503            checkTime(startTime, "getContentProviderImpl: done!");
11504
11505            grantEphemeralAccessLocked(userId, null /*intent*/,
11506                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11507        }
11508
11509        // Wait for the provider to be published...
11510        synchronized (cpr) {
11511            while (cpr.provider == null) {
11512                if (cpr.launchingApp == null) {
11513                    Slog.w(TAG, "Unable to launch app "
11514                            + cpi.applicationInfo.packageName + "/"
11515                            + cpi.applicationInfo.uid + " for provider "
11516                            + name + ": launching app became null");
11517                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11518                            UserHandle.getUserId(cpi.applicationInfo.uid),
11519                            cpi.applicationInfo.packageName,
11520                            cpi.applicationInfo.uid, name);
11521                    return null;
11522                }
11523                try {
11524                    if (DEBUG_MU) Slog.v(TAG_MU,
11525                            "Waiting to start provider " + cpr
11526                            + " launchingApp=" + cpr.launchingApp);
11527                    if (conn != null) {
11528                        conn.waiting = true;
11529                    }
11530                    cpr.wait();
11531                } catch (InterruptedException ex) {
11532                } finally {
11533                    if (conn != null) {
11534                        conn.waiting = false;
11535                    }
11536                }
11537            }
11538        }
11539        return cpr != null ? cpr.newHolder(conn) : null;
11540    }
11541
11542    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11543            ProcessRecord r, final int userId) {
11544        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11545                cpi.packageName, userId)) {
11546
11547            final boolean callerForeground = r == null || r.setSchedGroup
11548                    != ProcessList.SCHED_GROUP_BACKGROUND;
11549
11550            // Show a permission review UI only for starting from a foreground app
11551            if (!callerForeground) {
11552                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11553                        + cpi.packageName + " requires a permissions review");
11554                return false;
11555            }
11556
11557            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11558            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11559                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11560            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11561
11562            if (DEBUG_PERMISSIONS_REVIEW) {
11563                Slog.i(TAG, "u" + userId + " Launching permission review "
11564                        + "for package " + cpi.packageName);
11565            }
11566
11567            final UserHandle userHandle = new UserHandle(userId);
11568            mHandler.post(new Runnable() {
11569                @Override
11570                public void run() {
11571                    mContext.startActivityAsUser(intent, userHandle);
11572                }
11573            });
11574
11575            return false;
11576        }
11577
11578        return true;
11579    }
11580
11581    PackageManagerInternal getPackageManagerInternalLocked() {
11582        if (mPackageManagerInt == null) {
11583            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11584        }
11585        return mPackageManagerInt;
11586    }
11587
11588    @Override
11589    public final ContentProviderHolder getContentProvider(
11590            IApplicationThread caller, String name, int userId, boolean stable) {
11591        enforceNotIsolatedCaller("getContentProvider");
11592        if (caller == null) {
11593            String msg = "null IApplicationThread when getting content provider "
11594                    + name;
11595            Slog.w(TAG, msg);
11596            throw new SecurityException(msg);
11597        }
11598        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11599        // with cross-user grant.
11600        return getContentProviderImpl(caller, name, null, stable, userId);
11601    }
11602
11603    public ContentProviderHolder getContentProviderExternal(
11604            String name, int userId, IBinder token) {
11605        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11606            "Do not have permission in call getContentProviderExternal()");
11607        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11608                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11609        return getContentProviderExternalUnchecked(name, token, userId);
11610    }
11611
11612    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11613            IBinder token, int userId) {
11614        return getContentProviderImpl(null, name, token, true, userId);
11615    }
11616
11617    /**
11618     * Drop a content provider from a ProcessRecord's bookkeeping
11619     */
11620    public void removeContentProvider(IBinder connection, boolean stable) {
11621        enforceNotIsolatedCaller("removeContentProvider");
11622        long ident = Binder.clearCallingIdentity();
11623        try {
11624            synchronized (this) {
11625                ContentProviderConnection conn;
11626                try {
11627                    conn = (ContentProviderConnection)connection;
11628                } catch (ClassCastException e) {
11629                    String msg ="removeContentProvider: " + connection
11630                            + " not a ContentProviderConnection";
11631                    Slog.w(TAG, msg);
11632                    throw new IllegalArgumentException(msg);
11633                }
11634                if (conn == null) {
11635                    throw new NullPointerException("connection is null");
11636                }
11637                if (decProviderCountLocked(conn, null, null, stable)) {
11638                    updateOomAdjLocked();
11639                }
11640            }
11641        } finally {
11642            Binder.restoreCallingIdentity(ident);
11643        }
11644    }
11645
11646    public void removeContentProviderExternal(String name, IBinder token) {
11647        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11648            "Do not have permission in call removeContentProviderExternal()");
11649        int userId = UserHandle.getCallingUserId();
11650        long ident = Binder.clearCallingIdentity();
11651        try {
11652            removeContentProviderExternalUnchecked(name, token, userId);
11653        } finally {
11654            Binder.restoreCallingIdentity(ident);
11655        }
11656    }
11657
11658    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11659        synchronized (this) {
11660            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11661            if(cpr == null) {
11662                //remove from mProvidersByClass
11663                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11664                return;
11665            }
11666
11667            //update content provider record entry info
11668            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11669            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11670            if (localCpr.hasExternalProcessHandles()) {
11671                if (localCpr.removeExternalProcessHandleLocked(token)) {
11672                    updateOomAdjLocked();
11673                } else {
11674                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11675                            + " with no external reference for token: "
11676                            + token + ".");
11677                }
11678            } else {
11679                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11680                        + " with no external references.");
11681            }
11682        }
11683    }
11684
11685    public final void publishContentProviders(IApplicationThread caller,
11686            List<ContentProviderHolder> providers) {
11687        if (providers == null) {
11688            return;
11689        }
11690
11691        enforceNotIsolatedCaller("publishContentProviders");
11692        synchronized (this) {
11693            final ProcessRecord r = getRecordForAppLocked(caller);
11694            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11695            if (r == null) {
11696                throw new SecurityException(
11697                        "Unable to find app for caller " + caller
11698                      + " (pid=" + Binder.getCallingPid()
11699                      + ") when publishing content providers");
11700            }
11701
11702            final long origId = Binder.clearCallingIdentity();
11703
11704            final int N = providers.size();
11705            for (int i = 0; i < N; i++) {
11706                ContentProviderHolder src = providers.get(i);
11707                if (src == null || src.info == null || src.provider == null) {
11708                    continue;
11709                }
11710                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11711                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11712                if (dst != null) {
11713                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11714                    mProviderMap.putProviderByClass(comp, dst);
11715                    String names[] = dst.info.authority.split(";");
11716                    for (int j = 0; j < names.length; j++) {
11717                        mProviderMap.putProviderByName(names[j], dst);
11718                    }
11719
11720                    int launchingCount = mLaunchingProviders.size();
11721                    int j;
11722                    boolean wasInLaunchingProviders = false;
11723                    for (j = 0; j < launchingCount; j++) {
11724                        if (mLaunchingProviders.get(j) == dst) {
11725                            mLaunchingProviders.remove(j);
11726                            wasInLaunchingProviders = true;
11727                            j--;
11728                            launchingCount--;
11729                        }
11730                    }
11731                    if (wasInLaunchingProviders) {
11732                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11733                    }
11734                    synchronized (dst) {
11735                        dst.provider = src.provider;
11736                        dst.proc = r;
11737                        dst.notifyAll();
11738                    }
11739                    updateOomAdjLocked(r);
11740                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11741                            src.info.authority);
11742                }
11743            }
11744
11745            Binder.restoreCallingIdentity(origId);
11746        }
11747    }
11748
11749    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11750        ContentProviderConnection conn;
11751        try {
11752            conn = (ContentProviderConnection)connection;
11753        } catch (ClassCastException e) {
11754            String msg ="refContentProvider: " + connection
11755                    + " not a ContentProviderConnection";
11756            Slog.w(TAG, msg);
11757            throw new IllegalArgumentException(msg);
11758        }
11759        if (conn == null) {
11760            throw new NullPointerException("connection is null");
11761        }
11762
11763        synchronized (this) {
11764            if (stable > 0) {
11765                conn.numStableIncs += stable;
11766            }
11767            stable = conn.stableCount + stable;
11768            if (stable < 0) {
11769                throw new IllegalStateException("stableCount < 0: " + stable);
11770            }
11771
11772            if (unstable > 0) {
11773                conn.numUnstableIncs += unstable;
11774            }
11775            unstable = conn.unstableCount + unstable;
11776            if (unstable < 0) {
11777                throw new IllegalStateException("unstableCount < 0: " + unstable);
11778            }
11779
11780            if ((stable+unstable) <= 0) {
11781                throw new IllegalStateException("ref counts can't go to zero here: stable="
11782                        + stable + " unstable=" + unstable);
11783            }
11784            conn.stableCount = stable;
11785            conn.unstableCount = unstable;
11786            return !conn.dead;
11787        }
11788    }
11789
11790    public void unstableProviderDied(IBinder connection) {
11791        ContentProviderConnection conn;
11792        try {
11793            conn = (ContentProviderConnection)connection;
11794        } catch (ClassCastException e) {
11795            String msg ="refContentProvider: " + connection
11796                    + " not a ContentProviderConnection";
11797            Slog.w(TAG, msg);
11798            throw new IllegalArgumentException(msg);
11799        }
11800        if (conn == null) {
11801            throw new NullPointerException("connection is null");
11802        }
11803
11804        // Safely retrieve the content provider associated with the connection.
11805        IContentProvider provider;
11806        synchronized (this) {
11807            provider = conn.provider.provider;
11808        }
11809
11810        if (provider == null) {
11811            // Um, yeah, we're way ahead of you.
11812            return;
11813        }
11814
11815        // Make sure the caller is being honest with us.
11816        if (provider.asBinder().pingBinder()) {
11817            // Er, no, still looks good to us.
11818            synchronized (this) {
11819                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11820                        + " says " + conn + " died, but we don't agree");
11821                return;
11822            }
11823        }
11824
11825        // Well look at that!  It's dead!
11826        synchronized (this) {
11827            if (conn.provider.provider != provider) {
11828                // But something changed...  good enough.
11829                return;
11830            }
11831
11832            ProcessRecord proc = conn.provider.proc;
11833            if (proc == null || proc.thread == null) {
11834                // Seems like the process is already cleaned up.
11835                return;
11836            }
11837
11838            // As far as we're concerned, this is just like receiving a
11839            // death notification...  just a bit prematurely.
11840            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11841                    + ") early provider death");
11842            final long ident = Binder.clearCallingIdentity();
11843            try {
11844                appDiedLocked(proc);
11845            } finally {
11846                Binder.restoreCallingIdentity(ident);
11847            }
11848        }
11849    }
11850
11851    @Override
11852    public void appNotRespondingViaProvider(IBinder connection) {
11853        enforceCallingPermission(
11854                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11855
11856        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11857        if (conn == null) {
11858            Slog.w(TAG, "ContentProviderConnection is null");
11859            return;
11860        }
11861
11862        final ProcessRecord host = conn.provider.proc;
11863        if (host == null) {
11864            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11865            return;
11866        }
11867
11868        mHandler.post(new Runnable() {
11869            @Override
11870            public void run() {
11871                mAppErrors.appNotResponding(host, null, null, false,
11872                        "ContentProvider not responding");
11873            }
11874        });
11875    }
11876
11877    public final void installSystemProviders() {
11878        List<ProviderInfo> providers;
11879        synchronized (this) {
11880            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
11881            providers = generateApplicationProvidersLocked(app);
11882            if (providers != null) {
11883                for (int i=providers.size()-1; i>=0; i--) {
11884                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11885                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11886                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11887                                + ": not system .apk");
11888                        providers.remove(i);
11889                    }
11890                }
11891            }
11892        }
11893        if (providers != null) {
11894            mSystemThread.installSystemProviders(providers);
11895        }
11896
11897        mConstants.start(mContext.getContentResolver());
11898        mCoreSettingsObserver = new CoreSettingsObserver(this);
11899        mFontScaleSettingObserver = new FontScaleSettingObserver();
11900
11901        // Now that the settings provider is published we can consider sending
11902        // in a rescue party.
11903        RescueParty.onSettingsProviderPublished(mContext);
11904
11905        //mUsageStatsService.monitorPackages();
11906    }
11907
11908    private void startPersistentApps(int matchFlags) {
11909        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11910
11911        synchronized (this) {
11912            try {
11913                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11914                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11915                for (ApplicationInfo app : apps) {
11916                    if (!"android".equals(app.packageName)) {
11917                        addAppLocked(app, null, false, null /* ABI override */);
11918                    }
11919                }
11920            } catch (RemoteException ex) {
11921            }
11922        }
11923    }
11924
11925    /**
11926     * When a user is unlocked, we need to install encryption-unaware providers
11927     * belonging to any running apps.
11928     */
11929    private void installEncryptionUnawareProviders(int userId) {
11930        // We're only interested in providers that are encryption unaware, and
11931        // we don't care about uninstalled apps, since there's no way they're
11932        // running at this point.
11933        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11934
11935        synchronized (this) {
11936            final int NP = mProcessNames.getMap().size();
11937            for (int ip = 0; ip < NP; ip++) {
11938                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11939                final int NA = apps.size();
11940                for (int ia = 0; ia < NA; ia++) {
11941                    final ProcessRecord app = apps.valueAt(ia);
11942                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11943
11944                    final int NG = app.pkgList.size();
11945                    for (int ig = 0; ig < NG; ig++) {
11946                        try {
11947                            final String pkgName = app.pkgList.keyAt(ig);
11948                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11949                                    .getPackageInfo(pkgName, matchFlags, userId);
11950                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11951                                for (ProviderInfo pi : pkgInfo.providers) {
11952                                    // TODO: keep in sync with generateApplicationProvidersLocked
11953                                    final boolean processMatch = Objects.equals(pi.processName,
11954                                            app.processName) || pi.multiprocess;
11955                                    final boolean userMatch = isSingleton(pi.processName,
11956                                            pi.applicationInfo, pi.name, pi.flags)
11957                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11958                                    if (processMatch && userMatch) {
11959                                        Log.v(TAG, "Installing " + pi);
11960                                        app.thread.scheduleInstallProvider(pi);
11961                                    } else {
11962                                        Log.v(TAG, "Skipping " + pi);
11963                                    }
11964                                }
11965                            }
11966                        } catch (RemoteException ignored) {
11967                        }
11968                    }
11969                }
11970            }
11971        }
11972    }
11973
11974    /**
11975     * Allows apps to retrieve the MIME type of a URI.
11976     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11977     * users, then it does not need permission to access the ContentProvider.
11978     * Either, it needs cross-user uri grants.
11979     *
11980     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11981     *
11982     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11983     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11984     */
11985    public String getProviderMimeType(Uri uri, int userId) {
11986        enforceNotIsolatedCaller("getProviderMimeType");
11987        final String name = uri.getAuthority();
11988        int callingUid = Binder.getCallingUid();
11989        int callingPid = Binder.getCallingPid();
11990        long ident = 0;
11991        boolean clearedIdentity = false;
11992        synchronized (this) {
11993            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11994        }
11995        if (canClearIdentity(callingPid, callingUid, userId)) {
11996            clearedIdentity = true;
11997            ident = Binder.clearCallingIdentity();
11998        }
11999        ContentProviderHolder holder = null;
12000        try {
12001            holder = getContentProviderExternalUnchecked(name, null, userId);
12002            if (holder != null) {
12003                return holder.provider.getType(uri);
12004            }
12005        } catch (RemoteException e) {
12006            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12007            return null;
12008        } catch (Exception e) {
12009            Log.w(TAG, "Exception while determining type of " + uri, e);
12010            return null;
12011        } finally {
12012            // We need to clear the identity to call removeContentProviderExternalUnchecked
12013            if (!clearedIdentity) {
12014                ident = Binder.clearCallingIdentity();
12015            }
12016            try {
12017                if (holder != null) {
12018                    removeContentProviderExternalUnchecked(name, null, userId);
12019                }
12020            } finally {
12021                Binder.restoreCallingIdentity(ident);
12022            }
12023        }
12024
12025        return null;
12026    }
12027
12028    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12029        if (UserHandle.getUserId(callingUid) == userId) {
12030            return true;
12031        }
12032        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12033                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12034                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12035                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12036                return true;
12037        }
12038        return false;
12039    }
12040
12041    // =========================================================
12042    // GLOBAL MANAGEMENT
12043    // =========================================================
12044
12045    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12046            boolean isolated, int isolatedUid) {
12047        String proc = customProcess != null ? customProcess : info.processName;
12048        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12049        final int userId = UserHandle.getUserId(info.uid);
12050        int uid = info.uid;
12051        if (isolated) {
12052            if (isolatedUid == 0) {
12053                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12054                while (true) {
12055                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12056                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12057                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12058                    }
12059                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12060                    mNextIsolatedProcessUid++;
12061                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12062                        // No process for this uid, use it.
12063                        break;
12064                    }
12065                    stepsLeft--;
12066                    if (stepsLeft <= 0) {
12067                        return null;
12068                    }
12069                }
12070            } else {
12071                // Special case for startIsolatedProcess (internal only), where
12072                // the uid of the isolated process is specified by the caller.
12073                uid = isolatedUid;
12074            }
12075            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12076
12077            // Register the isolated UID with this application so BatteryStats knows to
12078            // attribute resource usage to the application.
12079            //
12080            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12081            // about the process state of the isolated UID *before* it is registered with the
12082            // owning application.
12083            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12084        }
12085        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12086        if (!mBooted && !mBooting
12087                && userId == UserHandle.USER_SYSTEM
12088                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12089            r.persistent = true;
12090            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12091        }
12092        addProcessNameLocked(r);
12093        return r;
12094    }
12095
12096    private boolean uidOnBackgroundWhitelist(final int uid) {
12097        final int N = mBackgroundUidWhitelist.length;
12098        for (int i = 0; i < N; i++) {
12099            if (uid == mBackgroundUidWhitelist[i]) {
12100                return true;
12101            }
12102        }
12103        return false;
12104    }
12105
12106    @Override
12107    public void backgroundWhitelistUid(final int uid) {
12108        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12109            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12110        }
12111
12112        if (DEBUG_BACKGROUND_CHECK) {
12113            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12114        }
12115        synchronized (this) {
12116            final int N = mBackgroundUidWhitelist.length;
12117            int[] newList = new int[N+1];
12118            System.arraycopy(mBackgroundUidWhitelist, 0, newList, 0, N);
12119            newList[N] = uid;
12120            mBackgroundUidWhitelist = newList;
12121        }
12122    }
12123
12124    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12125            String abiOverride) {
12126        ProcessRecord app;
12127        if (!isolated) {
12128            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12129                    info.uid, true);
12130        } else {
12131            app = null;
12132        }
12133
12134        if (app == null) {
12135            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12136            updateLruProcessLocked(app, false, null);
12137            updateOomAdjLocked();
12138        }
12139
12140        // This package really, really can not be stopped.
12141        try {
12142            AppGlobals.getPackageManager().setPackageStoppedState(
12143                    info.packageName, false, UserHandle.getUserId(app.uid));
12144        } catch (RemoteException e) {
12145        } catch (IllegalArgumentException e) {
12146            Slog.w(TAG, "Failed trying to unstop package "
12147                    + info.packageName + ": " + e);
12148        }
12149
12150        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12151            app.persistent = true;
12152            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12153        }
12154        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12155            mPersistentStartingProcesses.add(app);
12156            startProcessLocked(app, "added application",
12157                    customProcess != null ? customProcess : app.processName, abiOverride,
12158                    null /* entryPoint */, null /* entryPointArgs */);
12159        }
12160
12161        return app;
12162    }
12163
12164    public void unhandledBack() {
12165        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12166                "unhandledBack()");
12167
12168        synchronized(this) {
12169            final long origId = Binder.clearCallingIdentity();
12170            try {
12171                getFocusedStack().unhandledBackLocked();
12172            } finally {
12173                Binder.restoreCallingIdentity(origId);
12174            }
12175        }
12176    }
12177
12178    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12179        enforceNotIsolatedCaller("openContentUri");
12180        final int userId = UserHandle.getCallingUserId();
12181        final Uri uri = Uri.parse(uriString);
12182        String name = uri.getAuthority();
12183        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12184        ParcelFileDescriptor pfd = null;
12185        if (cph != null) {
12186            // We record the binder invoker's uid in thread-local storage before
12187            // going to the content provider to open the file.  Later, in the code
12188            // that handles all permissions checks, we look for this uid and use
12189            // that rather than the Activity Manager's own uid.  The effect is that
12190            // we do the check against the caller's permissions even though it looks
12191            // to the content provider like the Activity Manager itself is making
12192            // the request.
12193            Binder token = new Binder();
12194            sCallerIdentity.set(new Identity(
12195                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12196            try {
12197                pfd = cph.provider.openFile(null, uri, "r", null, token);
12198            } catch (FileNotFoundException e) {
12199                // do nothing; pfd will be returned null
12200            } finally {
12201                // Ensure that whatever happens, we clean up the identity state
12202                sCallerIdentity.remove();
12203                // Ensure we're done with the provider.
12204                removeContentProviderExternalUnchecked(name, null, userId);
12205            }
12206        } else {
12207            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12208        }
12209        return pfd;
12210    }
12211
12212    // Actually is sleeping or shutting down or whatever else in the future
12213    // is an inactive state.
12214    boolean isSleepingOrShuttingDownLocked() {
12215        return isSleepingLocked() || mShuttingDown;
12216    }
12217
12218    boolean isShuttingDownLocked() {
12219        return mShuttingDown;
12220    }
12221
12222    boolean isSleepingLocked() {
12223        return mSleeping;
12224    }
12225
12226    void onWakefulnessChanged(int wakefulness) {
12227        synchronized(this) {
12228            mWakefulness = wakefulness;
12229            updateSleepIfNeededLocked();
12230        }
12231    }
12232
12233    void finishRunningVoiceLocked() {
12234        if (mRunningVoice != null) {
12235            mRunningVoice = null;
12236            mVoiceWakeLock.release();
12237            updateSleepIfNeededLocked();
12238        }
12239    }
12240
12241    void startTimeTrackingFocusedActivityLocked() {
12242        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12243        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12244            mCurAppTimeTracker.start(resumedActivity.packageName);
12245        }
12246    }
12247
12248    void updateSleepIfNeededLocked() {
12249        if (mSleeping && !shouldSleepLocked()) {
12250            mSleeping = false;
12251            startTimeTrackingFocusedActivityLocked();
12252            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12253            mStackSupervisor.comeOutOfSleepIfNeededLocked();
12254            sendNotifyVrManagerOfSleepState(false);
12255            updateOomAdjLocked();
12256        } else if (!mSleeping && shouldSleepLocked()) {
12257            mSleeping = true;
12258            if (mCurAppTimeTracker != null) {
12259                mCurAppTimeTracker.stop();
12260            }
12261            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12262            mStackSupervisor.goingToSleepLocked();
12263            sendNotifyVrManagerOfSleepState(true);
12264            updateOomAdjLocked();
12265
12266            // Initialize the wake times of all processes.
12267            checkExcessivePowerUsageLocked(false);
12268            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12269            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12270            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
12271        }
12272    }
12273
12274    private boolean shouldSleepLocked() {
12275        // Resume applications while running a voice interactor.
12276        if (mRunningVoice != null) {
12277            return false;
12278        }
12279
12280        // TODO: Transform the lock screen state into a sleep token instead.
12281        switch (mWakefulness) {
12282            case PowerManagerInternal.WAKEFULNESS_AWAKE:
12283            case PowerManagerInternal.WAKEFULNESS_DREAMING:
12284            case PowerManagerInternal.WAKEFULNESS_DOZING:
12285                // Pause applications whenever the lock screen is shown or any sleep
12286                // tokens have been acquired.
12287                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12288            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12289            default:
12290                // If we're asleep then pause applications unconditionally.
12291                return true;
12292        }
12293    }
12294
12295    /** Pokes the task persister. */
12296    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12297        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12298    }
12299
12300    /**
12301     * Notifies all listeners when the pinned stack animation starts.
12302     */
12303    @Override
12304    public void notifyPinnedStackAnimationStarted() {
12305        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12306    }
12307
12308    /**
12309     * Notifies all listeners when the pinned stack animation ends.
12310     */
12311    @Override
12312    public void notifyPinnedStackAnimationEnded() {
12313        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12314    }
12315
12316    @Override
12317    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12318        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12319    }
12320
12321    @Override
12322    public boolean shutdown(int timeout) {
12323        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12324                != PackageManager.PERMISSION_GRANTED) {
12325            throw new SecurityException("Requires permission "
12326                    + android.Manifest.permission.SHUTDOWN);
12327        }
12328
12329        boolean timedout = false;
12330
12331        synchronized(this) {
12332            mShuttingDown = true;
12333            updateEventDispatchingLocked();
12334            timedout = mStackSupervisor.shutdownLocked(timeout);
12335        }
12336
12337        mAppOpsService.shutdown();
12338        if (mUsageStatsService != null) {
12339            mUsageStatsService.prepareShutdown();
12340        }
12341        mBatteryStatsService.shutdown();
12342        synchronized (this) {
12343            mProcessStats.shutdownLocked();
12344            notifyTaskPersisterLocked(null, true);
12345        }
12346
12347        return timedout;
12348    }
12349
12350    public final void activitySlept(IBinder token) {
12351        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12352
12353        final long origId = Binder.clearCallingIdentity();
12354
12355        synchronized (this) {
12356            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12357            if (r != null) {
12358                mStackSupervisor.activitySleptLocked(r);
12359            }
12360        }
12361
12362        Binder.restoreCallingIdentity(origId);
12363    }
12364
12365    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12366        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12367        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12368        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12369            boolean wasRunningVoice = mRunningVoice != null;
12370            mRunningVoice = session;
12371            if (!wasRunningVoice) {
12372                mVoiceWakeLock.acquire();
12373                updateSleepIfNeededLocked();
12374            }
12375        }
12376    }
12377
12378    private void updateEventDispatchingLocked() {
12379        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12380    }
12381
12382    @Override
12383    public void setLockScreenShown(boolean showing) {
12384        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12385                != PackageManager.PERMISSION_GRANTED) {
12386            throw new SecurityException("Requires permission "
12387                    + android.Manifest.permission.DEVICE_POWER);
12388        }
12389
12390        synchronized(this) {
12391            long ident = Binder.clearCallingIdentity();
12392            try {
12393                mKeyguardController.setKeyguardShown(showing);
12394            } finally {
12395                Binder.restoreCallingIdentity(ident);
12396            }
12397        }
12398    }
12399
12400    @Override
12401    public void notifyLockedProfile(@UserIdInt int userId) {
12402        try {
12403            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12404                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12405            }
12406        } catch (RemoteException ex) {
12407            throw new SecurityException("Fail to check is caller a privileged app", ex);
12408        }
12409
12410        synchronized (this) {
12411            final long ident = Binder.clearCallingIdentity();
12412            try {
12413                if (mUserController.shouldConfirmCredentials(userId)) {
12414                    if (mKeyguardController.isKeyguardLocked()) {
12415                        // Showing launcher to avoid user entering credential twice.
12416                        final int currentUserId = mUserController.getCurrentUserIdLocked();
12417                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12418                    }
12419                    mStackSupervisor.lockAllProfileTasks(userId);
12420                }
12421            } finally {
12422                Binder.restoreCallingIdentity(ident);
12423            }
12424        }
12425    }
12426
12427    @Override
12428    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12429        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12430        synchronized (this) {
12431            final long ident = Binder.clearCallingIdentity();
12432            try {
12433                mActivityStarter.startConfirmCredentialIntent(intent, options);
12434            } finally {
12435                Binder.restoreCallingIdentity(ident);
12436            }
12437        }
12438    }
12439
12440    @Override
12441    public void stopAppSwitches() {
12442        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12443                != PackageManager.PERMISSION_GRANTED) {
12444            throw new SecurityException("viewquires permission "
12445                    + android.Manifest.permission.STOP_APP_SWITCHES);
12446        }
12447
12448        synchronized(this) {
12449            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12450                    + APP_SWITCH_DELAY_TIME;
12451            mDidAppSwitch = false;
12452            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12453            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12454            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12455        }
12456    }
12457
12458    public void resumeAppSwitches() {
12459        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12460                != PackageManager.PERMISSION_GRANTED) {
12461            throw new SecurityException("Requires permission "
12462                    + android.Manifest.permission.STOP_APP_SWITCHES);
12463        }
12464
12465        synchronized(this) {
12466            // Note that we don't execute any pending app switches... we will
12467            // let those wait until either the timeout, or the next start
12468            // activity request.
12469            mAppSwitchesAllowedTime = 0;
12470        }
12471    }
12472
12473    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12474            int callingPid, int callingUid, String name) {
12475        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12476            return true;
12477        }
12478
12479        int perm = checkComponentPermission(
12480                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12481                sourceUid, -1, true);
12482        if (perm == PackageManager.PERMISSION_GRANTED) {
12483            return true;
12484        }
12485
12486        // If the actual IPC caller is different from the logical source, then
12487        // also see if they are allowed to control app switches.
12488        if (callingUid != -1 && callingUid != sourceUid) {
12489            perm = checkComponentPermission(
12490                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12491                    callingUid, -1, true);
12492            if (perm == PackageManager.PERMISSION_GRANTED) {
12493                return true;
12494            }
12495        }
12496
12497        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12498        return false;
12499    }
12500
12501    public void setDebugApp(String packageName, boolean waitForDebugger,
12502            boolean persistent) {
12503        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12504                "setDebugApp()");
12505
12506        long ident = Binder.clearCallingIdentity();
12507        try {
12508            // Note that this is not really thread safe if there are multiple
12509            // callers into it at the same time, but that's not a situation we
12510            // care about.
12511            if (persistent) {
12512                final ContentResolver resolver = mContext.getContentResolver();
12513                Settings.Global.putString(
12514                    resolver, Settings.Global.DEBUG_APP,
12515                    packageName);
12516                Settings.Global.putInt(
12517                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12518                    waitForDebugger ? 1 : 0);
12519            }
12520
12521            synchronized (this) {
12522                if (!persistent) {
12523                    mOrigDebugApp = mDebugApp;
12524                    mOrigWaitForDebugger = mWaitForDebugger;
12525                }
12526                mDebugApp = packageName;
12527                mWaitForDebugger = waitForDebugger;
12528                mDebugTransient = !persistent;
12529                if (packageName != null) {
12530                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12531                            false, UserHandle.USER_ALL, "set debug app");
12532                }
12533            }
12534        } finally {
12535            Binder.restoreCallingIdentity(ident);
12536        }
12537    }
12538
12539    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12540        synchronized (this) {
12541            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12542            if (!isDebuggable) {
12543                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12544                    throw new SecurityException("Process not debuggable: " + app.packageName);
12545                }
12546            }
12547
12548            mTrackAllocationApp = processName;
12549        }
12550    }
12551
12552    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12553        synchronized (this) {
12554            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12555            if (!isDebuggable) {
12556                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12557                    throw new SecurityException("Process not debuggable: " + app.packageName);
12558                }
12559            }
12560            mProfileApp = processName;
12561            mProfileFile = profilerInfo.profileFile;
12562            if (mProfileFd != null) {
12563                try {
12564                    mProfileFd.close();
12565                } catch (IOException e) {
12566                }
12567                mProfileFd = null;
12568            }
12569            mProfileFd = profilerInfo.profileFd;
12570            mSamplingInterval = profilerInfo.samplingInterval;
12571            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12572            mStreamingOutput = profilerInfo.streamingOutput;
12573            mProfileType = 0;
12574        }
12575    }
12576
12577    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12578        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12579        if (!isDebuggable) {
12580            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12581                throw new SecurityException("Process not debuggable: " + app.packageName);
12582            }
12583        }
12584        mNativeDebuggingApp = processName;
12585    }
12586
12587    @Override
12588    public void setAlwaysFinish(boolean enabled) {
12589        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12590                "setAlwaysFinish()");
12591
12592        long ident = Binder.clearCallingIdentity();
12593        try {
12594            Settings.Global.putInt(
12595                    mContext.getContentResolver(),
12596                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12597
12598            synchronized (this) {
12599                mAlwaysFinishActivities = enabled;
12600            }
12601        } finally {
12602            Binder.restoreCallingIdentity(ident);
12603        }
12604    }
12605
12606    @Override
12607    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12608        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12609                "setActivityController()");
12610        synchronized (this) {
12611            mController = controller;
12612            mControllerIsAMonkey = imAMonkey;
12613            Watchdog.getInstance().setActivityController(controller);
12614        }
12615    }
12616
12617    @Override
12618    public void setUserIsMonkey(boolean userIsMonkey) {
12619        synchronized (this) {
12620            synchronized (mPidsSelfLocked) {
12621                final int callingPid = Binder.getCallingPid();
12622                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12623                if (proc == null) {
12624                    throw new SecurityException("Unknown process: " + callingPid);
12625                }
12626                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12627                    throw new SecurityException("Only an instrumentation process "
12628                            + "with a UiAutomation can call setUserIsMonkey");
12629                }
12630            }
12631            mUserIsMonkey = userIsMonkey;
12632        }
12633    }
12634
12635    @Override
12636    public boolean isUserAMonkey() {
12637        synchronized (this) {
12638            // If there is a controller also implies the user is a monkey.
12639            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12640        }
12641    }
12642
12643    /**
12644     * @deprecated This method is only used by a few internal components and it will soon be
12645     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12646     * No new code should be calling it.
12647     */
12648    @Deprecated
12649    @Override
12650    public void requestBugReport(int bugreportType) {
12651        String extraOptions = null;
12652        switch (bugreportType) {
12653            case ActivityManager.BUGREPORT_OPTION_FULL:
12654                // Default options.
12655                break;
12656            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12657                extraOptions = "bugreportplus";
12658                break;
12659            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12660                extraOptions = "bugreportremote";
12661                break;
12662            case ActivityManager.BUGREPORT_OPTION_WEAR:
12663                extraOptions = "bugreportwear";
12664                break;
12665            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12666                extraOptions = "bugreporttelephony";
12667                break;
12668            default:
12669                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12670                        + bugreportType);
12671        }
12672        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12673        if (extraOptions != null) {
12674            SystemProperties.set("dumpstate.options", extraOptions);
12675        }
12676        SystemProperties.set("ctl.start", "bugreport");
12677    }
12678
12679    /**
12680     * @deprecated This method is only used by a few internal components and it will soon be
12681     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12682     * No new code should be calling it.
12683     */
12684    @Deprecated
12685    @Override
12686    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12687
12688        if (!TextUtils.isEmpty(shareTitle)) {
12689            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12690                String errorStr = "shareTitle should be less than " +
12691                        MAX_BUGREPORT_TITLE_SIZE + " characters";
12692                throw new IllegalArgumentException(errorStr);
12693            } else {
12694                if (!TextUtils.isEmpty(shareDescription)) {
12695                    int length;
12696                    try {
12697                        length = shareDescription.getBytes("UTF-8").length;
12698                    } catch (UnsupportedEncodingException e) {
12699                        String errorStr = "shareDescription: UnsupportedEncodingException";
12700                        throw new IllegalArgumentException(errorStr);
12701                    }
12702                    if (length > SystemProperties.PROP_VALUE_MAX) {
12703                        String errorStr = "shareTitle should be less than " +
12704                                SystemProperties.PROP_VALUE_MAX + " bytes";
12705                        throw new IllegalArgumentException(errorStr);
12706                    } else {
12707                        SystemProperties.set("dumpstate.options.description", shareDescription);
12708                    }
12709                }
12710                SystemProperties.set("dumpstate.options.title", shareTitle);
12711            }
12712        }
12713
12714        Slog.d(TAG, "Bugreport notification title " + shareTitle
12715                + " description " + shareDescription);
12716        requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12717    }
12718
12719    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12720        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12721    }
12722
12723    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12724        if (r != null && (r.instr != null || r.usingWrapper)) {
12725            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12726        }
12727        return KEY_DISPATCHING_TIMEOUT;
12728    }
12729
12730    @Override
12731    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12732        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12733                != PackageManager.PERMISSION_GRANTED) {
12734            throw new SecurityException("Requires permission "
12735                    + android.Manifest.permission.FILTER_EVENTS);
12736        }
12737        ProcessRecord proc;
12738        long timeout;
12739        synchronized (this) {
12740            synchronized (mPidsSelfLocked) {
12741                proc = mPidsSelfLocked.get(pid);
12742            }
12743            timeout = getInputDispatchingTimeoutLocked(proc);
12744        }
12745
12746        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12747            return -1;
12748        }
12749
12750        return timeout;
12751    }
12752
12753    /**
12754     * Handle input dispatching timeouts.
12755     * Returns whether input dispatching should be aborted or not.
12756     */
12757    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12758            final ActivityRecord activity, final ActivityRecord parent,
12759            final boolean aboveSystem, String reason) {
12760        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12761                != PackageManager.PERMISSION_GRANTED) {
12762            throw new SecurityException("Requires permission "
12763                    + android.Manifest.permission.FILTER_EVENTS);
12764        }
12765
12766        final String annotation;
12767        if (reason == null) {
12768            annotation = "Input dispatching timed out";
12769        } else {
12770            annotation = "Input dispatching timed out (" + reason + ")";
12771        }
12772
12773        if (proc != null) {
12774            synchronized (this) {
12775                if (proc.debugging) {
12776                    return false;
12777                }
12778
12779                if (mDidDexOpt) {
12780                    // Give more time since we were dexopting.
12781                    mDidDexOpt = false;
12782                    return false;
12783                }
12784
12785                if (proc.instr != null) {
12786                    Bundle info = new Bundle();
12787                    info.putString("shortMsg", "keyDispatchingTimedOut");
12788                    info.putString("longMsg", annotation);
12789                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12790                    return true;
12791                }
12792            }
12793            mHandler.post(new Runnable() {
12794                @Override
12795                public void run() {
12796                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12797                }
12798            });
12799        }
12800
12801        return true;
12802    }
12803
12804    @Override
12805    public Bundle getAssistContextExtras(int requestType) {
12806        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12807                null, null, true /* focused */, true /* newSessionId */,
12808                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12809        if (pae == null) {
12810            return null;
12811        }
12812        synchronized (pae) {
12813            while (!pae.haveResult) {
12814                try {
12815                    pae.wait();
12816                } catch (InterruptedException e) {
12817                }
12818            }
12819        }
12820        synchronized (this) {
12821            buildAssistBundleLocked(pae, pae.result);
12822            mPendingAssistExtras.remove(pae);
12823            mUiHandler.removeCallbacks(pae);
12824        }
12825        return pae.extras;
12826    }
12827
12828    @Override
12829    public boolean isAssistDataAllowedOnCurrentActivity() {
12830        int userId;
12831        synchronized (this) {
12832            final ActivityStack focusedStack = getFocusedStack();
12833            if (focusedStack == null || focusedStack.isAssistantStack()) {
12834                return false;
12835            }
12836
12837            final ActivityRecord activity = focusedStack.topActivity();
12838            if (activity == null) {
12839                return false;
12840            }
12841            userId = activity.userId;
12842        }
12843        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12844                Context.DEVICE_POLICY_SERVICE);
12845        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12846    }
12847
12848    @Override
12849    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12850        long ident = Binder.clearCallingIdentity();
12851        try {
12852            synchronized (this) {
12853                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12854                ActivityRecord top = getFocusedStack().topActivity();
12855                if (top != caller) {
12856                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12857                            + " is not current top " + top);
12858                    return false;
12859                }
12860                if (!top.nowVisible) {
12861                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12862                            + " is not visible");
12863                    return false;
12864                }
12865            }
12866            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
12867                    token);
12868        } finally {
12869            Binder.restoreCallingIdentity(ident);
12870        }
12871    }
12872
12873    @Override
12874    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12875            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
12876        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12877                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
12878                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
12879    }
12880
12881    @Override
12882    public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
12883            IBinder activityToken) {
12884        // NOTE: we could always use ActivityManager.ASSIST_CONTEXT_FULL and let ActivityThread
12885        // rely on the flags to decide whether the handleRequestAssistContextExtras() is for
12886        // autofill, but it's safer to explicitly use new AutoFill types, in case the Assist
12887        // requests use flags in the future as well (since their flags value might collide with the
12888        // autofill flag values).
12889        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
12890                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
12891                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT) != null;
12892    }
12893
12894    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12895            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12896            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12897        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12898                "enqueueAssistContext()");
12899
12900        synchronized (this) {
12901            ActivityRecord activity = getFocusedStack().topActivity();
12902            if (activity == null) {
12903                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12904                return null;
12905            }
12906            if (activity.app == null || activity.app.thread == null) {
12907                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12908                return null;
12909            }
12910            if (focused) {
12911                if (activityToken != null) {
12912                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12913                    if (activity != caller) {
12914                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12915                                + " is not current top " + activity);
12916                        return null;
12917                    }
12918                }
12919            } else {
12920                activity = ActivityRecord.forTokenLocked(activityToken);
12921                if (activity == null) {
12922                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12923                            + " couldn't be found");
12924                    return null;
12925                }
12926            }
12927
12928            PendingAssistExtras pae;
12929            Bundle extras = new Bundle();
12930            if (args != null) {
12931                extras.putAll(args);
12932            }
12933            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12934            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12935
12936            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12937                    userHandle);
12938            pae.isHome = activity.isHomeActivity();
12939
12940            // Increment the sessionId if necessary
12941            if (newSessionId) {
12942                mViSessionId++;
12943            }
12944            try {
12945                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
12946                        mViSessionId);
12947                mPendingAssistExtras.add(pae);
12948                mUiHandler.postDelayed(pae, timeout);
12949            } catch (RemoteException e) {
12950                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12951                return null;
12952            }
12953            return pae;
12954        }
12955    }
12956
12957    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12958        IResultReceiver receiver;
12959        synchronized (this) {
12960            mPendingAssistExtras.remove(pae);
12961            receiver = pae.receiver;
12962        }
12963        if (receiver != null) {
12964            // Caller wants result sent back to them.
12965            Bundle sendBundle = new Bundle();
12966            // At least return the receiver extras
12967            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12968                    pae.receiverExtras);
12969            try {
12970                pae.receiver.send(0, sendBundle);
12971            } catch (RemoteException e) {
12972            }
12973        }
12974    }
12975
12976    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12977        if (result != null) {
12978            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12979        }
12980        if (pae.hint != null) {
12981            pae.extras.putBoolean(pae.hint, true);
12982        }
12983    }
12984
12985    /** Called from an app when assist data is ready. */
12986    @Override
12987    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12988            AssistContent content, Uri referrer) {
12989        PendingAssistExtras pae = (PendingAssistExtras)token;
12990        synchronized (pae) {
12991            pae.result = extras;
12992            pae.structure = structure;
12993            pae.content = content;
12994            if (referrer != null) {
12995                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12996            }
12997            if (structure != null) {
12998                structure.setHomeActivity(pae.isHome);
12999            }
13000            pae.haveResult = true;
13001            pae.notifyAll();
13002            if (pae.intent == null && pae.receiver == null) {
13003                // Caller is just waiting for the result.
13004                return;
13005            }
13006        }
13007
13008        // We are now ready to launch the assist activity.
13009        IResultReceiver sendReceiver = null;
13010        Bundle sendBundle = null;
13011        synchronized (this) {
13012            buildAssistBundleLocked(pae, extras);
13013            boolean exists = mPendingAssistExtras.remove(pae);
13014            mUiHandler.removeCallbacks(pae);
13015            if (!exists) {
13016                // Timed out.
13017                return;
13018            }
13019            if ((sendReceiver=pae.receiver) != null) {
13020                // Caller wants result sent back to them.
13021                sendBundle = new Bundle();
13022                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13023                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13024                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13025                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13026                        pae.receiverExtras);
13027            }
13028        }
13029        if (sendReceiver != null) {
13030            try {
13031                sendReceiver.send(0, sendBundle);
13032            } catch (RemoteException e) {
13033            }
13034            return;
13035        }
13036
13037        long ident = Binder.clearCallingIdentity();
13038        try {
13039            pae.intent.replaceExtras(pae.extras);
13040            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13041                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
13042                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13043            closeSystemDialogs("assist");
13044            try {
13045                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13046            } catch (ActivityNotFoundException e) {
13047                Slog.w(TAG, "No activity to handle assist action.", e);
13048            }
13049        } finally {
13050            Binder.restoreCallingIdentity(ident);
13051        }
13052    }
13053
13054    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13055            Bundle args) {
13056        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13057                true /* focused */, true /* newSessionId */, userHandle, args,
13058                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
13059    }
13060
13061    public void registerProcessObserver(IProcessObserver observer) {
13062        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13063                "registerProcessObserver()");
13064        synchronized (this) {
13065            mProcessObservers.register(observer);
13066        }
13067    }
13068
13069    @Override
13070    public void unregisterProcessObserver(IProcessObserver observer) {
13071        synchronized (this) {
13072            mProcessObservers.unregister(observer);
13073        }
13074    }
13075
13076    @Override
13077    public int getUidProcessState(int uid, String callingPackage) {
13078        if (!hasUsageStatsPermission(callingPackage)) {
13079            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13080                    "getUidProcessState");
13081        }
13082
13083        synchronized (this) {
13084            UidRecord uidRec = mActiveUids.get(uid);
13085            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13086        }
13087    }
13088
13089    @Override
13090    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13091            String callingPackage) {
13092        if (!hasUsageStatsPermission(callingPackage)) {
13093            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13094                    "registerUidObserver");
13095        }
13096        synchronized (this) {
13097            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13098                    callingPackage, which, cutpoint));
13099        }
13100    }
13101
13102    @Override
13103    public void unregisterUidObserver(IUidObserver observer) {
13104        synchronized (this) {
13105            mUidObservers.unregister(observer);
13106        }
13107    }
13108
13109    @Override
13110    public boolean convertFromTranslucent(IBinder token) {
13111        final long origId = Binder.clearCallingIdentity();
13112        try {
13113            synchronized (this) {
13114                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13115                if (r == null) {
13116                    return false;
13117                }
13118                final boolean translucentChanged = r.changeWindowTranslucency(true);
13119                if (translucentChanged) {
13120                    r.getStack().releaseBackgroundResources(r);
13121                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13122                }
13123                mWindowManager.setAppFullscreen(token, true);
13124                return translucentChanged;
13125            }
13126        } finally {
13127            Binder.restoreCallingIdentity(origId);
13128        }
13129    }
13130
13131    @Override
13132    public boolean convertToTranslucent(IBinder token, Bundle options) {
13133        final long origId = Binder.clearCallingIdentity();
13134        try {
13135            synchronized (this) {
13136                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13137                if (r == null) {
13138                    return false;
13139                }
13140                final TaskRecord task = r.getTask();
13141                int index = task.mActivities.lastIndexOf(r);
13142                if (index > 0) {
13143                    ActivityRecord under = task.mActivities.get(index - 1);
13144                    under.returningOptions = ActivityOptions.fromBundle(options);
13145                }
13146                final boolean translucentChanged = r.changeWindowTranslucency(false);
13147                if (translucentChanged) {
13148                    r.getStack().convertActivityToTranslucent(r);
13149                }
13150                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13151                mWindowManager.setAppFullscreen(token, false);
13152                return translucentChanged;
13153            }
13154        } finally {
13155            Binder.restoreCallingIdentity(origId);
13156        }
13157    }
13158
13159    @Override
13160    public boolean requestVisibleBehind(IBinder token, boolean visible) {
13161        final long origId = Binder.clearCallingIdentity();
13162        try {
13163            synchronized (this) {
13164                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13165                if (r != null) {
13166                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13167                }
13168            }
13169            return false;
13170        } finally {
13171            Binder.restoreCallingIdentity(origId);
13172        }
13173    }
13174
13175    @Override
13176    public boolean isBackgroundVisibleBehind(IBinder token) {
13177        final long origId = Binder.clearCallingIdentity();
13178        try {
13179            synchronized (this) {
13180                final ActivityStack stack = ActivityRecord.getStackLocked(token);
13181                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13182                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13183                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13184                return visible;
13185            }
13186        } finally {
13187            Binder.restoreCallingIdentity(origId);
13188        }
13189    }
13190
13191    @Override
13192    public Bundle getActivityOptions(IBinder token) {
13193        final long origId = Binder.clearCallingIdentity();
13194        try {
13195            synchronized (this) {
13196                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13197                if (r != null) {
13198                    final ActivityOptions activityOptions = r.pendingOptions;
13199                    r.pendingOptions = null;
13200                    return activityOptions == null ? null : activityOptions.toBundle();
13201                }
13202                return null;
13203            }
13204        } finally {
13205            Binder.restoreCallingIdentity(origId);
13206        }
13207    }
13208
13209    @Override
13210    public void setImmersive(IBinder token, boolean immersive) {
13211        synchronized(this) {
13212            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13213            if (r == null) {
13214                throw new IllegalArgumentException();
13215            }
13216            r.immersive = immersive;
13217
13218            // update associated state if we're frontmost
13219            if (r == mStackSupervisor.getResumedActivityLocked()) {
13220                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13221                applyUpdateLockStateLocked(r);
13222            }
13223        }
13224    }
13225
13226    @Override
13227    public boolean isImmersive(IBinder token) {
13228        synchronized (this) {
13229            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13230            if (r == null) {
13231                throw new IllegalArgumentException();
13232            }
13233            return r.immersive;
13234        }
13235    }
13236
13237    @Override
13238    public void setVrThread(int tid) {
13239        enforceSystemHasVrFeature();
13240        synchronized (this) {
13241            synchronized (mPidsSelfLocked) {
13242                final int pid = Binder.getCallingPid();
13243                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13244                mVrController.setVrThreadLocked(tid, pid, proc);
13245            }
13246        }
13247    }
13248
13249    @Override
13250    public void setPersistentVrThread(int tid) {
13251        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13252            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13253                    + Binder.getCallingPid()
13254                    + ", uid=" + Binder.getCallingUid()
13255                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13256            Slog.w(TAG, msg);
13257            throw new SecurityException(msg);
13258        }
13259        enforceSystemHasVrFeature();
13260        synchronized (this) {
13261            synchronized (mPidsSelfLocked) {
13262                final int pid = Binder.getCallingPid();
13263                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13264                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13265            }
13266        }
13267    }
13268
13269    /**
13270     * Schedule the given thread a normal scheduling priority.
13271     *
13272     * @param newTid the tid of the thread to adjust the scheduling of.
13273     * @param suppressLogs {@code true} if any error logging should be disabled.
13274     *
13275     * @return {@code true} if this succeeded.
13276     */
13277    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13278        try {
13279            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13280            return true;
13281        } catch (IllegalArgumentException e) {
13282            if (!suppressLogs) {
13283                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13284            }
13285        }
13286        return false;
13287    }
13288
13289    /**
13290     * Schedule the given thread an FIFO scheduling priority.
13291     *
13292     * @param newTid the tid of the thread to adjust the scheduling of.
13293     * @param suppressLogs {@code true} if any error logging should be disabled.
13294     *
13295     * @return {@code true} if this succeeded.
13296     */
13297    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13298        try {
13299            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13300            return true;
13301        } catch (IllegalArgumentException e) {
13302            if (!suppressLogs) {
13303                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13304            }
13305        }
13306        return false;
13307    }
13308
13309    /**
13310     * Check that we have the features required for VR-related API calls, and throw an exception if
13311     * not.
13312     */
13313    private void enforceSystemHasVrFeature() {
13314        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13315            throw new UnsupportedOperationException("VR mode not supported on this device!");
13316        }
13317    }
13318
13319    @Override
13320    public void setRenderThread(int tid) {
13321        synchronized (this) {
13322            ProcessRecord proc;
13323            synchronized (mPidsSelfLocked) {
13324                int pid = Binder.getCallingPid();
13325                proc = mPidsSelfLocked.get(pid);
13326                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13327                    // ensure the tid belongs to the process
13328                    if (!isThreadInProcess(pid, tid)) {
13329                        throw new IllegalArgumentException(
13330                            "Render thread does not belong to process");
13331                    }
13332                    proc.renderThreadTid = tid;
13333                    if (DEBUG_OOM_ADJ) {
13334                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13335                    }
13336                    // promote to FIFO now
13337                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13338                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13339                        if (mUseFifoUiScheduling) {
13340                            setThreadScheduler(proc.renderThreadTid,
13341                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13342                        } else {
13343                            setThreadPriority(proc.renderThreadTid, -10);
13344                        }
13345                    }
13346                } else {
13347                    if (DEBUG_OOM_ADJ) {
13348                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13349                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13350                               mUseFifoUiScheduling);
13351                    }
13352                }
13353            }
13354        }
13355    }
13356
13357    @Override
13358    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13359        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13360            throw new UnsupportedOperationException("VR mode not supported on this device!");
13361        }
13362
13363        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13364
13365        ActivityRecord r;
13366        synchronized (this) {
13367            r = ActivityRecord.isInStackLocked(token);
13368        }
13369
13370        if (r == null) {
13371            throw new IllegalArgumentException();
13372        }
13373
13374        int err;
13375        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13376                VrManagerInternal.NO_ERROR) {
13377            return err;
13378        }
13379
13380        synchronized(this) {
13381            r.requestedVrComponent = (enabled) ? packageName : null;
13382
13383            // Update associated state if this activity is currently focused
13384            if (r == mStackSupervisor.getResumedActivityLocked()) {
13385                applyUpdateVrModeLocked(r);
13386            }
13387            return 0;
13388        }
13389    }
13390
13391    @Override
13392    public boolean isVrModePackageEnabled(ComponentName packageName) {
13393        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13394            throw new UnsupportedOperationException("VR mode not supported on this device!");
13395        }
13396
13397        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13398
13399        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13400                VrManagerInternal.NO_ERROR;
13401    }
13402
13403    public boolean isTopActivityImmersive() {
13404        enforceNotIsolatedCaller("startActivity");
13405        synchronized (this) {
13406            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13407            return (r != null) ? r.immersive : false;
13408        }
13409    }
13410
13411    /**
13412     * @return whether the system should disable UI modes incompatible with VR mode.
13413     */
13414    boolean shouldDisableNonVrUiLocked() {
13415        return mVrController.shouldDisableNonVrUiLocked();
13416    }
13417
13418    @Override
13419    public boolean isTopOfTask(IBinder token) {
13420        synchronized (this) {
13421            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13422            if (r == null) {
13423                throw new IllegalArgumentException();
13424            }
13425            return r.getTask().getTopActivity() == r;
13426        }
13427    }
13428
13429    @Override
13430    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13431        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13432            String msg = "Permission Denial: setHasTopUi() from pid="
13433                    + Binder.getCallingPid()
13434                    + ", uid=" + Binder.getCallingUid()
13435                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13436            Slog.w(TAG, msg);
13437            throw new SecurityException(msg);
13438        }
13439        final int pid = Binder.getCallingPid();
13440        final long origId = Binder.clearCallingIdentity();
13441        try {
13442            synchronized (this) {
13443                boolean changed = false;
13444                ProcessRecord pr;
13445                synchronized (mPidsSelfLocked) {
13446                    pr = mPidsSelfLocked.get(pid);
13447                    if (pr == null) {
13448                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13449                        return;
13450                    }
13451                    if (pr.hasTopUi != hasTopUi) {
13452                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13453                        pr.hasTopUi = hasTopUi;
13454                        changed = true;
13455                    }
13456                }
13457                if (changed) {
13458                    updateOomAdjLocked(pr);
13459                }
13460            }
13461        } finally {
13462            Binder.restoreCallingIdentity(origId);
13463        }
13464    }
13465
13466    public final void enterSafeMode() {
13467        synchronized(this) {
13468            // It only makes sense to do this before the system is ready
13469            // and started launching other packages.
13470            if (!mSystemReady) {
13471                try {
13472                    AppGlobals.getPackageManager().enterSafeMode();
13473                } catch (RemoteException e) {
13474                }
13475            }
13476
13477            mSafeMode = true;
13478        }
13479    }
13480
13481    public final void showSafeModeOverlay() {
13482        View v = LayoutInflater.from(mContext).inflate(
13483                com.android.internal.R.layout.safe_mode, null);
13484        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13485        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13486        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13487        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13488        lp.gravity = Gravity.BOTTOM | Gravity.START;
13489        lp.format = v.getBackground().getOpacity();
13490        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13491                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13492        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13493        ((WindowManager)mContext.getSystemService(
13494                Context.WINDOW_SERVICE)).addView(v, lp);
13495    }
13496
13497    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13498        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13499            return;
13500        }
13501        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13502        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13503        synchronized (stats) {
13504            if (mBatteryStatsService.isOnBattery()) {
13505                mBatteryStatsService.enforceCallingPermission();
13506                int MY_UID = Binder.getCallingUid();
13507                final int uid;
13508                if (sender == null) {
13509                    uid = sourceUid;
13510                } else {
13511                    uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13512                }
13513                BatteryStatsImpl.Uid.Pkg pkg =
13514                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13515                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13516                pkg.noteWakeupAlarmLocked(tag);
13517            }
13518        }
13519    }
13520
13521    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13522        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13523            return;
13524        }
13525        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13526        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13527        synchronized (stats) {
13528            mBatteryStatsService.enforceCallingPermission();
13529            int MY_UID = Binder.getCallingUid();
13530            final int uid;
13531            if (sender == null) {
13532                uid = sourceUid;
13533            } else {
13534                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13535            }
13536            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13537        }
13538    }
13539
13540    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13541        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13542            return;
13543        }
13544        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13545        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13546        synchronized (stats) {
13547            mBatteryStatsService.enforceCallingPermission();
13548            int MY_UID = Binder.getCallingUid();
13549            final int uid;
13550            if (sender == null) {
13551                uid = sourceUid;
13552            } else {
13553                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13554            }
13555            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13556        }
13557    }
13558
13559    public boolean killPids(int[] pids, String pReason, boolean secure) {
13560        if (Binder.getCallingUid() != SYSTEM_UID) {
13561            throw new SecurityException("killPids only available to the system");
13562        }
13563        String reason = (pReason == null) ? "Unknown" : pReason;
13564        // XXX Note: don't acquire main activity lock here, because the window
13565        // manager calls in with its locks held.
13566
13567        boolean killed = false;
13568        synchronized (mPidsSelfLocked) {
13569            int worstType = 0;
13570            for (int i=0; i<pids.length; i++) {
13571                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13572                if (proc != null) {
13573                    int type = proc.setAdj;
13574                    if (type > worstType) {
13575                        worstType = type;
13576                    }
13577                }
13578            }
13579
13580            // If the worst oom_adj is somewhere in the cached proc LRU range,
13581            // then constrain it so we will kill all cached procs.
13582            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13583                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13584                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13585            }
13586
13587            // If this is not a secure call, don't let it kill processes that
13588            // are important.
13589            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13590                worstType = ProcessList.SERVICE_ADJ;
13591            }
13592
13593            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13594            for (int i=0; i<pids.length; i++) {
13595                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13596                if (proc == null) {
13597                    continue;
13598                }
13599                int adj = proc.setAdj;
13600                if (adj >= worstType && !proc.killedByAm) {
13601                    proc.kill(reason, true);
13602                    killed = true;
13603                }
13604            }
13605        }
13606        return killed;
13607    }
13608
13609    @Override
13610    public void killUid(int appId, int userId, String reason) {
13611        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13612        synchronized (this) {
13613            final long identity = Binder.clearCallingIdentity();
13614            try {
13615                killPackageProcessesLocked(null, appId, userId,
13616                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13617                        reason != null ? reason : "kill uid");
13618            } finally {
13619                Binder.restoreCallingIdentity(identity);
13620            }
13621        }
13622    }
13623
13624    @Override
13625    public boolean killProcessesBelowForeground(String reason) {
13626        if (Binder.getCallingUid() != SYSTEM_UID) {
13627            throw new SecurityException("killProcessesBelowForeground() only available to system");
13628        }
13629
13630        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13631    }
13632
13633    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13634        if (Binder.getCallingUid() != SYSTEM_UID) {
13635            throw new SecurityException("killProcessesBelowAdj() only available to system");
13636        }
13637
13638        boolean killed = false;
13639        synchronized (mPidsSelfLocked) {
13640            final int size = mPidsSelfLocked.size();
13641            for (int i = 0; i < size; i++) {
13642                final int pid = mPidsSelfLocked.keyAt(i);
13643                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13644                if (proc == null) continue;
13645
13646                final int adj = proc.setAdj;
13647                if (adj > belowAdj && !proc.killedByAm) {
13648                    proc.kill(reason, true);
13649                    killed = true;
13650                }
13651            }
13652        }
13653        return killed;
13654    }
13655
13656    @Override
13657    public void hang(final IBinder who, boolean allowRestart) {
13658        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13659                != PackageManager.PERMISSION_GRANTED) {
13660            throw new SecurityException("Requires permission "
13661                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13662        }
13663
13664        final IBinder.DeathRecipient death = new DeathRecipient() {
13665            @Override
13666            public void binderDied() {
13667                synchronized (this) {
13668                    notifyAll();
13669                }
13670            }
13671        };
13672
13673        try {
13674            who.linkToDeath(death, 0);
13675        } catch (RemoteException e) {
13676            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13677            return;
13678        }
13679
13680        synchronized (this) {
13681            Watchdog.getInstance().setAllowRestart(allowRestart);
13682            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13683            synchronized (death) {
13684                while (who.isBinderAlive()) {
13685                    try {
13686                        death.wait();
13687                    } catch (InterruptedException e) {
13688                    }
13689                }
13690            }
13691            Watchdog.getInstance().setAllowRestart(true);
13692        }
13693    }
13694
13695    @Override
13696    public void restart() {
13697        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13698                != PackageManager.PERMISSION_GRANTED) {
13699            throw new SecurityException("Requires permission "
13700                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13701        }
13702
13703        Log.i(TAG, "Sending shutdown broadcast...");
13704
13705        BroadcastReceiver br = new BroadcastReceiver() {
13706            @Override public void onReceive(Context context, Intent intent) {
13707                // Now the broadcast is done, finish up the low-level shutdown.
13708                Log.i(TAG, "Shutting down activity manager...");
13709                shutdown(10000);
13710                Log.i(TAG, "Shutdown complete, restarting!");
13711                killProcess(myPid());
13712                System.exit(10);
13713            }
13714        };
13715
13716        // First send the high-level shut down broadcast.
13717        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13718        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13719        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13720        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13721        mContext.sendOrderedBroadcastAsUser(intent,
13722                UserHandle.ALL, null, br, mHandler, 0, null, null);
13723        */
13724        br.onReceive(mContext, intent);
13725    }
13726
13727    private long getLowRamTimeSinceIdle(long now) {
13728        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13729    }
13730
13731    @Override
13732    public void performIdleMaintenance() {
13733        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13734                != PackageManager.PERMISSION_GRANTED) {
13735            throw new SecurityException("Requires permission "
13736                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13737        }
13738
13739        synchronized (this) {
13740            final long now = SystemClock.uptimeMillis();
13741            final long timeSinceLastIdle = now - mLastIdleTime;
13742            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13743            mLastIdleTime = now;
13744            mLowRamTimeSinceLastIdle = 0;
13745            if (mLowRamStartTime != 0) {
13746                mLowRamStartTime = now;
13747            }
13748
13749            StringBuilder sb = new StringBuilder(128);
13750            sb.append("Idle maintenance over ");
13751            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13752            sb.append(" low RAM for ");
13753            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13754            Slog.i(TAG, sb.toString());
13755
13756            // If at least 1/3 of our time since the last idle period has been spent
13757            // with RAM low, then we want to kill processes.
13758            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13759
13760            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13761                ProcessRecord proc = mLruProcesses.get(i);
13762                if (proc.notCachedSinceIdle) {
13763                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13764                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13765                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13766                        if (doKilling && proc.initialIdlePss != 0
13767                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13768                            sb = new StringBuilder(128);
13769                            sb.append("Kill");
13770                            sb.append(proc.processName);
13771                            sb.append(" in idle maint: pss=");
13772                            sb.append(proc.lastPss);
13773                            sb.append(", swapPss=");
13774                            sb.append(proc.lastSwapPss);
13775                            sb.append(", initialPss=");
13776                            sb.append(proc.initialIdlePss);
13777                            sb.append(", period=");
13778                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13779                            sb.append(", lowRamPeriod=");
13780                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13781                            Slog.wtfQuiet(TAG, sb.toString());
13782                            proc.kill("idle maint (pss " + proc.lastPss
13783                                    + " from " + proc.initialIdlePss + ")", true);
13784                        }
13785                    }
13786                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13787                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13788                    proc.notCachedSinceIdle = true;
13789                    proc.initialIdlePss = 0;
13790                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13791                            mTestPssMode, isSleepingLocked(), now);
13792                }
13793            }
13794
13795            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13796            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13797        }
13798    }
13799
13800    @Override
13801    public void sendIdleJobTrigger() {
13802        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13803                != PackageManager.PERMISSION_GRANTED) {
13804            throw new SecurityException("Requires permission "
13805                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13806        }
13807
13808        final long ident = Binder.clearCallingIdentity();
13809        try {
13810            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13811                    .setPackage("android")
13812                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13813            broadcastIntent(null, intent, null, null, 0, null, null, null,
13814                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13815        } finally {
13816            Binder.restoreCallingIdentity(ident);
13817        }
13818    }
13819
13820    private void retrieveSettings() {
13821        final ContentResolver resolver = mContext.getContentResolver();
13822        final boolean freeformWindowManagement =
13823                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13824                        || Settings.Global.getInt(
13825                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13826        final boolean supportsPictureInPicture =
13827                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13828
13829        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13830        final boolean supportsSplitScreenMultiWindow =
13831                ActivityManager.supportsSplitScreenMultiWindow();
13832        final boolean supportsMultiDisplay = mContext.getPackageManager()
13833                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
13834        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13835        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13836        final boolean alwaysFinishActivities =
13837                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13838        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13839        final boolean forceResizable = Settings.Global.getInt(
13840                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13841        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
13842                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
13843        final boolean supportsLeanbackOnly =
13844                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13845
13846        // Transfer any global setting for forcing RTL layout, into a System Property
13847        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13848
13849        final Configuration configuration = new Configuration();
13850        Settings.System.getConfiguration(resolver, configuration);
13851        if (forceRtl) {
13852            // This will take care of setting the correct layout direction flags
13853            configuration.setLayoutDirection(configuration.locale);
13854        }
13855
13856        synchronized (this) {
13857            mDebugApp = mOrigDebugApp = debugApp;
13858            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13859            mAlwaysFinishActivities = alwaysFinishActivities;
13860            mSupportsLeanbackOnly = supportsLeanbackOnly;
13861            mForceResizableActivities = forceResizable;
13862            if (supportsMultiWindow || forceResizable) {
13863                mSupportsMultiWindow = true;
13864                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13865            } else {
13866                mSupportsMultiWindow = false;
13867                mSupportsFreeformWindowManagement = false;
13868            }
13869            mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13870            mSupportsPictureInPicture = supportsPictureInPicture;
13871            mSupportsMultiDisplay = supportsMultiDisplay;
13872            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13873            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13874            // This happens before any activities are started, so we can change global configuration
13875            // in-place.
13876            updateConfigurationLocked(configuration, null, true);
13877            final Configuration globalConfig = getGlobalConfiguration();
13878            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13879
13880            // Load resources only after the current configuration has been set.
13881            final Resources res = mContext.getResources();
13882            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13883            mThumbnailWidth = res.getDimensionPixelSize(
13884                    com.android.internal.R.dimen.thumbnail_width);
13885            mThumbnailHeight = res.getDimensionPixelSize(
13886                    com.android.internal.R.dimen.thumbnail_height);
13887            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13888                    com.android.internal.R.string.config_appsNotReportingCrashes));
13889            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13890                    com.android.internal.R.bool.config_customUserSwitchUi);
13891            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13892                mFullscreenThumbnailScale = (float) res
13893                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13894                    (float) globalConfig.screenWidthDp;
13895            } else {
13896                mFullscreenThumbnailScale = res.getFraction(
13897                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13898            }
13899            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
13900        }
13901    }
13902
13903    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
13904        traceLog.traceBegin("PhaseActivityManagerReady");
13905        synchronized(this) {
13906            if (mSystemReady) {
13907                // If we're done calling all the receivers, run the next "boot phase" passed in
13908                // by the SystemServer
13909                if (goingCallback != null) {
13910                    goingCallback.run();
13911                }
13912                return;
13913            }
13914
13915            mLocalDeviceIdleController
13916                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13917            mAssistUtils = new AssistUtils(mContext);
13918            mVrController.onSystemReady();
13919            // Make sure we have the current profile info, since it is needed for security checks.
13920            mUserController.onSystemReady();
13921            mRecentTasks.onSystemReadyLocked();
13922            mAppOpsService.systemReady();
13923            mSystemReady = true;
13924        }
13925
13926        ArrayList<ProcessRecord> procsToKill = null;
13927        synchronized(mPidsSelfLocked) {
13928            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13929                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13930                if (!isAllowedWhileBooting(proc.info)){
13931                    if (procsToKill == null) {
13932                        procsToKill = new ArrayList<ProcessRecord>();
13933                    }
13934                    procsToKill.add(proc);
13935                }
13936            }
13937        }
13938
13939        synchronized(this) {
13940            if (procsToKill != null) {
13941                for (int i=procsToKill.size()-1; i>=0; i--) {
13942                    ProcessRecord proc = procsToKill.get(i);
13943                    Slog.i(TAG, "Removing system update proc: " + proc);
13944                    removeProcessLocked(proc, true, false, "system update done");
13945                }
13946            }
13947
13948            // Now that we have cleaned up any update processes, we
13949            // are ready to start launching real processes and know that
13950            // we won't trample on them any more.
13951            mProcessesReady = true;
13952        }
13953
13954        Slog.i(TAG, "System now ready");
13955        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13956            SystemClock.uptimeMillis());
13957
13958        synchronized(this) {
13959            // Make sure we have no pre-ready processes sitting around.
13960
13961            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13962                ResolveInfo ri = mContext.getPackageManager()
13963                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13964                                STOCK_PM_FLAGS);
13965                CharSequence errorMsg = null;
13966                if (ri != null) {
13967                    ActivityInfo ai = ri.activityInfo;
13968                    ApplicationInfo app = ai.applicationInfo;
13969                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13970                        mTopAction = Intent.ACTION_FACTORY_TEST;
13971                        mTopData = null;
13972                        mTopComponent = new ComponentName(app.packageName,
13973                                ai.name);
13974                    } else {
13975                        errorMsg = mContext.getResources().getText(
13976                                com.android.internal.R.string.factorytest_not_system);
13977                    }
13978                } else {
13979                    errorMsg = mContext.getResources().getText(
13980                            com.android.internal.R.string.factorytest_no_action);
13981                }
13982                if (errorMsg != null) {
13983                    mTopAction = null;
13984                    mTopData = null;
13985                    mTopComponent = null;
13986                    Message msg = Message.obtain();
13987                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13988                    msg.getData().putCharSequence("msg", errorMsg);
13989                    mUiHandler.sendMessage(msg);
13990                }
13991            }
13992        }
13993
13994        retrieveSettings();
13995        final int currentUserId;
13996        synchronized (this) {
13997            currentUserId = mUserController.getCurrentUserIdLocked();
13998            readGrantedUriPermissionsLocked();
13999        }
14000
14001        if (goingCallback != null) goingCallback.run();
14002        traceLog.traceBegin("ActivityManagerStartApps");
14003        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14004                Integer.toString(currentUserId), currentUserId);
14005        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14006                Integer.toString(currentUserId), currentUserId);
14007        mSystemServiceManager.startUser(currentUserId);
14008
14009        synchronized (this) {
14010            // Only start up encryption-aware persistent apps; once user is
14011            // unlocked we'll come back around and start unaware apps
14012            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14013
14014            // Start up initial activity.
14015            mBooting = true;
14016            // Enable home activity for system user, so that the system can always boot. We don't
14017            // do this when the system user is not setup since the setup wizard should be the one
14018            // to handle home activity in this case.
14019            if (UserManager.isSplitSystemUser() &&
14020                    Settings.Secure.getInt(mContext.getContentResolver(),
14021                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14022                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14023                try {
14024                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14025                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14026                            UserHandle.USER_SYSTEM);
14027                } catch (RemoteException e) {
14028                    throw e.rethrowAsRuntimeException();
14029                }
14030            }
14031            startHomeActivityLocked(currentUserId, "systemReady");
14032
14033            try {
14034                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14035                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14036                            + " data partition or your device will be unstable.");
14037                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14038                }
14039            } catch (RemoteException e) {
14040            }
14041
14042            if (!Build.isBuildConsistent()) {
14043                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14044                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14045            }
14046
14047            long ident = Binder.clearCallingIdentity();
14048            try {
14049                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14050                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14051                        | Intent.FLAG_RECEIVER_FOREGROUND);
14052                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14053                broadcastIntentLocked(null, null, intent,
14054                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14055                        null, false, false, MY_PID, SYSTEM_UID,
14056                        currentUserId);
14057                intent = new Intent(Intent.ACTION_USER_STARTING);
14058                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14059                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14060                broadcastIntentLocked(null, null, intent,
14061                        null, new IIntentReceiver.Stub() {
14062                            @Override
14063                            public void performReceive(Intent intent, int resultCode, String data,
14064                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14065                                    throws RemoteException {
14066                            }
14067                        }, 0, null, null,
14068                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14069                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14070            } catch (Throwable t) {
14071                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14072            } finally {
14073                Binder.restoreCallingIdentity(ident);
14074            }
14075            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14076            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14077            traceLog.traceEnd(); // ActivityManagerStartApps
14078            traceLog.traceEnd(); // PhaseActivityManagerReady
14079        }
14080    }
14081
14082    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14083        synchronized (this) {
14084            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14085        }
14086    }
14087
14088    void skipCurrentReceiverLocked(ProcessRecord app) {
14089        for (BroadcastQueue queue : mBroadcastQueues) {
14090            queue.skipCurrentReceiverLocked(app);
14091        }
14092    }
14093
14094    /**
14095     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14096     * The application process will exit immediately after this call returns.
14097     * @param app object of the crashing app, null for the system server
14098     * @param crashInfo describing the exception
14099     */
14100    public void handleApplicationCrash(IBinder app,
14101            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14102        ProcessRecord r = findAppProcess(app, "Crash");
14103        final String processName = app == null ? "system_server"
14104                : (r == null ? "unknown" : r.processName);
14105
14106        handleApplicationCrashInner("crash", r, processName, crashInfo);
14107    }
14108
14109    /* Native crash reporting uses this inner version because it needs to be somewhat
14110     * decoupled from the AM-managed cleanup lifecycle
14111     */
14112    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14113            ApplicationErrorReport.CrashInfo crashInfo) {
14114        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14115                UserHandle.getUserId(Binder.getCallingUid()), processName,
14116                r == null ? -1 : r.info.flags,
14117                crashInfo.exceptionClassName,
14118                crashInfo.exceptionMessage,
14119                crashInfo.throwFileName,
14120                crashInfo.throwLineNumber);
14121
14122        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14123
14124        mAppErrors.crashApplication(r, crashInfo);
14125    }
14126
14127    public void handleApplicationStrictModeViolation(
14128            IBinder app,
14129            int violationMask,
14130            StrictMode.ViolationInfo info) {
14131        ProcessRecord r = findAppProcess(app, "StrictMode");
14132        if (r == null) {
14133            return;
14134        }
14135
14136        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14137            Integer stackFingerprint = info.hashCode();
14138            boolean logIt = true;
14139            synchronized (mAlreadyLoggedViolatedStacks) {
14140                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14141                    logIt = false;
14142                    // TODO: sub-sample into EventLog for these, with
14143                    // the info.durationMillis?  Then we'd get
14144                    // the relative pain numbers, without logging all
14145                    // the stack traces repeatedly.  We'd want to do
14146                    // likewise in the client code, which also does
14147                    // dup suppression, before the Binder call.
14148                } else {
14149                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14150                        mAlreadyLoggedViolatedStacks.clear();
14151                    }
14152                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14153                }
14154            }
14155            if (logIt) {
14156                logStrictModeViolationToDropBox(r, info);
14157            }
14158        }
14159
14160        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14161            AppErrorResult result = new AppErrorResult();
14162            synchronized (this) {
14163                final long origId = Binder.clearCallingIdentity();
14164
14165                Message msg = Message.obtain();
14166                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14167                HashMap<String, Object> data = new HashMap<String, Object>();
14168                data.put("result", result);
14169                data.put("app", r);
14170                data.put("violationMask", violationMask);
14171                data.put("info", info);
14172                msg.obj = data;
14173                mUiHandler.sendMessage(msg);
14174
14175                Binder.restoreCallingIdentity(origId);
14176            }
14177            int res = result.get();
14178            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14179        }
14180    }
14181
14182    // Depending on the policy in effect, there could be a bunch of
14183    // these in quick succession so we try to batch these together to
14184    // minimize disk writes, number of dropbox entries, and maximize
14185    // compression, by having more fewer, larger records.
14186    private void logStrictModeViolationToDropBox(
14187            ProcessRecord process,
14188            StrictMode.ViolationInfo info) {
14189        if (info == null) {
14190            return;
14191        }
14192        final boolean isSystemApp = process == null ||
14193                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14194                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14195        final String processName = process == null ? "unknown" : process.processName;
14196        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14197        final DropBoxManager dbox = (DropBoxManager)
14198                mContext.getSystemService(Context.DROPBOX_SERVICE);
14199
14200        // Exit early if the dropbox isn't configured to accept this report type.
14201        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14202
14203        boolean bufferWasEmpty;
14204        boolean needsFlush;
14205        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14206        synchronized (sb) {
14207            bufferWasEmpty = sb.length() == 0;
14208            appendDropBoxProcessHeaders(process, processName, sb);
14209            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14210            sb.append("System-App: ").append(isSystemApp).append("\n");
14211            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14212            if (info.violationNumThisLoop != 0) {
14213                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14214            }
14215            if (info.numAnimationsRunning != 0) {
14216                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14217            }
14218            if (info.broadcastIntentAction != null) {
14219                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14220            }
14221            if (info.durationMillis != -1) {
14222                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14223            }
14224            if (info.numInstances != -1) {
14225                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14226            }
14227            if (info.tags != null) {
14228                for (String tag : info.tags) {
14229                    sb.append("Span-Tag: ").append(tag).append("\n");
14230                }
14231            }
14232            sb.append("\n");
14233            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14234                sb.append(info.crashInfo.stackTrace);
14235                sb.append("\n");
14236            }
14237            if (info.message != null) {
14238                sb.append(info.message);
14239                sb.append("\n");
14240            }
14241
14242            // Only buffer up to ~64k.  Various logging bits truncate
14243            // things at 128k.
14244            needsFlush = (sb.length() > 64 * 1024);
14245        }
14246
14247        // Flush immediately if the buffer's grown too large, or this
14248        // is a non-system app.  Non-system apps are isolated with a
14249        // different tag & policy and not batched.
14250        //
14251        // Batching is useful during internal testing with
14252        // StrictMode settings turned up high.  Without batching,
14253        // thousands of separate files could be created on boot.
14254        if (!isSystemApp || needsFlush) {
14255            new Thread("Error dump: " + dropboxTag) {
14256                @Override
14257                public void run() {
14258                    String report;
14259                    synchronized (sb) {
14260                        report = sb.toString();
14261                        sb.delete(0, sb.length());
14262                        sb.trimToSize();
14263                    }
14264                    if (report.length() != 0) {
14265                        dbox.addText(dropboxTag, report);
14266                    }
14267                }
14268            }.start();
14269            return;
14270        }
14271
14272        // System app batching:
14273        if (!bufferWasEmpty) {
14274            // An existing dropbox-writing thread is outstanding, so
14275            // we don't need to start it up.  The existing thread will
14276            // catch the buffer appends we just did.
14277            return;
14278        }
14279
14280        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14281        // (After this point, we shouldn't access AMS internal data structures.)
14282        new Thread("Error dump: " + dropboxTag) {
14283            @Override
14284            public void run() {
14285                // 5 second sleep to let stacks arrive and be batched together
14286                try {
14287                    Thread.sleep(5000);  // 5 seconds
14288                } catch (InterruptedException e) {}
14289
14290                String errorReport;
14291                synchronized (mStrictModeBuffer) {
14292                    errorReport = mStrictModeBuffer.toString();
14293                    if (errorReport.length() == 0) {
14294                        return;
14295                    }
14296                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14297                    mStrictModeBuffer.trimToSize();
14298                }
14299                dbox.addText(dropboxTag, errorReport);
14300            }
14301        }.start();
14302    }
14303
14304    /**
14305     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14306     * @param app object of the crashing app, null for the system server
14307     * @param tag reported by the caller
14308     * @param system whether this wtf is coming from the system
14309     * @param crashInfo describing the context of the error
14310     * @return true if the process should exit immediately (WTF is fatal)
14311     */
14312    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14313            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14314        final int callingUid = Binder.getCallingUid();
14315        final int callingPid = Binder.getCallingPid();
14316
14317        if (system) {
14318            // If this is coming from the system, we could very well have low-level
14319            // system locks held, so we want to do this all asynchronously.  And we
14320            // never want this to become fatal, so there is that too.
14321            mHandler.post(new Runnable() {
14322                @Override public void run() {
14323                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14324                }
14325            });
14326            return false;
14327        }
14328
14329        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14330                crashInfo);
14331
14332        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14333                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14334        final boolean isSystem = (r == null) || r.persistent;
14335
14336        if (isFatal && !isSystem) {
14337            mAppErrors.crashApplication(r, crashInfo);
14338            return true;
14339        } else {
14340            return false;
14341        }
14342    }
14343
14344    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14345            final ApplicationErrorReport.CrashInfo crashInfo) {
14346        final ProcessRecord r = findAppProcess(app, "WTF");
14347        final String processName = app == null ? "system_server"
14348                : (r == null ? "unknown" : r.processName);
14349
14350        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14351                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14352
14353        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14354
14355        return r;
14356    }
14357
14358    /**
14359     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14360     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14361     */
14362    private ProcessRecord findAppProcess(IBinder app, String reason) {
14363        if (app == null) {
14364            return null;
14365        }
14366
14367        synchronized (this) {
14368            final int NP = mProcessNames.getMap().size();
14369            for (int ip=0; ip<NP; ip++) {
14370                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14371                final int NA = apps.size();
14372                for (int ia=0; ia<NA; ia++) {
14373                    ProcessRecord p = apps.valueAt(ia);
14374                    if (p.thread != null && p.thread.asBinder() == app) {
14375                        return p;
14376                    }
14377                }
14378            }
14379
14380            Slog.w(TAG, "Can't find mystery application for " + reason
14381                    + " from pid=" + Binder.getCallingPid()
14382                    + " uid=" + Binder.getCallingUid() + ": " + app);
14383            return null;
14384        }
14385    }
14386
14387    /**
14388     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14389     * to append various headers to the dropbox log text.
14390     */
14391    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14392            StringBuilder sb) {
14393        // Watchdog thread ends up invoking this function (with
14394        // a null ProcessRecord) to add the stack file to dropbox.
14395        // Do not acquire a lock on this (am) in such cases, as it
14396        // could cause a potential deadlock, if and when watchdog
14397        // is invoked due to unavailability of lock on am and it
14398        // would prevent watchdog from killing system_server.
14399        if (process == null) {
14400            sb.append("Process: ").append(processName).append("\n");
14401            return;
14402        }
14403        // Note: ProcessRecord 'process' is guarded by the service
14404        // instance.  (notably process.pkgList, which could otherwise change
14405        // concurrently during execution of this method)
14406        synchronized (this) {
14407            sb.append("Process: ").append(processName).append("\n");
14408            int flags = process.info.flags;
14409            IPackageManager pm = AppGlobals.getPackageManager();
14410            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14411            for (int ip=0; ip<process.pkgList.size(); ip++) {
14412                String pkg = process.pkgList.keyAt(ip);
14413                sb.append("Package: ").append(pkg);
14414                try {
14415                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14416                    if (pi != null) {
14417                        sb.append(" v").append(pi.versionCode);
14418                        if (pi.versionName != null) {
14419                            sb.append(" (").append(pi.versionName).append(")");
14420                        }
14421                    }
14422                } catch (RemoteException e) {
14423                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14424                }
14425                sb.append("\n");
14426            }
14427        }
14428    }
14429
14430    private static String processClass(ProcessRecord process) {
14431        if (process == null || process.pid == MY_PID) {
14432            return "system_server";
14433        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14434            return "system_app";
14435        } else {
14436            return "data_app";
14437        }
14438    }
14439
14440    private volatile long mWtfClusterStart;
14441    private volatile int mWtfClusterCount;
14442
14443    /**
14444     * Write a description of an error (crash, WTF, ANR) to the drop box.
14445     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14446     * @param process which caused the error, null means the system server
14447     * @param activity which triggered the error, null if unknown
14448     * @param parent activity related to the error, null if unknown
14449     * @param subject line related to the error, null if absent
14450     * @param report in long form describing the error, null if absent
14451     * @param dataFile text file to include in the report, null if none
14452     * @param crashInfo giving an application stack trace, null if absent
14453     */
14454    public void addErrorToDropBox(String eventType,
14455            ProcessRecord process, String processName, ActivityRecord activity,
14456            ActivityRecord parent, String subject,
14457            final String report, final File dataFile,
14458            final ApplicationErrorReport.CrashInfo crashInfo) {
14459        // NOTE -- this must never acquire the ActivityManagerService lock,
14460        // otherwise the watchdog may be prevented from resetting the system.
14461
14462        // Bail early if not published yet
14463        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14464        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14465
14466        // Exit early if the dropbox isn't configured to accept this report type.
14467        final String dropboxTag = processClass(process) + "_" + eventType;
14468        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14469
14470        // Rate-limit how often we're willing to do the heavy lifting below to
14471        // collect and record logs; currently 5 logs per 10 second period.
14472        final long now = SystemClock.elapsedRealtime();
14473        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14474            mWtfClusterStart = now;
14475            mWtfClusterCount = 1;
14476        } else {
14477            if (mWtfClusterCount++ >= 5) return;
14478        }
14479
14480        final StringBuilder sb = new StringBuilder(1024);
14481        appendDropBoxProcessHeaders(process, processName, sb);
14482        if (process != null) {
14483            sb.append("Foreground: ")
14484                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14485                    .append("\n");
14486        }
14487        if (activity != null) {
14488            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14489        }
14490        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14491            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14492        }
14493        if (parent != null && parent != activity) {
14494            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14495        }
14496        if (subject != null) {
14497            sb.append("Subject: ").append(subject).append("\n");
14498        }
14499        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14500        if (Debug.isDebuggerConnected()) {
14501            sb.append("Debugger: Connected\n");
14502        }
14503        sb.append("\n");
14504
14505        // Do the rest in a worker thread to avoid blocking the caller on I/O
14506        // (After this point, we shouldn't access AMS internal data structures.)
14507        Thread worker = new Thread("Error dump: " + dropboxTag) {
14508            @Override
14509            public void run() {
14510                if (report != null) {
14511                    sb.append(report);
14512                }
14513
14514                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14515                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14516                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14517                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14518
14519                if (dataFile != null && maxDataFileSize > 0) {
14520                    try {
14521                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14522                                    "\n\n[[TRUNCATED]]"));
14523                    } catch (IOException e) {
14524                        Slog.e(TAG, "Error reading " + dataFile, e);
14525                    }
14526                }
14527                if (crashInfo != null && crashInfo.stackTrace != null) {
14528                    sb.append(crashInfo.stackTrace);
14529                }
14530
14531                if (lines > 0) {
14532                    sb.append("\n");
14533
14534                    // Merge several logcat streams, and take the last N lines
14535                    InputStreamReader input = null;
14536                    try {
14537                        java.lang.Process logcat = new ProcessBuilder(
14538                                "/system/bin/timeout", "-k", "15s", "10s",
14539                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14540                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14541                                        .redirectErrorStream(true).start();
14542
14543                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14544                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14545                        input = new InputStreamReader(logcat.getInputStream());
14546
14547                        int num;
14548                        char[] buf = new char[8192];
14549                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14550                    } catch (IOException e) {
14551                        Slog.e(TAG, "Error running logcat", e);
14552                    } finally {
14553                        if (input != null) try { input.close(); } catch (IOException e) {}
14554                    }
14555                }
14556
14557                dbox.addText(dropboxTag, sb.toString());
14558            }
14559        };
14560
14561        if (process == null) {
14562            // If process is null, we are being called from some internal code
14563            // and may be about to die -- run this synchronously.
14564            worker.run();
14565        } else {
14566            worker.start();
14567        }
14568    }
14569
14570    @Override
14571    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14572        enforceNotIsolatedCaller("getProcessesInErrorState");
14573        // assume our apps are happy - lazy create the list
14574        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14575
14576        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14577                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14578        int userId = UserHandle.getUserId(Binder.getCallingUid());
14579
14580        synchronized (this) {
14581
14582            // iterate across all processes
14583            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14584                ProcessRecord app = mLruProcesses.get(i);
14585                if (!allUsers && app.userId != userId) {
14586                    continue;
14587                }
14588                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14589                    // This one's in trouble, so we'll generate a report for it
14590                    // crashes are higher priority (in case there's a crash *and* an anr)
14591                    ActivityManager.ProcessErrorStateInfo report = null;
14592                    if (app.crashing) {
14593                        report = app.crashingReport;
14594                    } else if (app.notResponding) {
14595                        report = app.notRespondingReport;
14596                    }
14597
14598                    if (report != null) {
14599                        if (errList == null) {
14600                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14601                        }
14602                        errList.add(report);
14603                    } else {
14604                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14605                                " crashing = " + app.crashing +
14606                                " notResponding = " + app.notResponding);
14607                    }
14608                }
14609            }
14610        }
14611
14612        return errList;
14613    }
14614
14615    static int procStateToImportance(int procState, int memAdj,
14616            ActivityManager.RunningAppProcessInfo currApp) {
14617        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
14618        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14619            currApp.lru = memAdj;
14620        } else {
14621            currApp.lru = 0;
14622        }
14623        return imp;
14624    }
14625
14626    private void fillInProcMemInfo(ProcessRecord app,
14627            ActivityManager.RunningAppProcessInfo outInfo) {
14628        outInfo.pid = app.pid;
14629        outInfo.uid = app.info.uid;
14630        if (mHeavyWeightProcess == app) {
14631            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14632        }
14633        if (app.persistent) {
14634            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14635        }
14636        if (app.activities.size() > 0) {
14637            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14638        }
14639        outInfo.lastTrimLevel = app.trimMemoryLevel;
14640        int adj = app.curAdj;
14641        int procState = app.curProcState;
14642        outInfo.importance = procStateToImportance(procState, adj, outInfo);
14643        outInfo.importanceReasonCode = app.adjTypeCode;
14644        outInfo.processState = app.curProcState;
14645    }
14646
14647    @Override
14648    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14649        enforceNotIsolatedCaller("getRunningAppProcesses");
14650
14651        final int callingUid = Binder.getCallingUid();
14652
14653        // Lazy instantiation of list
14654        List<ActivityManager.RunningAppProcessInfo> runList = null;
14655        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14656                callingUid) == PackageManager.PERMISSION_GRANTED;
14657        final int userId = UserHandle.getUserId(callingUid);
14658        final boolean allUids = isGetTasksAllowed(
14659                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14660
14661        synchronized (this) {
14662            // Iterate across all processes
14663            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14664                ProcessRecord app = mLruProcesses.get(i);
14665                if ((!allUsers && app.userId != userId)
14666                        || (!allUids && app.uid != callingUid)) {
14667                    continue;
14668                }
14669                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14670                    // Generate process state info for running application
14671                    ActivityManager.RunningAppProcessInfo currApp =
14672                        new ActivityManager.RunningAppProcessInfo(app.processName,
14673                                app.pid, app.getPackageList());
14674                    fillInProcMemInfo(app, currApp);
14675                    if (app.adjSource instanceof ProcessRecord) {
14676                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14677                        currApp.importanceReasonImportance =
14678                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14679                                        app.adjSourceProcState);
14680                    } else if (app.adjSource instanceof ActivityRecord) {
14681                        ActivityRecord r = (ActivityRecord)app.adjSource;
14682                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14683                    }
14684                    if (app.adjTarget instanceof ComponentName) {
14685                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14686                    }
14687                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14688                    //        + " lru=" + currApp.lru);
14689                    if (runList == null) {
14690                        runList = new ArrayList<>();
14691                    }
14692                    runList.add(currApp);
14693                }
14694            }
14695        }
14696        return runList;
14697    }
14698
14699    @Override
14700    public List<ApplicationInfo> getRunningExternalApplications() {
14701        enforceNotIsolatedCaller("getRunningExternalApplications");
14702        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14703        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14704        if (runningApps != null && runningApps.size() > 0) {
14705            Set<String> extList = new HashSet<String>();
14706            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14707                if (app.pkgList != null) {
14708                    for (String pkg : app.pkgList) {
14709                        extList.add(pkg);
14710                    }
14711                }
14712            }
14713            IPackageManager pm = AppGlobals.getPackageManager();
14714            for (String pkg : extList) {
14715                try {
14716                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14717                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14718                        retList.add(info);
14719                    }
14720                } catch (RemoteException e) {
14721                }
14722            }
14723        }
14724        return retList;
14725    }
14726
14727    @Override
14728    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14729        enforceNotIsolatedCaller("getMyMemoryState");
14730        synchronized (this) {
14731            ProcessRecord proc;
14732            synchronized (mPidsSelfLocked) {
14733                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14734            }
14735            fillInProcMemInfo(proc, outInfo);
14736        }
14737    }
14738
14739    @Override
14740    public int getMemoryTrimLevel() {
14741        enforceNotIsolatedCaller("getMyMemoryState");
14742        synchronized (this) {
14743            return mLastMemoryLevel;
14744        }
14745    }
14746
14747    @Override
14748    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14749            FileDescriptor err, String[] args, ShellCallback callback,
14750            ResultReceiver resultReceiver) {
14751        (new ActivityManagerShellCommand(this, false)).exec(
14752                this, in, out, err, args, callback, resultReceiver);
14753    }
14754
14755    @Override
14756    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14757        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14758
14759        boolean dumpAll = false;
14760        boolean dumpClient = false;
14761        boolean dumpCheckin = false;
14762        boolean dumpCheckinFormat = false;
14763        boolean dumpVisibleStacksOnly = false;
14764        boolean dumpFocusedStackOnly = false;
14765        String dumpPackage = null;
14766
14767        int opti = 0;
14768        while (opti < args.length) {
14769            String opt = args[opti];
14770            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14771                break;
14772            }
14773            opti++;
14774            if ("-a".equals(opt)) {
14775                dumpAll = true;
14776            } else if ("-c".equals(opt)) {
14777                dumpClient = true;
14778            } else if ("-v".equals(opt)) {
14779                dumpVisibleStacksOnly = true;
14780            } else if ("-f".equals(opt)) {
14781                dumpFocusedStackOnly = true;
14782            } else if ("-p".equals(opt)) {
14783                if (opti < args.length) {
14784                    dumpPackage = args[opti];
14785                    opti++;
14786                } else {
14787                    pw.println("Error: -p option requires package argument");
14788                    return;
14789                }
14790                dumpClient = true;
14791            } else if ("--checkin".equals(opt)) {
14792                dumpCheckin = dumpCheckinFormat = true;
14793            } else if ("-C".equals(opt)) {
14794                dumpCheckinFormat = true;
14795            } else if ("-h".equals(opt)) {
14796                ActivityManagerShellCommand.dumpHelp(pw, true);
14797                return;
14798            } else {
14799                pw.println("Unknown argument: " + opt + "; use -h for help");
14800            }
14801        }
14802
14803        long origId = Binder.clearCallingIdentity();
14804        boolean more = false;
14805        // Is the caller requesting to dump a particular piece of data?
14806        if (opti < args.length) {
14807            String cmd = args[opti];
14808            opti++;
14809            if ("activities".equals(cmd) || "a".equals(cmd)) {
14810                synchronized (this) {
14811                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14812                }
14813            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14814                synchronized (this) {
14815                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14816                }
14817            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14818                String[] newArgs;
14819                String name;
14820                if (opti >= args.length) {
14821                    name = null;
14822                    newArgs = EMPTY_STRING_ARRAY;
14823                } else {
14824                    dumpPackage = args[opti];
14825                    opti++;
14826                    newArgs = new String[args.length - opti];
14827                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14828                            args.length - opti);
14829                }
14830                synchronized (this) {
14831                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14832                }
14833            } else if ("broadcast-stats".equals(cmd)) {
14834                String[] newArgs;
14835                String name;
14836                if (opti >= args.length) {
14837                    name = null;
14838                    newArgs = EMPTY_STRING_ARRAY;
14839                } else {
14840                    dumpPackage = args[opti];
14841                    opti++;
14842                    newArgs = new String[args.length - opti];
14843                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14844                            args.length - opti);
14845                }
14846                synchronized (this) {
14847                    if (dumpCheckinFormat) {
14848                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14849                                dumpPackage);
14850                    } else {
14851                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14852                    }
14853                }
14854            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14855                String[] newArgs;
14856                String name;
14857                if (opti >= args.length) {
14858                    name = null;
14859                    newArgs = EMPTY_STRING_ARRAY;
14860                } else {
14861                    dumpPackage = args[opti];
14862                    opti++;
14863                    newArgs = new String[args.length - opti];
14864                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14865                            args.length - opti);
14866                }
14867                synchronized (this) {
14868                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14869                }
14870            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14871                String[] newArgs;
14872                String name;
14873                if (opti >= args.length) {
14874                    name = null;
14875                    newArgs = EMPTY_STRING_ARRAY;
14876                } else {
14877                    dumpPackage = args[opti];
14878                    opti++;
14879                    newArgs = new String[args.length - opti];
14880                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14881                            args.length - opti);
14882                }
14883                synchronized (this) {
14884                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14885                }
14886            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14887                synchronized (this) {
14888                    dumpOomLocked(fd, pw, args, opti, true);
14889                }
14890            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14891                synchronized (this) {
14892                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14893                }
14894            } else if ("provider".equals(cmd)) {
14895                String[] newArgs;
14896                String name;
14897                if (opti >= args.length) {
14898                    name = null;
14899                    newArgs = EMPTY_STRING_ARRAY;
14900                } else {
14901                    name = args[opti];
14902                    opti++;
14903                    newArgs = new String[args.length - opti];
14904                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14905                }
14906                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14907                    pw.println("No providers match: " + name);
14908                    pw.println("Use -h for help.");
14909                }
14910            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14911                synchronized (this) {
14912                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14913                }
14914            } else if ("service".equals(cmd)) {
14915                String[] newArgs;
14916                String name;
14917                if (opti >= args.length) {
14918                    name = null;
14919                    newArgs = EMPTY_STRING_ARRAY;
14920                } else {
14921                    name = args[opti];
14922                    opti++;
14923                    newArgs = new String[args.length - opti];
14924                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14925                            args.length - opti);
14926                }
14927                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14928                    pw.println("No services match: " + name);
14929                    pw.println("Use -h for help.");
14930                }
14931            } else if ("package".equals(cmd)) {
14932                String[] newArgs;
14933                if (opti >= args.length) {
14934                    pw.println("package: no package name specified");
14935                    pw.println("Use -h for help.");
14936                } else {
14937                    dumpPackage = args[opti];
14938                    opti++;
14939                    newArgs = new String[args.length - opti];
14940                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14941                            args.length - opti);
14942                    args = newArgs;
14943                    opti = 0;
14944                    more = true;
14945                }
14946            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14947                synchronized (this) {
14948                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14949                }
14950            } else if ("settings".equals(cmd)) {
14951                synchronized (this) {
14952                    mConstants.dump(pw);
14953                }
14954            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14955                if (dumpClient) {
14956                    ActiveServices.ServiceDumper dumper;
14957                    synchronized (this) {
14958                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14959                                dumpPackage);
14960                    }
14961                    dumper.dumpWithClient();
14962                } else {
14963                    synchronized (this) {
14964                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14965                                dumpPackage).dumpLocked();
14966                    }
14967                }
14968            } else if ("locks".equals(cmd)) {
14969                LockGuard.dump(fd, pw, args);
14970            } else {
14971                // Dumping a single activity?
14972                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
14973                        dumpFocusedStackOnly)) {
14974                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14975                    int res = shell.exec(this, null, fd, null, args, null,
14976                            new ResultReceiver(null));
14977                    if (res < 0) {
14978                        pw.println("Bad activity command, or no activities match: " + cmd);
14979                        pw.println("Use -h for help.");
14980                    }
14981                }
14982            }
14983            if (!more) {
14984                Binder.restoreCallingIdentity(origId);
14985                return;
14986            }
14987        }
14988
14989        // No piece of data specified, dump everything.
14990        if (dumpCheckinFormat) {
14991            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14992        } else if (dumpClient) {
14993            ActiveServices.ServiceDumper sdumper;
14994            synchronized (this) {
14995                mConstants.dump(pw);
14996                pw.println();
14997                if (dumpAll) {
14998                    pw.println("-------------------------------------------------------------------------------");
14999                }
15000                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15001                pw.println();
15002                if (dumpAll) {
15003                    pw.println("-------------------------------------------------------------------------------");
15004                }
15005                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15006                pw.println();
15007                if (dumpAll) {
15008                    pw.println("-------------------------------------------------------------------------------");
15009                }
15010                if (dumpAll || dumpPackage != null) {
15011                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15012                    pw.println();
15013                    if (dumpAll) {
15014                        pw.println("-------------------------------------------------------------------------------");
15015                    }
15016                }
15017                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15018                pw.println();
15019                if (dumpAll) {
15020                    pw.println("-------------------------------------------------------------------------------");
15021                }
15022                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15023                pw.println();
15024                if (dumpAll) {
15025                    pw.println("-------------------------------------------------------------------------------");
15026                }
15027                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15028                        dumpPackage);
15029            }
15030            sdumper.dumpWithClient();
15031            pw.println();
15032            synchronized (this) {
15033                if (dumpAll) {
15034                    pw.println("-------------------------------------------------------------------------------");
15035                }
15036                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15037                pw.println();
15038                if (dumpAll) {
15039                    pw.println("-------------------------------------------------------------------------------");
15040                }
15041                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15042                if (mAssociations.size() > 0) {
15043                    pw.println();
15044                    if (dumpAll) {
15045                        pw.println("-------------------------------------------------------------------------------");
15046                    }
15047                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15048                }
15049                pw.println();
15050                if (dumpAll) {
15051                    pw.println("-------------------------------------------------------------------------------");
15052                }
15053                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15054            }
15055
15056        } else {
15057            synchronized (this) {
15058                mConstants.dump(pw);
15059                pw.println();
15060                if (dumpAll) {
15061                    pw.println("-------------------------------------------------------------------------------");
15062                }
15063                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15064                pw.println();
15065                if (dumpAll) {
15066                    pw.println("-------------------------------------------------------------------------------");
15067                }
15068                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15069                pw.println();
15070                if (dumpAll) {
15071                    pw.println("-------------------------------------------------------------------------------");
15072                }
15073                if (dumpAll || dumpPackage != null) {
15074                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15075                    pw.println();
15076                    if (dumpAll) {
15077                        pw.println("-------------------------------------------------------------------------------");
15078                    }
15079                }
15080                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15081                pw.println();
15082                if (dumpAll) {
15083                    pw.println("-------------------------------------------------------------------------------");
15084                }
15085                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15086                pw.println();
15087                if (dumpAll) {
15088                    pw.println("-------------------------------------------------------------------------------");
15089                }
15090                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15091                        .dumpLocked();
15092                pw.println();
15093                if (dumpAll) {
15094                    pw.println("-------------------------------------------------------------------------------");
15095                }
15096                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15097                pw.println();
15098                if (dumpAll) {
15099                    pw.println("-------------------------------------------------------------------------------");
15100                }
15101                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15102                if (mAssociations.size() > 0) {
15103                    pw.println();
15104                    if (dumpAll) {
15105                        pw.println("-------------------------------------------------------------------------------");
15106                    }
15107                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15108                }
15109                pw.println();
15110                if (dumpAll) {
15111                    pw.println("-------------------------------------------------------------------------------");
15112                }
15113                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15114            }
15115        }
15116        Binder.restoreCallingIdentity(origId);
15117    }
15118
15119    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15120            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15121        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15122
15123        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15124                dumpPackage);
15125        boolean needSep = printedAnything;
15126
15127        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15128                mStackSupervisor.getResumedActivityLocked(),
15129                dumpPackage, needSep, "  ResumedActivity: ");
15130        if (printed) {
15131            printedAnything = true;
15132            needSep = false;
15133        }
15134
15135        if (dumpPackage == null) {
15136            if (needSep) {
15137                pw.println();
15138            }
15139            needSep = true;
15140            printedAnything = true;
15141            mStackSupervisor.dump(pw, "  ");
15142        }
15143
15144        if (!printedAnything) {
15145            pw.println("  (nothing)");
15146        }
15147    }
15148
15149    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15150            int opti, boolean dumpAll, String dumpPackage) {
15151        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15152
15153        boolean printedAnything = false;
15154
15155        if (mRecentTasks != null && mRecentTasks.size() > 0) {
15156            boolean printedHeader = false;
15157
15158            final int N = mRecentTasks.size();
15159            for (int i=0; i<N; i++) {
15160                TaskRecord tr = mRecentTasks.get(i);
15161                if (dumpPackage != null) {
15162                    if (tr.realActivity == null ||
15163                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
15164                        continue;
15165                    }
15166                }
15167                if (!printedHeader) {
15168                    pw.println("  Recent tasks:");
15169                    printedHeader = true;
15170                    printedAnything = true;
15171                }
15172                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15173                        pw.println(tr);
15174                if (dumpAll) {
15175                    mRecentTasks.get(i).dump(pw, "    ");
15176                }
15177            }
15178        }
15179
15180        if (!printedAnything) {
15181            pw.println("  (nothing)");
15182        }
15183    }
15184
15185    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15186            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15187        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15188
15189        int dumpUid = 0;
15190        if (dumpPackage != null) {
15191            IPackageManager pm = AppGlobals.getPackageManager();
15192            try {
15193                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15194            } catch (RemoteException e) {
15195            }
15196        }
15197
15198        boolean printedAnything = false;
15199
15200        final long now = SystemClock.uptimeMillis();
15201
15202        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15203            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15204                    = mAssociations.valueAt(i1);
15205            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15206                SparseArray<ArrayMap<String, Association>> sourceUids
15207                        = targetComponents.valueAt(i2);
15208                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15209                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15210                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15211                        Association ass = sourceProcesses.valueAt(i4);
15212                        if (dumpPackage != null) {
15213                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15214                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15215                                continue;
15216                            }
15217                        }
15218                        printedAnything = true;
15219                        pw.print("  ");
15220                        pw.print(ass.mTargetProcess);
15221                        pw.print("/");
15222                        UserHandle.formatUid(pw, ass.mTargetUid);
15223                        pw.print(" <- ");
15224                        pw.print(ass.mSourceProcess);
15225                        pw.print("/");
15226                        UserHandle.formatUid(pw, ass.mSourceUid);
15227                        pw.println();
15228                        pw.print("    via ");
15229                        pw.print(ass.mTargetComponent.flattenToShortString());
15230                        pw.println();
15231                        pw.print("    ");
15232                        long dur = ass.mTime;
15233                        if (ass.mNesting > 0) {
15234                            dur += now - ass.mStartTime;
15235                        }
15236                        TimeUtils.formatDuration(dur, pw);
15237                        pw.print(" (");
15238                        pw.print(ass.mCount);
15239                        pw.print(" times)");
15240                        pw.print("  ");
15241                        for (int i=0; i<ass.mStateTimes.length; i++) {
15242                            long amt = ass.mStateTimes[i];
15243                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15244                                amt += now - ass.mLastStateUptime;
15245                            }
15246                            if (amt != 0) {
15247                                pw.print(" ");
15248                                pw.print(ProcessList.makeProcStateString(
15249                                            i + ActivityManager.MIN_PROCESS_STATE));
15250                                pw.print("=");
15251                                TimeUtils.formatDuration(amt, pw);
15252                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15253                                    pw.print("*");
15254                                }
15255                            }
15256                        }
15257                        pw.println();
15258                        if (ass.mNesting > 0) {
15259                            pw.print("    Currently active: ");
15260                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15261                            pw.println();
15262                        }
15263                    }
15264                }
15265            }
15266
15267        }
15268
15269        if (!printedAnything) {
15270            pw.println("  (nothing)");
15271        }
15272    }
15273
15274    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15275            String header, boolean needSep) {
15276        boolean printed = false;
15277        int whichAppId = -1;
15278        if (dumpPackage != null) {
15279            try {
15280                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15281                        dumpPackage, 0);
15282                whichAppId = UserHandle.getAppId(info.uid);
15283            } catch (NameNotFoundException e) {
15284                e.printStackTrace();
15285            }
15286        }
15287        for (int i=0; i<uids.size(); i++) {
15288            UidRecord uidRec = uids.valueAt(i);
15289            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15290                continue;
15291            }
15292            if (!printed) {
15293                printed = true;
15294                if (needSep) {
15295                    pw.println();
15296                }
15297                pw.print("  ");
15298                pw.println(header);
15299                needSep = true;
15300            }
15301            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15302            pw.print(": "); pw.println(uidRec);
15303        }
15304        return printed;
15305    }
15306
15307    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15308            int opti, boolean dumpAll, String dumpPackage) {
15309        boolean needSep = false;
15310        boolean printedAnything = false;
15311        int numPers = 0;
15312
15313        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15314
15315        if (dumpAll) {
15316            final int NP = mProcessNames.getMap().size();
15317            for (int ip=0; ip<NP; ip++) {
15318                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15319                final int NA = procs.size();
15320                for (int ia=0; ia<NA; ia++) {
15321                    ProcessRecord r = procs.valueAt(ia);
15322                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15323                        continue;
15324                    }
15325                    if (!needSep) {
15326                        pw.println("  All known processes:");
15327                        needSep = true;
15328                        printedAnything = true;
15329                    }
15330                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15331                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15332                        pw.print(" "); pw.println(r);
15333                    r.dump(pw, "    ");
15334                    if (r.persistent) {
15335                        numPers++;
15336                    }
15337                }
15338            }
15339        }
15340
15341        if (mIsolatedProcesses.size() > 0) {
15342            boolean printed = false;
15343            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15344                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15345                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15346                    continue;
15347                }
15348                if (!printed) {
15349                    if (needSep) {
15350                        pw.println();
15351                    }
15352                    pw.println("  Isolated process list (sorted by uid):");
15353                    printedAnything = true;
15354                    printed = true;
15355                    needSep = true;
15356                }
15357                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15358                pw.println(r);
15359            }
15360        }
15361
15362        if (mActiveInstrumentation.size() > 0) {
15363            boolean printed = false;
15364            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15365                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15366                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15367                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15368                    continue;
15369                }
15370                if (!printed) {
15371                    if (needSep) {
15372                        pw.println();
15373                    }
15374                    pw.println("  Active instrumentation:");
15375                    printedAnything = true;
15376                    printed = true;
15377                    needSep = true;
15378                }
15379                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15380                pw.println(ai);
15381                ai.dump(pw, "      ");
15382            }
15383        }
15384
15385        if (mActiveUids.size() > 0) {
15386            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15387                printedAnything = needSep = true;
15388            }
15389        }
15390        if (dumpAll) {
15391            if (mValidateUids.size() > 0) {
15392                if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15393                    printedAnything = needSep = true;
15394                }
15395            }
15396        }
15397
15398        if (mLruProcesses.size() > 0) {
15399            if (needSep) {
15400                pw.println();
15401            }
15402            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15403                    pw.print(" total, non-act at ");
15404                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15405                    pw.print(", non-svc at ");
15406                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15407                    pw.println("):");
15408            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15409            needSep = true;
15410            printedAnything = true;
15411        }
15412
15413        if (dumpAll || dumpPackage != null) {
15414            synchronized (mPidsSelfLocked) {
15415                boolean printed = false;
15416                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15417                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15418                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15419                        continue;
15420                    }
15421                    if (!printed) {
15422                        if (needSep) pw.println();
15423                        needSep = true;
15424                        pw.println("  PID mappings:");
15425                        printed = true;
15426                        printedAnything = true;
15427                    }
15428                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15429                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15430                }
15431            }
15432        }
15433
15434        if (mForegroundProcesses.size() > 0) {
15435            synchronized (mPidsSelfLocked) {
15436                boolean printed = false;
15437                for (int i=0; i<mForegroundProcesses.size(); i++) {
15438                    ProcessRecord r = mPidsSelfLocked.get(
15439                            mForegroundProcesses.valueAt(i).pid);
15440                    if (dumpPackage != null && (r == null
15441                            || !r.pkgList.containsKey(dumpPackage))) {
15442                        continue;
15443                    }
15444                    if (!printed) {
15445                        if (needSep) pw.println();
15446                        needSep = true;
15447                        pw.println("  Foreground Processes:");
15448                        printed = true;
15449                        printedAnything = true;
15450                    }
15451                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
15452                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
15453                }
15454            }
15455        }
15456
15457        if (mPersistentStartingProcesses.size() > 0) {
15458            if (needSep) pw.println();
15459            needSep = true;
15460            printedAnything = true;
15461            pw.println("  Persisent processes that are starting:");
15462            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15463                    "Starting Norm", "Restarting PERS", dumpPackage);
15464        }
15465
15466        if (mRemovedProcesses.size() > 0) {
15467            if (needSep) pw.println();
15468            needSep = true;
15469            printedAnything = true;
15470            pw.println("  Processes that are being removed:");
15471            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15472                    "Removed Norm", "Removed PERS", dumpPackage);
15473        }
15474
15475        if (mProcessesOnHold.size() > 0) {
15476            if (needSep) pw.println();
15477            needSep = true;
15478            printedAnything = true;
15479            pw.println("  Processes that are on old until the system is ready:");
15480            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15481                    "OnHold Norm", "OnHold PERS", dumpPackage);
15482        }
15483
15484        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15485
15486        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15487        if (needSep) {
15488            printedAnything = true;
15489        }
15490
15491        if (dumpPackage == null) {
15492            pw.println();
15493            needSep = false;
15494            mUserController.dump(pw, dumpAll);
15495        }
15496        if (mHomeProcess != null && (dumpPackage == null
15497                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15498            if (needSep) {
15499                pw.println();
15500                needSep = false;
15501            }
15502            pw.println("  mHomeProcess: " + mHomeProcess);
15503        }
15504        if (mPreviousProcess != null && (dumpPackage == null
15505                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15506            if (needSep) {
15507                pw.println();
15508                needSep = false;
15509            }
15510            pw.println("  mPreviousProcess: " + mPreviousProcess);
15511        }
15512        if (dumpAll) {
15513            StringBuilder sb = new StringBuilder(128);
15514            sb.append("  mPreviousProcessVisibleTime: ");
15515            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15516            pw.println(sb);
15517        }
15518        if (mHeavyWeightProcess != null && (dumpPackage == null
15519                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15520            if (needSep) {
15521                pw.println();
15522                needSep = false;
15523            }
15524            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15525        }
15526        if (dumpPackage == null) {
15527            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15528            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15529        }
15530        if (dumpAll) {
15531            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15532            if (mCompatModePackages.getPackages().size() > 0) {
15533                boolean printed = false;
15534                for (Map.Entry<String, Integer> entry
15535                        : mCompatModePackages.getPackages().entrySet()) {
15536                    String pkg = entry.getKey();
15537                    int mode = entry.getValue();
15538                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15539                        continue;
15540                    }
15541                    if (!printed) {
15542                        pw.println("  mScreenCompatPackages:");
15543                        printed = true;
15544                    }
15545                    pw.print("    "); pw.print(pkg); pw.print(": ");
15546                            pw.print(mode); pw.println();
15547                }
15548            }
15549            final int NI = mUidObservers.getRegisteredCallbackCount();
15550            boolean printed = false;
15551            for (int i=0; i<NI; i++) {
15552                final UidObserverRegistration reg = (UidObserverRegistration)
15553                        mUidObservers.getRegisteredCallbackCookie(i);
15554                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15555                    if (!printed) {
15556                        pw.println("  mUidObservers:");
15557                        printed = true;
15558                    }
15559                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15560                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15561                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15562                        pw.print(" IDLE");
15563                    }
15564                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15565                        pw.print(" ACT" );
15566                    }
15567                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15568                        pw.print(" GONE");
15569                    }
15570                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15571                        pw.print(" STATE");
15572                        pw.print(" (cut="); pw.print(reg.cutpoint);
15573                        pw.print(")");
15574                    }
15575                    pw.println();
15576                    if (reg.lastProcStates != null) {
15577                        final int NJ = reg.lastProcStates.size();
15578                        for (int j=0; j<NJ; j++) {
15579                            pw.print("      Last ");
15580                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15581                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15582                        }
15583                    }
15584                }
15585            }
15586            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15587            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15588            if (mPendingTempWhitelist.size() > 0) {
15589                pw.println("  mPendingTempWhitelist:");
15590                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15591                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15592                    pw.print("    ");
15593                    UserHandle.formatUid(pw, ptw.targetUid);
15594                    pw.print(": ");
15595                    TimeUtils.formatDuration(ptw.duration, pw);
15596                    pw.print(" ");
15597                    pw.println(ptw.tag);
15598                }
15599            }
15600        }
15601        if (dumpPackage == null) {
15602            pw.println("  mWakefulness="
15603                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15604            pw.println("  mSleepTokens=" + mSleepTokens);
15605            pw.println("  mSleeping=" + mSleeping);
15606            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15607            if (mRunningVoice != null) {
15608                pw.println("  mRunningVoice=" + mRunningVoice);
15609                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15610            }
15611        }
15612        pw.println("  mVrController=" + mVrController);
15613        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15614                || mOrigWaitForDebugger) {
15615            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15616                    || dumpPackage.equals(mOrigDebugApp)) {
15617                if (needSep) {
15618                    pw.println();
15619                    needSep = false;
15620                }
15621                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15622                        + " mDebugTransient=" + mDebugTransient
15623                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15624            }
15625        }
15626        if (mCurAppTimeTracker != null) {
15627            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15628        }
15629        if (mMemWatchProcesses.getMap().size() > 0) {
15630            pw.println("  Mem watch processes:");
15631            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15632                    = mMemWatchProcesses.getMap();
15633            for (int i=0; i<procs.size(); i++) {
15634                final String proc = procs.keyAt(i);
15635                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15636                for (int j=0; j<uids.size(); j++) {
15637                    if (needSep) {
15638                        pw.println();
15639                        needSep = false;
15640                    }
15641                    StringBuilder sb = new StringBuilder();
15642                    sb.append("    ").append(proc).append('/');
15643                    UserHandle.formatUid(sb, uids.keyAt(j));
15644                    Pair<Long, String> val = uids.valueAt(j);
15645                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15646                    if (val.second != null) {
15647                        sb.append(", report to ").append(val.second);
15648                    }
15649                    pw.println(sb.toString());
15650                }
15651            }
15652            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15653            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15654            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15655                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15656        }
15657        if (mTrackAllocationApp != null) {
15658            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15659                if (needSep) {
15660                    pw.println();
15661                    needSep = false;
15662                }
15663                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15664            }
15665        }
15666        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15667                || mProfileFd != null) {
15668            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15669                if (needSep) {
15670                    pw.println();
15671                    needSep = false;
15672                }
15673                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15674                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15675                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15676                        + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15677                pw.println("  mProfileType=" + mProfileType);
15678            }
15679        }
15680        if (mNativeDebuggingApp != null) {
15681            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15682                if (needSep) {
15683                    pw.println();
15684                    needSep = false;
15685                }
15686                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15687            }
15688        }
15689        if (dumpPackage == null) {
15690            if (mAlwaysFinishActivities) {
15691                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15692            }
15693            if (mController != null) {
15694                pw.println("  mController=" + mController
15695                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15696            }
15697            if (dumpAll) {
15698                pw.println("  Total persistent processes: " + numPers);
15699                pw.println("  mProcessesReady=" + mProcessesReady
15700                        + " mSystemReady=" + mSystemReady
15701                        + " mBooted=" + mBooted
15702                        + " mFactoryTest=" + mFactoryTest);
15703                pw.println("  mBooting=" + mBooting
15704                        + " mCallFinishBooting=" + mCallFinishBooting
15705                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15706                pw.print("  mLastPowerCheckRealtime=");
15707                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15708                        pw.println("");
15709                pw.print("  mLastPowerCheckUptime=");
15710                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15711                        pw.println("");
15712                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15713                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15714                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15715                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15716                        + " (" + mLruProcesses.size() + " total)"
15717                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15718                        + " mNumServiceProcs=" + mNumServiceProcs
15719                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15720                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15721                        + " mLastMemoryLevel=" + mLastMemoryLevel
15722                        + " mLastNumProcesses=" + mLastNumProcesses);
15723                long now = SystemClock.uptimeMillis();
15724                pw.print("  mLastIdleTime=");
15725                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15726                        pw.print(" mLowRamSinceLastIdle=");
15727                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15728                        pw.println();
15729            }
15730        }
15731
15732        if (!printedAnything) {
15733            pw.println("  (nothing)");
15734        }
15735    }
15736
15737    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15738            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15739        if (mProcessesToGc.size() > 0) {
15740            boolean printed = false;
15741            long now = SystemClock.uptimeMillis();
15742            for (int i=0; i<mProcessesToGc.size(); i++) {
15743                ProcessRecord proc = mProcessesToGc.get(i);
15744                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15745                    continue;
15746                }
15747                if (!printed) {
15748                    if (needSep) pw.println();
15749                    needSep = true;
15750                    pw.println("  Processes that are waiting to GC:");
15751                    printed = true;
15752                }
15753                pw.print("    Process "); pw.println(proc);
15754                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15755                        pw.print(", last gced=");
15756                        pw.print(now-proc.lastRequestedGc);
15757                        pw.print(" ms ago, last lowMem=");
15758                        pw.print(now-proc.lastLowMemory);
15759                        pw.println(" ms ago");
15760
15761            }
15762        }
15763        return needSep;
15764    }
15765
15766    void printOomLevel(PrintWriter pw, String name, int adj) {
15767        pw.print("    ");
15768        if (adj >= 0) {
15769            pw.print(' ');
15770            if (adj < 10) pw.print(' ');
15771        } else {
15772            if (adj > -10) pw.print(' ');
15773        }
15774        pw.print(adj);
15775        pw.print(": ");
15776        pw.print(name);
15777        pw.print(" (");
15778        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15779        pw.println(")");
15780    }
15781
15782    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15783            int opti, boolean dumpAll) {
15784        boolean needSep = false;
15785
15786        if (mLruProcesses.size() > 0) {
15787            if (needSep) pw.println();
15788            needSep = true;
15789            pw.println("  OOM levels:");
15790            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15791            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15792            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15793            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15794            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15795            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15796            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15797            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15798            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15799            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15800            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15801            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15802            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15803            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15804
15805            if (needSep) pw.println();
15806            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15807                    pw.print(" total, non-act at ");
15808                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15809                    pw.print(", non-svc at ");
15810                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15811                    pw.println("):");
15812            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15813            needSep = true;
15814        }
15815
15816        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15817
15818        pw.println();
15819        pw.println("  mHomeProcess: " + mHomeProcess);
15820        pw.println("  mPreviousProcess: " + mPreviousProcess);
15821        if (mHeavyWeightProcess != null) {
15822            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15823        }
15824
15825        return true;
15826    }
15827
15828    /**
15829     * There are three ways to call this:
15830     *  - no provider specified: dump all the providers
15831     *  - a flattened component name that matched an existing provider was specified as the
15832     *    first arg: dump that one provider
15833     *  - the first arg isn't the flattened component name of an existing provider:
15834     *    dump all providers whose component contains the first arg as a substring
15835     */
15836    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15837            int opti, boolean dumpAll) {
15838        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15839    }
15840
15841    static class ItemMatcher {
15842        ArrayList<ComponentName> components;
15843        ArrayList<String> strings;
15844        ArrayList<Integer> objects;
15845        boolean all;
15846
15847        ItemMatcher() {
15848            all = true;
15849        }
15850
15851        void build(String name) {
15852            ComponentName componentName = ComponentName.unflattenFromString(name);
15853            if (componentName != null) {
15854                if (components == null) {
15855                    components = new ArrayList<ComponentName>();
15856                }
15857                components.add(componentName);
15858                all = false;
15859            } else {
15860                int objectId = 0;
15861                // Not a '/' separated full component name; maybe an object ID?
15862                try {
15863                    objectId = Integer.parseInt(name, 16);
15864                    if (objects == null) {
15865                        objects = new ArrayList<Integer>();
15866                    }
15867                    objects.add(objectId);
15868                    all = false;
15869                } catch (RuntimeException e) {
15870                    // Not an integer; just do string match.
15871                    if (strings == null) {
15872                        strings = new ArrayList<String>();
15873                    }
15874                    strings.add(name);
15875                    all = false;
15876                }
15877            }
15878        }
15879
15880        int build(String[] args, int opti) {
15881            for (; opti<args.length; opti++) {
15882                String name = args[opti];
15883                if ("--".equals(name)) {
15884                    return opti+1;
15885                }
15886                build(name);
15887            }
15888            return opti;
15889        }
15890
15891        boolean match(Object object, ComponentName comp) {
15892            if (all) {
15893                return true;
15894            }
15895            if (components != null) {
15896                for (int i=0; i<components.size(); i++) {
15897                    if (components.get(i).equals(comp)) {
15898                        return true;
15899                    }
15900                }
15901            }
15902            if (objects != null) {
15903                for (int i=0; i<objects.size(); i++) {
15904                    if (System.identityHashCode(object) == objects.get(i)) {
15905                        return true;
15906                    }
15907                }
15908            }
15909            if (strings != null) {
15910                String flat = comp.flattenToString();
15911                for (int i=0; i<strings.size(); i++) {
15912                    if (flat.contains(strings.get(i))) {
15913                        return true;
15914                    }
15915                }
15916            }
15917            return false;
15918        }
15919    }
15920
15921    /**
15922     * There are three things that cmd can be:
15923     *  - a flattened component name that matches an existing activity
15924     *  - the cmd arg isn't the flattened component name of an existing activity:
15925     *    dump all activity whose component contains the cmd as a substring
15926     *  - A hex number of the ActivityRecord object instance.
15927     *
15928     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
15929     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
15930     */
15931    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15932            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
15933        ArrayList<ActivityRecord> activities;
15934
15935        synchronized (this) {
15936            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
15937                    dumpFocusedStackOnly);
15938        }
15939
15940        if (activities.size() <= 0) {
15941            return false;
15942        }
15943
15944        String[] newArgs = new String[args.length - opti];
15945        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15946
15947        TaskRecord lastTask = null;
15948        boolean needSep = false;
15949        for (int i=activities.size()-1; i>=0; i--) {
15950            ActivityRecord r = activities.get(i);
15951            if (needSep) {
15952                pw.println();
15953            }
15954            needSep = true;
15955            synchronized (this) {
15956                final TaskRecord task = r.getTask();
15957                if (lastTask != task) {
15958                    lastTask = task;
15959                    pw.print("TASK "); pw.print(lastTask.affinity);
15960                            pw.print(" id="); pw.print(lastTask.taskId);
15961                            pw.print(" userId="); pw.println(lastTask.userId);
15962                    if (dumpAll) {
15963                        lastTask.dump(pw, "  ");
15964                    }
15965                }
15966            }
15967            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15968        }
15969        return true;
15970    }
15971
15972    /**
15973     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15974     * there is a thread associated with the activity.
15975     */
15976    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15977            final ActivityRecord r, String[] args, boolean dumpAll) {
15978        String innerPrefix = prefix + "  ";
15979        synchronized (this) {
15980            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15981                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15982                    pw.print(" pid=");
15983                    if (r.app != null) pw.println(r.app.pid);
15984                    else pw.println("(not running)");
15985            if (dumpAll) {
15986                r.dump(pw, innerPrefix);
15987            }
15988        }
15989        if (r.app != null && r.app.thread != null) {
15990            // flush anything that is already in the PrintWriter since the thread is going
15991            // to write to the file descriptor directly
15992            pw.flush();
15993            try {
15994                TransferPipe tp = new TransferPipe();
15995                try {
15996                    r.app.thread.dumpActivity(tp.getWriteFd(),
15997                            r.appToken, innerPrefix, args);
15998                    tp.go(fd);
15999                } finally {
16000                    tp.kill();
16001                }
16002            } catch (IOException e) {
16003                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16004            } catch (RemoteException e) {
16005                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16006            }
16007        }
16008    }
16009
16010    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16011            int opti, boolean dumpAll, String dumpPackage) {
16012        boolean needSep = false;
16013        boolean onlyHistory = false;
16014        boolean printedAnything = false;
16015
16016        if ("history".equals(dumpPackage)) {
16017            if (opti < args.length && "-s".equals(args[opti])) {
16018                dumpAll = false;
16019            }
16020            onlyHistory = true;
16021            dumpPackage = null;
16022        }
16023
16024        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16025        if (!onlyHistory && dumpAll) {
16026            if (mRegisteredReceivers.size() > 0) {
16027                boolean printed = false;
16028                Iterator it = mRegisteredReceivers.values().iterator();
16029                while (it.hasNext()) {
16030                    ReceiverList r = (ReceiverList)it.next();
16031                    if (dumpPackage != null && (r.app == null ||
16032                            !dumpPackage.equals(r.app.info.packageName))) {
16033                        continue;
16034                    }
16035                    if (!printed) {
16036                        pw.println("  Registered Receivers:");
16037                        needSep = true;
16038                        printed = true;
16039                        printedAnything = true;
16040                    }
16041                    pw.print("  * "); pw.println(r);
16042                    r.dump(pw, "    ");
16043                }
16044            }
16045
16046            if (mReceiverResolver.dump(pw, needSep ?
16047                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16048                    "    ", dumpPackage, false, false)) {
16049                needSep = true;
16050                printedAnything = true;
16051            }
16052        }
16053
16054        for (BroadcastQueue q : mBroadcastQueues) {
16055            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16056            printedAnything |= needSep;
16057        }
16058
16059        needSep = true;
16060
16061        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16062            for (int user=0; user<mStickyBroadcasts.size(); user++) {
16063                if (needSep) {
16064                    pw.println();
16065                }
16066                needSep = true;
16067                printedAnything = true;
16068                pw.print("  Sticky broadcasts for user ");
16069                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16070                StringBuilder sb = new StringBuilder(128);
16071                for (Map.Entry<String, ArrayList<Intent>> ent
16072                        : mStickyBroadcasts.valueAt(user).entrySet()) {
16073                    pw.print("  * Sticky action "); pw.print(ent.getKey());
16074                    if (dumpAll) {
16075                        pw.println(":");
16076                        ArrayList<Intent> intents = ent.getValue();
16077                        final int N = intents.size();
16078                        for (int i=0; i<N; i++) {
16079                            sb.setLength(0);
16080                            sb.append("    Intent: ");
16081                            intents.get(i).toShortString(sb, false, true, false, false);
16082                            pw.println(sb.toString());
16083                            Bundle bundle = intents.get(i).getExtras();
16084                            if (bundle != null) {
16085                                pw.print("      ");
16086                                pw.println(bundle.toString());
16087                            }
16088                        }
16089                    } else {
16090                        pw.println("");
16091                    }
16092                }
16093            }
16094        }
16095
16096        if (!onlyHistory && dumpAll) {
16097            pw.println();
16098            for (BroadcastQueue queue : mBroadcastQueues) {
16099                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16100                        + queue.mBroadcastsScheduled);
16101            }
16102            pw.println("  mHandler:");
16103            mHandler.dump(new PrintWriterPrinter(pw), "    ");
16104            needSep = true;
16105            printedAnything = true;
16106        }
16107
16108        if (!printedAnything) {
16109            pw.println("  (nothing)");
16110        }
16111    }
16112
16113    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16114            int opti, boolean dumpAll, String dumpPackage) {
16115        if (mCurBroadcastStats == null) {
16116            return;
16117        }
16118
16119        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16120        final long now = SystemClock.elapsedRealtime();
16121        if (mLastBroadcastStats != null) {
16122            pw.print("  Last stats (from ");
16123            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16124            pw.print(" to ");
16125            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16126            pw.print(", ");
16127            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16128                    - mLastBroadcastStats.mStartUptime, pw);
16129            pw.println(" uptime):");
16130            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16131                pw.println("    (nothing)");
16132            }
16133            pw.println();
16134        }
16135        pw.print("  Current stats (from ");
16136        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16137        pw.print(" to now, ");
16138        TimeUtils.formatDuration(SystemClock.uptimeMillis()
16139                - mCurBroadcastStats.mStartUptime, pw);
16140        pw.println(" uptime):");
16141        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16142            pw.println("    (nothing)");
16143        }
16144    }
16145
16146    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16147            int opti, boolean fullCheckin, String dumpPackage) {
16148        if (mCurBroadcastStats == null) {
16149            return;
16150        }
16151
16152        if (mLastBroadcastStats != null) {
16153            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16154            if (fullCheckin) {
16155                mLastBroadcastStats = null;
16156                return;
16157            }
16158        }
16159        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16160        if (fullCheckin) {
16161            mCurBroadcastStats = null;
16162        }
16163    }
16164
16165    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16166            int opti, boolean dumpAll, String dumpPackage) {
16167        boolean needSep;
16168        boolean printedAnything = false;
16169
16170        ItemMatcher matcher = new ItemMatcher();
16171        matcher.build(args, opti);
16172
16173        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16174
16175        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16176        printedAnything |= needSep;
16177
16178        if (mLaunchingProviders.size() > 0) {
16179            boolean printed = false;
16180            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16181                ContentProviderRecord r = mLaunchingProviders.get(i);
16182                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16183                    continue;
16184                }
16185                if (!printed) {
16186                    if (needSep) pw.println();
16187                    needSep = true;
16188                    pw.println("  Launching content providers:");
16189                    printed = true;
16190                    printedAnything = true;
16191                }
16192                pw.print("  Launching #"); pw.print(i); pw.print(": ");
16193                        pw.println(r);
16194            }
16195        }
16196
16197        if (!printedAnything) {
16198            pw.println("  (nothing)");
16199        }
16200    }
16201
16202    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16203            int opti, boolean dumpAll, String dumpPackage) {
16204        boolean needSep = false;
16205        boolean printedAnything = false;
16206
16207        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16208
16209        if (mGrantedUriPermissions.size() > 0) {
16210            boolean printed = false;
16211            int dumpUid = -2;
16212            if (dumpPackage != null) {
16213                try {
16214                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16215                            MATCH_ANY_USER, 0);
16216                } catch (NameNotFoundException e) {
16217                    dumpUid = -1;
16218                }
16219            }
16220            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16221                int uid = mGrantedUriPermissions.keyAt(i);
16222                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16223                    continue;
16224                }
16225                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16226                if (!printed) {
16227                    if (needSep) pw.println();
16228                    needSep = true;
16229                    pw.println("  Granted Uri Permissions:");
16230                    printed = true;
16231                    printedAnything = true;
16232                }
16233                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16234                for (UriPermission perm : perms.values()) {
16235                    pw.print("    "); pw.println(perm);
16236                    if (dumpAll) {
16237                        perm.dump(pw, "      ");
16238                    }
16239                }
16240            }
16241        }
16242
16243        if (!printedAnything) {
16244            pw.println("  (nothing)");
16245        }
16246    }
16247
16248    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16249            int opti, boolean dumpAll, String dumpPackage) {
16250        boolean printed = false;
16251
16252        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16253
16254        if (mIntentSenderRecords.size() > 0) {
16255            // Organize these by package name, so they are easier to read.
16256            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16257            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16258            final Iterator<WeakReference<PendingIntentRecord>> it
16259                    = mIntentSenderRecords.values().iterator();
16260            while (it.hasNext()) {
16261                WeakReference<PendingIntentRecord> ref = it.next();
16262                PendingIntentRecord rec = ref != null ? ref.get() : null;
16263                if (rec == null) {
16264                    weakRefs.add(ref);
16265                    continue;
16266                }
16267                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16268                    continue;
16269                }
16270                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16271                if (list == null) {
16272                    list = new ArrayList<>();
16273                    byPackage.put(rec.key.packageName, list);
16274                }
16275                list.add(rec);
16276            }
16277            for (int i = 0; i < byPackage.size(); i++) {
16278                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16279                printed = true;
16280                pw.print("  * "); pw.print(byPackage.keyAt(i));
16281                pw.print(": "); pw.print(intents.size()); pw.println(" items");
16282                for (int j = 0; j < intents.size(); j++) {
16283                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16284                    if (dumpAll) {
16285                        intents.get(j).dump(pw, "      ");
16286                    }
16287                }
16288            }
16289            if (weakRefs.size() > 0) {
16290                printed = true;
16291                pw.println("  * WEAK REFS:");
16292                for (int i = 0; i < weakRefs.size(); i++) {
16293                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16294                }
16295            }
16296        }
16297
16298        if (!printed) {
16299            pw.println("  (nothing)");
16300        }
16301    }
16302
16303    private static final int dumpProcessList(PrintWriter pw,
16304            ActivityManagerService service, List list,
16305            String prefix, String normalLabel, String persistentLabel,
16306            String dumpPackage) {
16307        int numPers = 0;
16308        final int N = list.size()-1;
16309        for (int i=N; i>=0; i--) {
16310            ProcessRecord r = (ProcessRecord)list.get(i);
16311            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16312                continue;
16313            }
16314            pw.println(String.format("%s%s #%2d: %s",
16315                    prefix, (r.persistent ? persistentLabel : normalLabel),
16316                    i, r.toString()));
16317            if (r.persistent) {
16318                numPers++;
16319            }
16320        }
16321        return numPers;
16322    }
16323
16324    private static final boolean dumpProcessOomList(PrintWriter pw,
16325            ActivityManagerService service, List<ProcessRecord> origList,
16326            String prefix, String normalLabel, String persistentLabel,
16327            boolean inclDetails, String dumpPackage) {
16328
16329        ArrayList<Pair<ProcessRecord, Integer>> list
16330                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16331        for (int i=0; i<origList.size(); i++) {
16332            ProcessRecord r = origList.get(i);
16333            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16334                continue;
16335            }
16336            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16337        }
16338
16339        if (list.size() <= 0) {
16340            return false;
16341        }
16342
16343        Comparator<Pair<ProcessRecord, Integer>> comparator
16344                = new Comparator<Pair<ProcessRecord, Integer>>() {
16345            @Override
16346            public int compare(Pair<ProcessRecord, Integer> object1,
16347                    Pair<ProcessRecord, Integer> object2) {
16348                if (object1.first.setAdj != object2.first.setAdj) {
16349                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16350                }
16351                if (object1.first.setProcState != object2.first.setProcState) {
16352                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16353                }
16354                if (object1.second.intValue() != object2.second.intValue()) {
16355                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16356                }
16357                return 0;
16358            }
16359        };
16360
16361        Collections.sort(list, comparator);
16362
16363        final long curRealtime = SystemClock.elapsedRealtime();
16364        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16365        final long curUptime = SystemClock.uptimeMillis();
16366        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16367
16368        for (int i=list.size()-1; i>=0; i--) {
16369            ProcessRecord r = list.get(i).first;
16370            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16371            char schedGroup;
16372            switch (r.setSchedGroup) {
16373                case ProcessList.SCHED_GROUP_BACKGROUND:
16374                    schedGroup = 'B';
16375                    break;
16376                case ProcessList.SCHED_GROUP_DEFAULT:
16377                    schedGroup = 'F';
16378                    break;
16379                case ProcessList.SCHED_GROUP_TOP_APP:
16380                    schedGroup = 'T';
16381                    break;
16382                default:
16383                    schedGroup = '?';
16384                    break;
16385            }
16386            char foreground;
16387            if (r.foregroundActivities) {
16388                foreground = 'A';
16389            } else if (r.foregroundServices) {
16390                foreground = 'S';
16391            } else {
16392                foreground = ' ';
16393            }
16394            String procState = ProcessList.makeProcStateString(r.curProcState);
16395            pw.print(prefix);
16396            pw.print(r.persistent ? persistentLabel : normalLabel);
16397            pw.print(" #");
16398            int num = (origList.size()-1)-list.get(i).second;
16399            if (num < 10) pw.print(' ');
16400            pw.print(num);
16401            pw.print(": ");
16402            pw.print(oomAdj);
16403            pw.print(' ');
16404            pw.print(schedGroup);
16405            pw.print('/');
16406            pw.print(foreground);
16407            pw.print('/');
16408            pw.print(procState);
16409            pw.print(" trm:");
16410            if (r.trimMemoryLevel < 10) pw.print(' ');
16411            pw.print(r.trimMemoryLevel);
16412            pw.print(' ');
16413            pw.print(r.toShortString());
16414            pw.print(" (");
16415            pw.print(r.adjType);
16416            pw.println(')');
16417            if (r.adjSource != null || r.adjTarget != null) {
16418                pw.print(prefix);
16419                pw.print("    ");
16420                if (r.adjTarget instanceof ComponentName) {
16421                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16422                } else if (r.adjTarget != null) {
16423                    pw.print(r.adjTarget.toString());
16424                } else {
16425                    pw.print("{null}");
16426                }
16427                pw.print("<=");
16428                if (r.adjSource instanceof ProcessRecord) {
16429                    pw.print("Proc{");
16430                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16431                    pw.println("}");
16432                } else if (r.adjSource != null) {
16433                    pw.println(r.adjSource.toString());
16434                } else {
16435                    pw.println("{null}");
16436                }
16437            }
16438            if (inclDetails) {
16439                pw.print(prefix);
16440                pw.print("    ");
16441                pw.print("oom: max="); pw.print(r.maxAdj);
16442                pw.print(" curRaw="); pw.print(r.curRawAdj);
16443                pw.print(" setRaw="); pw.print(r.setRawAdj);
16444                pw.print(" cur="); pw.print(r.curAdj);
16445                pw.print(" set="); pw.println(r.setAdj);
16446                pw.print(prefix);
16447                pw.print("    ");
16448                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16449                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16450                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16451                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16452                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16453                pw.println();
16454                pw.print(prefix);
16455                pw.print("    ");
16456                pw.print("cached="); pw.print(r.cached);
16457                pw.print(" empty="); pw.print(r.empty);
16458                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16459
16460                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16461                    if (r.lastWakeTime != 0) {
16462                        long wtime;
16463                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16464                        synchronized (stats) {
16465                            wtime = stats.getProcessWakeTime(r.info.uid,
16466                                    r.pid, curRealtime);
16467                        }
16468                        long timeUsed = wtime - r.lastWakeTime;
16469                        pw.print(prefix);
16470                        pw.print("    ");
16471                        pw.print("keep awake over ");
16472                        TimeUtils.formatDuration(realtimeSince, pw);
16473                        pw.print(" used ");
16474                        TimeUtils.formatDuration(timeUsed, pw);
16475                        pw.print(" (");
16476                        pw.print((timeUsed*100)/realtimeSince);
16477                        pw.println("%)");
16478                    }
16479                    if (r.lastCpuTime != 0) {
16480                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16481                        pw.print(prefix);
16482                        pw.print("    ");
16483                        pw.print("run cpu over ");
16484                        TimeUtils.formatDuration(uptimeSince, pw);
16485                        pw.print(" used ");
16486                        TimeUtils.formatDuration(timeUsed, pw);
16487                        pw.print(" (");
16488                        pw.print((timeUsed*100)/uptimeSince);
16489                        pw.println("%)");
16490                    }
16491                }
16492            }
16493        }
16494        return true;
16495    }
16496
16497    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16498            String[] args) {
16499        ArrayList<ProcessRecord> procs;
16500        synchronized (this) {
16501            if (args != null && args.length > start
16502                    && args[start].charAt(0) != '-') {
16503                procs = new ArrayList<ProcessRecord>();
16504                int pid = -1;
16505                try {
16506                    pid = Integer.parseInt(args[start]);
16507                } catch (NumberFormatException e) {
16508                }
16509                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16510                    ProcessRecord proc = mLruProcesses.get(i);
16511                    if (proc.pid == pid) {
16512                        procs.add(proc);
16513                    } else if (allPkgs && proc.pkgList != null
16514                            && proc.pkgList.containsKey(args[start])) {
16515                        procs.add(proc);
16516                    } else if (proc.processName.equals(args[start])) {
16517                        procs.add(proc);
16518                    }
16519                }
16520                if (procs.size() <= 0) {
16521                    return null;
16522                }
16523            } else {
16524                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16525            }
16526        }
16527        return procs;
16528    }
16529
16530    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16531            PrintWriter pw, String[] args) {
16532        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16533        if (procs == null) {
16534            pw.println("No process found for: " + args[0]);
16535            return;
16536        }
16537
16538        long uptime = SystemClock.uptimeMillis();
16539        long realtime = SystemClock.elapsedRealtime();
16540        pw.println("Applications Graphics Acceleration Info:");
16541        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16542
16543        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16544            ProcessRecord r = procs.get(i);
16545            if (r.thread != null) {
16546                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16547                pw.flush();
16548                try {
16549                    TransferPipe tp = new TransferPipe();
16550                    try {
16551                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16552                        tp.go(fd);
16553                    } finally {
16554                        tp.kill();
16555                    }
16556                } catch (IOException e) {
16557                    pw.println("Failure while dumping the app: " + r);
16558                    pw.flush();
16559                } catch (RemoteException e) {
16560                    pw.println("Got a RemoteException while dumping the app " + r);
16561                    pw.flush();
16562                }
16563            }
16564        }
16565    }
16566
16567    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16568        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16569        if (procs == null) {
16570            pw.println("No process found for: " + args[0]);
16571            return;
16572        }
16573
16574        pw.println("Applications Database Info:");
16575
16576        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16577            ProcessRecord r = procs.get(i);
16578            if (r.thread != null) {
16579                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16580                pw.flush();
16581                try {
16582                    TransferPipe tp = new TransferPipe();
16583                    try {
16584                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16585                        tp.go(fd);
16586                    } finally {
16587                        tp.kill();
16588                    }
16589                } catch (IOException e) {
16590                    pw.println("Failure while dumping the app: " + r);
16591                    pw.flush();
16592                } catch (RemoteException e) {
16593                    pw.println("Got a RemoteException while dumping the app " + r);
16594                    pw.flush();
16595                }
16596            }
16597        }
16598    }
16599
16600    final static class MemItem {
16601        final boolean isProc;
16602        final String label;
16603        final String shortLabel;
16604        final long pss;
16605        final long swapPss;
16606        final int id;
16607        final boolean hasActivities;
16608        ArrayList<MemItem> subitems;
16609
16610        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16611                boolean _hasActivities) {
16612            isProc = true;
16613            label = _label;
16614            shortLabel = _shortLabel;
16615            pss = _pss;
16616            swapPss = _swapPss;
16617            id = _id;
16618            hasActivities = _hasActivities;
16619        }
16620
16621        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16622            isProc = false;
16623            label = _label;
16624            shortLabel = _shortLabel;
16625            pss = _pss;
16626            swapPss = _swapPss;
16627            id = _id;
16628            hasActivities = false;
16629        }
16630    }
16631
16632    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16633            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16634        if (sort && !isCompact) {
16635            Collections.sort(items, new Comparator<MemItem>() {
16636                @Override
16637                public int compare(MemItem lhs, MemItem rhs) {
16638                    if (lhs.pss < rhs.pss) {
16639                        return 1;
16640                    } else if (lhs.pss > rhs.pss) {
16641                        return -1;
16642                    }
16643                    return 0;
16644                }
16645            });
16646        }
16647
16648        for (int i=0; i<items.size(); i++) {
16649            MemItem mi = items.get(i);
16650            if (!isCompact) {
16651                if (dumpSwapPss) {
16652                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16653                            mi.label, stringifyKBSize(mi.swapPss));
16654                } else {
16655                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16656                }
16657            } else if (mi.isProc) {
16658                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16659                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16660                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16661                pw.println(mi.hasActivities ? ",a" : ",e");
16662            } else {
16663                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16664                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16665            }
16666            if (mi.subitems != null) {
16667                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16668                        true, isCompact, dumpSwapPss);
16669            }
16670        }
16671    }
16672
16673    // These are in KB.
16674    static final long[] DUMP_MEM_BUCKETS = new long[] {
16675        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16676        120*1024, 160*1024, 200*1024,
16677        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16678        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16679    };
16680
16681    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16682            boolean stackLike) {
16683        int start = label.lastIndexOf('.');
16684        if (start >= 0) start++;
16685        else start = 0;
16686        int end = label.length();
16687        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16688            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16689                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16690                out.append(bucket);
16691                out.append(stackLike ? "MB." : "MB ");
16692                out.append(label, start, end);
16693                return;
16694            }
16695        }
16696        out.append(memKB/1024);
16697        out.append(stackLike ? "MB." : "MB ");
16698        out.append(label, start, end);
16699    }
16700
16701    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16702            ProcessList.NATIVE_ADJ,
16703            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16704            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16705            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16706            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16707            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16708            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16709    };
16710    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16711            "Native",
16712            "System", "Persistent", "Persistent Service", "Foreground",
16713            "Visible", "Perceptible",
16714            "Heavy Weight", "Backup",
16715            "A Services", "Home",
16716            "Previous", "B Services", "Cached"
16717    };
16718    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16719            "native",
16720            "sys", "pers", "persvc", "fore",
16721            "vis", "percept",
16722            "heavy", "backup",
16723            "servicea", "home",
16724            "prev", "serviceb", "cached"
16725    };
16726
16727    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16728            long realtime, boolean isCheckinRequest, boolean isCompact) {
16729        if (isCompact) {
16730            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16731        }
16732        if (isCheckinRequest || isCompact) {
16733            // short checkin version
16734            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16735        } else {
16736            pw.println("Applications Memory Usage (in Kilobytes):");
16737            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16738        }
16739    }
16740
16741    private static final int KSM_SHARED = 0;
16742    private static final int KSM_SHARING = 1;
16743    private static final int KSM_UNSHARED = 2;
16744    private static final int KSM_VOLATILE = 3;
16745
16746    private final long[] getKsmInfo() {
16747        long[] longOut = new long[4];
16748        final int[] SINGLE_LONG_FORMAT = new int[] {
16749            PROC_SPACE_TERM| PROC_OUT_LONG
16750        };
16751        long[] longTmp = new long[1];
16752        readProcFile("/sys/kernel/mm/ksm/pages_shared",
16753                SINGLE_LONG_FORMAT, null, longTmp, null);
16754        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16755        longTmp[0] = 0;
16756        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16757                SINGLE_LONG_FORMAT, null, longTmp, null);
16758        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16759        longTmp[0] = 0;
16760        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16761                SINGLE_LONG_FORMAT, null, longTmp, null);
16762        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16763        longTmp[0] = 0;
16764        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16765                SINGLE_LONG_FORMAT, null, longTmp, null);
16766        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16767        return longOut;
16768    }
16769
16770    private static String stringifySize(long size, int order) {
16771        Locale locale = Locale.US;
16772        switch (order) {
16773            case 1:
16774                return String.format(locale, "%,13d", size);
16775            case 1024:
16776                return String.format(locale, "%,9dK", size / 1024);
16777            case 1024 * 1024:
16778                return String.format(locale, "%,5dM", size / 1024 / 1024);
16779            case 1024 * 1024 * 1024:
16780                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16781            default:
16782                throw new IllegalArgumentException("Invalid size order");
16783        }
16784    }
16785
16786    private static String stringifyKBSize(long size) {
16787        return stringifySize(size * 1024, 1024);
16788    }
16789
16790    // Update this version number in case you change the 'compact' format
16791    private static final int MEMINFO_COMPACT_VERSION = 1;
16792
16793    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16794            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16795        boolean dumpDetails = false;
16796        boolean dumpFullDetails = false;
16797        boolean dumpDalvik = false;
16798        boolean dumpSummaryOnly = false;
16799        boolean dumpUnreachable = false;
16800        boolean oomOnly = false;
16801        boolean isCompact = false;
16802        boolean localOnly = false;
16803        boolean packages = false;
16804        boolean isCheckinRequest = false;
16805        boolean dumpSwapPss = false;
16806
16807        int opti = 0;
16808        while (opti < args.length) {
16809            String opt = args[opti];
16810            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16811                break;
16812            }
16813            opti++;
16814            if ("-a".equals(opt)) {
16815                dumpDetails = true;
16816                dumpFullDetails = true;
16817                dumpDalvik = true;
16818                dumpSwapPss = true;
16819            } else if ("-d".equals(opt)) {
16820                dumpDalvik = true;
16821            } else if ("-c".equals(opt)) {
16822                isCompact = true;
16823            } else if ("-s".equals(opt)) {
16824                dumpDetails = true;
16825                dumpSummaryOnly = true;
16826            } else if ("-S".equals(opt)) {
16827                dumpSwapPss = true;
16828            } else if ("--unreachable".equals(opt)) {
16829                dumpUnreachable = true;
16830            } else if ("--oom".equals(opt)) {
16831                oomOnly = true;
16832            } else if ("--local".equals(opt)) {
16833                localOnly = true;
16834            } else if ("--package".equals(opt)) {
16835                packages = true;
16836            } else if ("--checkin".equals(opt)) {
16837                isCheckinRequest = true;
16838
16839            } else if ("-h".equals(opt)) {
16840                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16841                pw.println("  -a: include all available information for each process.");
16842                pw.println("  -d: include dalvik details.");
16843                pw.println("  -c: dump in a compact machine-parseable representation.");
16844                pw.println("  -s: dump only summary of application memory usage.");
16845                pw.println("  -S: dump also SwapPss.");
16846                pw.println("  --oom: only show processes organized by oom adj.");
16847                pw.println("  --local: only collect details locally, don't call process.");
16848                pw.println("  --package: interpret process arg as package, dumping all");
16849                pw.println("             processes that have loaded that package.");
16850                pw.println("  --checkin: dump data for a checkin");
16851                pw.println("If [process] is specified it can be the name or ");
16852                pw.println("pid of a specific process to dump.");
16853                return;
16854            } else {
16855                pw.println("Unknown argument: " + opt + "; use -h for help");
16856            }
16857        }
16858
16859        long uptime = SystemClock.uptimeMillis();
16860        long realtime = SystemClock.elapsedRealtime();
16861        final long[] tmpLong = new long[1];
16862
16863        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16864        if (procs == null) {
16865            // No Java processes.  Maybe they want to print a native process.
16866            if (args != null && args.length > opti
16867                    && args[opti].charAt(0) != '-') {
16868                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16869                        = new ArrayList<ProcessCpuTracker.Stats>();
16870                updateCpuStatsNow();
16871                int findPid = -1;
16872                try {
16873                    findPid = Integer.parseInt(args[opti]);
16874                } catch (NumberFormatException e) {
16875                }
16876                synchronized (mProcessCpuTracker) {
16877                    final int N = mProcessCpuTracker.countStats();
16878                    for (int i=0; i<N; i++) {
16879                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16880                        if (st.pid == findPid || (st.baseName != null
16881                                && st.baseName.equals(args[opti]))) {
16882                            nativeProcs.add(st);
16883                        }
16884                    }
16885                }
16886                if (nativeProcs.size() > 0) {
16887                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16888                            isCompact);
16889                    Debug.MemoryInfo mi = null;
16890                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16891                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16892                        final int pid = r.pid;
16893                        if (!isCheckinRequest && dumpDetails) {
16894                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16895                        }
16896                        if (mi == null) {
16897                            mi = new Debug.MemoryInfo();
16898                        }
16899                        if (dumpDetails || (!brief && !oomOnly)) {
16900                            Debug.getMemoryInfo(pid, mi);
16901                        } else {
16902                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16903                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16904                        }
16905                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16906                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16907                        if (isCheckinRequest) {
16908                            pw.println();
16909                        }
16910                    }
16911                    return;
16912                }
16913            }
16914            pw.println("No process found for: " + args[opti]);
16915            return;
16916        }
16917
16918        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16919            dumpDetails = true;
16920        }
16921
16922        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16923
16924        String[] innerArgs = new String[args.length-opti];
16925        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16926
16927        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16928        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16929        long nativePss = 0;
16930        long nativeSwapPss = 0;
16931        long dalvikPss = 0;
16932        long dalvikSwapPss = 0;
16933        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16934                EmptyArray.LONG;
16935        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16936                EmptyArray.LONG;
16937        long otherPss = 0;
16938        long otherSwapPss = 0;
16939        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16940        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16941
16942        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16943        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16944        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16945                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16946
16947        long totalPss = 0;
16948        long totalSwapPss = 0;
16949        long cachedPss = 0;
16950        long cachedSwapPss = 0;
16951        boolean hasSwapPss = false;
16952
16953        Debug.MemoryInfo mi = null;
16954        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16955            final ProcessRecord r = procs.get(i);
16956            final IApplicationThread thread;
16957            final int pid;
16958            final int oomAdj;
16959            final boolean hasActivities;
16960            synchronized (this) {
16961                thread = r.thread;
16962                pid = r.pid;
16963                oomAdj = r.getSetAdjWithServices();
16964                hasActivities = r.activities.size() > 0;
16965            }
16966            if (thread != null) {
16967                if (!isCheckinRequest && dumpDetails) {
16968                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16969                }
16970                if (mi == null) {
16971                    mi = new Debug.MemoryInfo();
16972                }
16973                if (dumpDetails || (!brief && !oomOnly)) {
16974                    Debug.getMemoryInfo(pid, mi);
16975                    hasSwapPss = mi.hasSwappedOutPss;
16976                } else {
16977                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16978                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16979                }
16980                if (dumpDetails) {
16981                    if (localOnly) {
16982                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16983                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16984                        if (isCheckinRequest) {
16985                            pw.println();
16986                        }
16987                    } else {
16988                        pw.flush();
16989                        try {
16990                            TransferPipe tp = new TransferPipe();
16991                            try {
16992                                thread.dumpMemInfo(tp.getWriteFd(),
16993                                        mi, isCheckinRequest, dumpFullDetails,
16994                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16995                                tp.go(fd);
16996                            } finally {
16997                                tp.kill();
16998                            }
16999                        } catch (IOException e) {
17000                            if (!isCheckinRequest) {
17001                                pw.println("Got IoException!");
17002                                pw.flush();
17003                            }
17004                        } catch (RemoteException e) {
17005                            if (!isCheckinRequest) {
17006                                pw.println("Got RemoteException!");
17007                                pw.flush();
17008                            }
17009                        }
17010                    }
17011                }
17012
17013                final long myTotalPss = mi.getTotalPss();
17014                final long myTotalUss = mi.getTotalUss();
17015                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17016
17017                synchronized (this) {
17018                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17019                        // Record this for posterity if the process has been stable.
17020                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17021                    }
17022                }
17023
17024                if (!isCheckinRequest && mi != null) {
17025                    totalPss += myTotalPss;
17026                    totalSwapPss += myTotalSwapPss;
17027                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17028                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17029                            myTotalSwapPss, pid, hasActivities);
17030                    procMems.add(pssItem);
17031                    procMemsMap.put(pid, pssItem);
17032
17033                    nativePss += mi.nativePss;
17034                    nativeSwapPss += mi.nativeSwappedOutPss;
17035                    dalvikPss += mi.dalvikPss;
17036                    dalvikSwapPss += mi.dalvikSwappedOutPss;
17037                    for (int j=0; j<dalvikSubitemPss.length; j++) {
17038                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17039                        dalvikSubitemSwapPss[j] +=
17040                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17041                    }
17042                    otherPss += mi.otherPss;
17043                    otherSwapPss += mi.otherSwappedOutPss;
17044                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17045                        long mem = mi.getOtherPss(j);
17046                        miscPss[j] += mem;
17047                        otherPss -= mem;
17048                        mem = mi.getOtherSwappedOutPss(j);
17049                        miscSwapPss[j] += mem;
17050                        otherSwapPss -= mem;
17051                    }
17052
17053                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17054                        cachedPss += myTotalPss;
17055                        cachedSwapPss += myTotalSwapPss;
17056                    }
17057
17058                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17059                        if (oomIndex == (oomPss.length - 1)
17060                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17061                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17062                            oomPss[oomIndex] += myTotalPss;
17063                            oomSwapPss[oomIndex] += myTotalSwapPss;
17064                            if (oomProcs[oomIndex] == null) {
17065                                oomProcs[oomIndex] = new ArrayList<MemItem>();
17066                            }
17067                            oomProcs[oomIndex].add(pssItem);
17068                            break;
17069                        }
17070                    }
17071                }
17072            }
17073        }
17074
17075        long nativeProcTotalPss = 0;
17076
17077        if (!isCheckinRequest && procs.size() > 1 && !packages) {
17078            // If we are showing aggregations, also look for native processes to
17079            // include so that our aggregations are more accurate.
17080            updateCpuStatsNow();
17081            mi = null;
17082            synchronized (mProcessCpuTracker) {
17083                final int N = mProcessCpuTracker.countStats();
17084                for (int i=0; i<N; i++) {
17085                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17086                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17087                        if (mi == null) {
17088                            mi = new Debug.MemoryInfo();
17089                        }
17090                        if (!brief && !oomOnly) {
17091                            Debug.getMemoryInfo(st.pid, mi);
17092                        } else {
17093                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17094                            mi.nativePrivateDirty = (int)tmpLong[0];
17095                        }
17096
17097                        final long myTotalPss = mi.getTotalPss();
17098                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17099                        totalPss += myTotalPss;
17100                        nativeProcTotalPss += myTotalPss;
17101
17102                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17103                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17104                        procMems.add(pssItem);
17105
17106                        nativePss += mi.nativePss;
17107                        nativeSwapPss += mi.nativeSwappedOutPss;
17108                        dalvikPss += mi.dalvikPss;
17109                        dalvikSwapPss += mi.dalvikSwappedOutPss;
17110                        for (int j=0; j<dalvikSubitemPss.length; j++) {
17111                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17112                            dalvikSubitemSwapPss[j] +=
17113                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17114                        }
17115                        otherPss += mi.otherPss;
17116                        otherSwapPss += mi.otherSwappedOutPss;
17117                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17118                            long mem = mi.getOtherPss(j);
17119                            miscPss[j] += mem;
17120                            otherPss -= mem;
17121                            mem = mi.getOtherSwappedOutPss(j);
17122                            miscSwapPss[j] += mem;
17123                            otherSwapPss -= mem;
17124                        }
17125                        oomPss[0] += myTotalPss;
17126                        oomSwapPss[0] += myTotalSwapPss;
17127                        if (oomProcs[0] == null) {
17128                            oomProcs[0] = new ArrayList<MemItem>();
17129                        }
17130                        oomProcs[0].add(pssItem);
17131                    }
17132                }
17133            }
17134
17135            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17136
17137            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17138            final MemItem dalvikItem =
17139                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17140            if (dalvikSubitemPss.length > 0) {
17141                dalvikItem.subitems = new ArrayList<MemItem>();
17142                for (int j=0; j<dalvikSubitemPss.length; j++) {
17143                    final String name = Debug.MemoryInfo.getOtherLabel(
17144                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
17145                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17146                                    dalvikSubitemSwapPss[j], j));
17147                }
17148            }
17149            catMems.add(dalvikItem);
17150            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17151            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17152                String label = Debug.MemoryInfo.getOtherLabel(j);
17153                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17154            }
17155
17156            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17157            for (int j=0; j<oomPss.length; j++) {
17158                if (oomPss[j] != 0) {
17159                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17160                            : DUMP_MEM_OOM_LABEL[j];
17161                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17162                            DUMP_MEM_OOM_ADJ[j]);
17163                    item.subitems = oomProcs[j];
17164                    oomMems.add(item);
17165                }
17166            }
17167
17168            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17169            if (!brief && !oomOnly && !isCompact) {
17170                pw.println();
17171                pw.println("Total PSS by process:");
17172                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17173                pw.println();
17174            }
17175            if (!isCompact) {
17176                pw.println("Total PSS by OOM adjustment:");
17177            }
17178            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17179            if (!brief && !oomOnly) {
17180                PrintWriter out = categoryPw != null ? categoryPw : pw;
17181                if (!isCompact) {
17182                    out.println();
17183                    out.println("Total PSS by category:");
17184                }
17185                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17186            }
17187            if (!isCompact) {
17188                pw.println();
17189            }
17190            MemInfoReader memInfo = new MemInfoReader();
17191            memInfo.readMemInfo();
17192            if (nativeProcTotalPss > 0) {
17193                synchronized (this) {
17194                    final long cachedKb = memInfo.getCachedSizeKb();
17195                    final long freeKb = memInfo.getFreeSizeKb();
17196                    final long zramKb = memInfo.getZramTotalSizeKb();
17197                    final long kernelKb = memInfo.getKernelUsedSizeKb();
17198                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17199                            kernelKb*1024, nativeProcTotalPss*1024);
17200                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17201                            nativeProcTotalPss);
17202                }
17203            }
17204            if (!brief) {
17205                if (!isCompact) {
17206                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17207                    pw.print(" (status ");
17208                    switch (mLastMemoryLevel) {
17209                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17210                            pw.println("normal)");
17211                            break;
17212                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17213                            pw.println("moderate)");
17214                            break;
17215                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
17216                            pw.println("low)");
17217                            break;
17218                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17219                            pw.println("critical)");
17220                            break;
17221                        default:
17222                            pw.print(mLastMemoryLevel);
17223                            pw.println(")");
17224                            break;
17225                    }
17226                    pw.print(" Free RAM: ");
17227                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17228                            + memInfo.getFreeSizeKb()));
17229                    pw.print(" (");
17230                    pw.print(stringifyKBSize(cachedPss));
17231                    pw.print(" cached pss + ");
17232                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17233                    pw.print(" cached kernel + ");
17234                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17235                    pw.println(" free)");
17236                } else {
17237                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17238                    pw.print(cachedPss + memInfo.getCachedSizeKb()
17239                            + memInfo.getFreeSizeKb()); pw.print(",");
17240                    pw.println(totalPss - cachedPss);
17241                }
17242            }
17243            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17244                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17245                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17246            if (!isCompact) {
17247                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17248                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17249                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17250                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17251                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17252            } else {
17253                pw.print("lostram,"); pw.println(lostRAM);
17254            }
17255            if (!brief) {
17256                if (memInfo.getZramTotalSizeKb() != 0) {
17257                    if (!isCompact) {
17258                        pw.print("     ZRAM: ");
17259                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17260                                pw.print(" physical used for ");
17261                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17262                                        - memInfo.getSwapFreeSizeKb()));
17263                                pw.print(" in swap (");
17264                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17265                                pw.println(" total swap)");
17266                    } else {
17267                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17268                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17269                                pw.println(memInfo.getSwapFreeSizeKb());
17270                    }
17271                }
17272                final long[] ksm = getKsmInfo();
17273                if (!isCompact) {
17274                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17275                            || ksm[KSM_VOLATILE] != 0) {
17276                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17277                                pw.print(" saved from shared ");
17278                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17279                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17280                                pw.print(" unshared; ");
17281                                pw.print(stringifyKBSize(
17282                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
17283                    }
17284                    pw.print("   Tuning: ");
17285                    pw.print(ActivityManager.staticGetMemoryClass());
17286                    pw.print(" (large ");
17287                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17288                    pw.print("), oom ");
17289                    pw.print(stringifySize(
17290                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17291                    pw.print(", restore limit ");
17292                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17293                    if (ActivityManager.isLowRamDeviceStatic()) {
17294                        pw.print(" (low-ram)");
17295                    }
17296                    if (ActivityManager.isHighEndGfx()) {
17297                        pw.print(" (high-end-gfx)");
17298                    }
17299                    pw.println();
17300                } else {
17301                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17302                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17303                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17304                    pw.print("tuning,");
17305                    pw.print(ActivityManager.staticGetMemoryClass());
17306                    pw.print(',');
17307                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17308                    pw.print(',');
17309                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17310                    if (ActivityManager.isLowRamDeviceStatic()) {
17311                        pw.print(",low-ram");
17312                    }
17313                    if (ActivityManager.isHighEndGfx()) {
17314                        pw.print(",high-end-gfx");
17315                    }
17316                    pw.println();
17317                }
17318            }
17319        }
17320    }
17321
17322    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17323            long memtrack, String name) {
17324        sb.append("  ");
17325        sb.append(ProcessList.makeOomAdjString(oomAdj));
17326        sb.append(' ');
17327        sb.append(ProcessList.makeProcStateString(procState));
17328        sb.append(' ');
17329        ProcessList.appendRamKb(sb, pss);
17330        sb.append(": ");
17331        sb.append(name);
17332        if (memtrack > 0) {
17333            sb.append(" (");
17334            sb.append(stringifyKBSize(memtrack));
17335            sb.append(" memtrack)");
17336        }
17337    }
17338
17339    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17340        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17341        sb.append(" (pid ");
17342        sb.append(mi.pid);
17343        sb.append(") ");
17344        sb.append(mi.adjType);
17345        sb.append('\n');
17346        if (mi.adjReason != null) {
17347            sb.append("                      ");
17348            sb.append(mi.adjReason);
17349            sb.append('\n');
17350        }
17351    }
17352
17353    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17354        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17355        for (int i=0, N=memInfos.size(); i<N; i++) {
17356            ProcessMemInfo mi = memInfos.get(i);
17357            infoMap.put(mi.pid, mi);
17358        }
17359        updateCpuStatsNow();
17360        long[] memtrackTmp = new long[1];
17361        final List<ProcessCpuTracker.Stats> stats;
17362        // Get a list of Stats that have vsize > 0
17363        synchronized (mProcessCpuTracker) {
17364            stats = mProcessCpuTracker.getStats((st) -> {
17365                return st.vsize > 0;
17366            });
17367        }
17368        final int statsCount = stats.size();
17369        for (int i = 0; i < statsCount; i++) {
17370            ProcessCpuTracker.Stats st = stats.get(i);
17371            long pss = Debug.getPss(st.pid, null, memtrackTmp);
17372            if (pss > 0) {
17373                if (infoMap.indexOfKey(st.pid) < 0) {
17374                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17375                            ProcessList.NATIVE_ADJ, -1, "native", null);
17376                    mi.pss = pss;
17377                    mi.memtrack = memtrackTmp[0];
17378                    memInfos.add(mi);
17379                }
17380            }
17381        }
17382
17383        long totalPss = 0;
17384        long totalMemtrack = 0;
17385        for (int i=0, N=memInfos.size(); i<N; i++) {
17386            ProcessMemInfo mi = memInfos.get(i);
17387            if (mi.pss == 0) {
17388                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17389                mi.memtrack = memtrackTmp[0];
17390            }
17391            totalPss += mi.pss;
17392            totalMemtrack += mi.memtrack;
17393        }
17394        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17395            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17396                if (lhs.oomAdj != rhs.oomAdj) {
17397                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17398                }
17399                if (lhs.pss != rhs.pss) {
17400                    return lhs.pss < rhs.pss ? 1 : -1;
17401                }
17402                return 0;
17403            }
17404        });
17405
17406        StringBuilder tag = new StringBuilder(128);
17407        StringBuilder stack = new StringBuilder(128);
17408        tag.append("Low on memory -- ");
17409        appendMemBucket(tag, totalPss, "total", false);
17410        appendMemBucket(stack, totalPss, "total", true);
17411
17412        StringBuilder fullNativeBuilder = new StringBuilder(1024);
17413        StringBuilder shortNativeBuilder = new StringBuilder(1024);
17414        StringBuilder fullJavaBuilder = new StringBuilder(1024);
17415
17416        boolean firstLine = true;
17417        int lastOomAdj = Integer.MIN_VALUE;
17418        long extraNativeRam = 0;
17419        long extraNativeMemtrack = 0;
17420        long cachedPss = 0;
17421        for (int i=0, N=memInfos.size(); i<N; i++) {
17422            ProcessMemInfo mi = memInfos.get(i);
17423
17424            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17425                cachedPss += mi.pss;
17426            }
17427
17428            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17429                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17430                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17431                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17432                if (lastOomAdj != mi.oomAdj) {
17433                    lastOomAdj = mi.oomAdj;
17434                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17435                        tag.append(" / ");
17436                    }
17437                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17438                        if (firstLine) {
17439                            stack.append(":");
17440                            firstLine = false;
17441                        }
17442                        stack.append("\n\t at ");
17443                    } else {
17444                        stack.append("$");
17445                    }
17446                } else {
17447                    tag.append(" ");
17448                    stack.append("$");
17449                }
17450                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17451                    appendMemBucket(tag, mi.pss, mi.name, false);
17452                }
17453                appendMemBucket(stack, mi.pss, mi.name, true);
17454                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17455                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17456                    stack.append("(");
17457                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17458                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17459                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17460                            stack.append(":");
17461                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17462                        }
17463                    }
17464                    stack.append(")");
17465                }
17466            }
17467
17468            appendMemInfo(fullNativeBuilder, mi);
17469            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17470                // The short form only has native processes that are >= 512K.
17471                if (mi.pss >= 512) {
17472                    appendMemInfo(shortNativeBuilder, mi);
17473                } else {
17474                    extraNativeRam += mi.pss;
17475                    extraNativeMemtrack += mi.memtrack;
17476                }
17477            } else {
17478                // Short form has all other details, but if we have collected RAM
17479                // from smaller native processes let's dump a summary of that.
17480                if (extraNativeRam > 0) {
17481                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17482                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17483                    shortNativeBuilder.append('\n');
17484                    extraNativeRam = 0;
17485                }
17486                appendMemInfo(fullJavaBuilder, mi);
17487            }
17488        }
17489
17490        fullJavaBuilder.append("           ");
17491        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17492        fullJavaBuilder.append(": TOTAL");
17493        if (totalMemtrack > 0) {
17494            fullJavaBuilder.append(" (");
17495            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17496            fullJavaBuilder.append(" memtrack)");
17497        } else {
17498        }
17499        fullJavaBuilder.append("\n");
17500
17501        MemInfoReader memInfo = new MemInfoReader();
17502        memInfo.readMemInfo();
17503        final long[] infos = memInfo.getRawInfo();
17504
17505        StringBuilder memInfoBuilder = new StringBuilder(1024);
17506        Debug.getMemInfo(infos);
17507        memInfoBuilder.append("  MemInfo: ");
17508        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17509        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17510        memInfoBuilder.append(stringifyKBSize(
17511                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17512        memInfoBuilder.append(stringifyKBSize(
17513                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17514        memInfoBuilder.append(stringifyKBSize(
17515                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17516        memInfoBuilder.append("           ");
17517        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17518        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17519        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17520        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17521        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17522            memInfoBuilder.append("  ZRAM: ");
17523            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17524            memInfoBuilder.append(" RAM, ");
17525            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17526            memInfoBuilder.append(" swap total, ");
17527            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17528            memInfoBuilder.append(" swap free\n");
17529        }
17530        final long[] ksm = getKsmInfo();
17531        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17532                || ksm[KSM_VOLATILE] != 0) {
17533            memInfoBuilder.append("  KSM: ");
17534            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17535            memInfoBuilder.append(" saved from shared ");
17536            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17537            memInfoBuilder.append("\n       ");
17538            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17539            memInfoBuilder.append(" unshared; ");
17540            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17541            memInfoBuilder.append(" volatile\n");
17542        }
17543        memInfoBuilder.append("  Free RAM: ");
17544        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17545                + memInfo.getFreeSizeKb()));
17546        memInfoBuilder.append("\n");
17547        memInfoBuilder.append("  Used RAM: ");
17548        memInfoBuilder.append(stringifyKBSize(
17549                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17550        memInfoBuilder.append("\n");
17551        memInfoBuilder.append("  Lost RAM: ");
17552        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17553                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17554                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17555        memInfoBuilder.append("\n");
17556        Slog.i(TAG, "Low on memory:");
17557        Slog.i(TAG, shortNativeBuilder.toString());
17558        Slog.i(TAG, fullJavaBuilder.toString());
17559        Slog.i(TAG, memInfoBuilder.toString());
17560
17561        StringBuilder dropBuilder = new StringBuilder(1024);
17562        /*
17563        StringWriter oomSw = new StringWriter();
17564        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17565        StringWriter catSw = new StringWriter();
17566        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17567        String[] emptyArgs = new String[] { };
17568        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17569        oomPw.flush();
17570        String oomString = oomSw.toString();
17571        */
17572        dropBuilder.append("Low on memory:");
17573        dropBuilder.append(stack);
17574        dropBuilder.append('\n');
17575        dropBuilder.append(fullNativeBuilder);
17576        dropBuilder.append(fullJavaBuilder);
17577        dropBuilder.append('\n');
17578        dropBuilder.append(memInfoBuilder);
17579        dropBuilder.append('\n');
17580        /*
17581        dropBuilder.append(oomString);
17582        dropBuilder.append('\n');
17583        */
17584        StringWriter catSw = new StringWriter();
17585        synchronized (ActivityManagerService.this) {
17586            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17587            String[] emptyArgs = new String[] { };
17588            catPw.println();
17589            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17590            catPw.println();
17591            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17592                    false, null).dumpLocked();
17593            catPw.println();
17594            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17595            catPw.flush();
17596        }
17597        dropBuilder.append(catSw.toString());
17598        addErrorToDropBox("lowmem", null, "system_server", null,
17599                null, tag.toString(), dropBuilder.toString(), null, null);
17600        //Slog.i(TAG, "Sent to dropbox:");
17601        //Slog.i(TAG, dropBuilder.toString());
17602        synchronized (ActivityManagerService.this) {
17603            long now = SystemClock.uptimeMillis();
17604            if (mLastMemUsageReportTime < now) {
17605                mLastMemUsageReportTime = now;
17606            }
17607        }
17608    }
17609
17610    /**
17611     * Searches array of arguments for the specified string
17612     * @param args array of argument strings
17613     * @param value value to search for
17614     * @return true if the value is contained in the array
17615     */
17616    private static boolean scanArgs(String[] args, String value) {
17617        if (args != null) {
17618            for (String arg : args) {
17619                if (value.equals(arg)) {
17620                    return true;
17621                }
17622            }
17623        }
17624        return false;
17625    }
17626
17627    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17628            ContentProviderRecord cpr, boolean always) {
17629        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17630
17631        if (!inLaunching || always) {
17632            synchronized (cpr) {
17633                cpr.launchingApp = null;
17634                cpr.notifyAll();
17635            }
17636            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17637            String names[] = cpr.info.authority.split(";");
17638            for (int j = 0; j < names.length; j++) {
17639                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17640            }
17641        }
17642
17643        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17644            ContentProviderConnection conn = cpr.connections.get(i);
17645            if (conn.waiting) {
17646                // If this connection is waiting for the provider, then we don't
17647                // need to mess with its process unless we are always removing
17648                // or for some reason the provider is not currently launching.
17649                if (inLaunching && !always) {
17650                    continue;
17651                }
17652            }
17653            ProcessRecord capp = conn.client;
17654            conn.dead = true;
17655            if (conn.stableCount > 0) {
17656                if (!capp.persistent && capp.thread != null
17657                        && capp.pid != 0
17658                        && capp.pid != MY_PID) {
17659                    capp.kill("depends on provider "
17660                            + cpr.name.flattenToShortString()
17661                            + " in dying proc " + (proc != null ? proc.processName : "??")
17662                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17663                }
17664            } else if (capp.thread != null && conn.provider.provider != null) {
17665                try {
17666                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17667                } catch (RemoteException e) {
17668                }
17669                // In the protocol here, we don't expect the client to correctly
17670                // clean up this connection, we'll just remove it.
17671                cpr.connections.remove(i);
17672                if (conn.client.conProviders.remove(conn)) {
17673                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17674                }
17675            }
17676        }
17677
17678        if (inLaunching && always) {
17679            mLaunchingProviders.remove(cpr);
17680        }
17681        return inLaunching;
17682    }
17683
17684    /**
17685     * Main code for cleaning up a process when it has gone away.  This is
17686     * called both as a result of the process dying, or directly when stopping
17687     * a process when running in single process mode.
17688     *
17689     * @return Returns true if the given process has been restarted, so the
17690     * app that was passed in must remain on the process lists.
17691     */
17692    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17693            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17694        if (index >= 0) {
17695            removeLruProcessLocked(app);
17696            ProcessList.remove(app.pid);
17697        }
17698
17699        mProcessesToGc.remove(app);
17700        mPendingPssProcesses.remove(app);
17701
17702        // Dismiss any open dialogs.
17703        if (app.crashDialog != null && !app.forceCrashReport) {
17704            app.crashDialog.dismiss();
17705            app.crashDialog = null;
17706        }
17707        if (app.anrDialog != null) {
17708            app.anrDialog.dismiss();
17709            app.anrDialog = null;
17710        }
17711        if (app.waitDialog != null) {
17712            app.waitDialog.dismiss();
17713            app.waitDialog = null;
17714        }
17715
17716        app.crashing = false;
17717        app.notResponding = false;
17718
17719        app.resetPackageList(mProcessStats);
17720        app.unlinkDeathRecipient();
17721        app.makeInactive(mProcessStats);
17722        app.waitingToKill = null;
17723        app.forcingToForeground = null;
17724        updateProcessForegroundLocked(app, false, false);
17725        app.foregroundActivities = false;
17726        app.hasShownUi = false;
17727        app.treatLikeActivity = false;
17728        app.hasAboveClient = false;
17729        app.hasClientActivities = false;
17730
17731        mServices.killServicesLocked(app, allowRestart);
17732
17733        boolean restart = false;
17734
17735        // Remove published content providers.
17736        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17737            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17738            final boolean always = app.bad || !allowRestart;
17739            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17740            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17741                // We left the provider in the launching list, need to
17742                // restart it.
17743                restart = true;
17744            }
17745
17746            cpr.provider = null;
17747            cpr.proc = null;
17748        }
17749        app.pubProviders.clear();
17750
17751        // Take care of any launching providers waiting for this process.
17752        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17753            restart = true;
17754        }
17755
17756        // Unregister from connected content providers.
17757        if (!app.conProviders.isEmpty()) {
17758            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17759                ContentProviderConnection conn = app.conProviders.get(i);
17760                conn.provider.connections.remove(conn);
17761                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17762                        conn.provider.name);
17763            }
17764            app.conProviders.clear();
17765        }
17766
17767        // At this point there may be remaining entries in mLaunchingProviders
17768        // where we were the only one waiting, so they are no longer of use.
17769        // Look for these and clean up if found.
17770        // XXX Commented out for now.  Trying to figure out a way to reproduce
17771        // the actual situation to identify what is actually going on.
17772        if (false) {
17773            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17774                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17775                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17776                    synchronized (cpr) {
17777                        cpr.launchingApp = null;
17778                        cpr.notifyAll();
17779                    }
17780                }
17781            }
17782        }
17783
17784        skipCurrentReceiverLocked(app);
17785
17786        // Unregister any receivers.
17787        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17788            removeReceiverLocked(app.receivers.valueAt(i));
17789        }
17790        app.receivers.clear();
17791
17792        // If the app is undergoing backup, tell the backup manager about it
17793        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17794            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17795                    + mBackupTarget.appInfo + " died during backup");
17796            mHandler.post(new Runnable() {
17797                @Override
17798                public void run(){
17799                    try {
17800                        IBackupManager bm = IBackupManager.Stub.asInterface(
17801                                ServiceManager.getService(Context.BACKUP_SERVICE));
17802                        bm.agentDisconnected(app.info.packageName);
17803                    } catch (RemoteException e) {
17804                        // can't happen; backup manager is local
17805                    }
17806                }
17807            });
17808        }
17809
17810        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17811            ProcessChangeItem item = mPendingProcessChanges.get(i);
17812            if (item.pid == app.pid) {
17813                mPendingProcessChanges.remove(i);
17814                mAvailProcessChanges.add(item);
17815            }
17816        }
17817        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17818                null).sendToTarget();
17819
17820        // If the caller is restarting this app, then leave it in its
17821        // current lists and let the caller take care of it.
17822        if (restarting) {
17823            return false;
17824        }
17825
17826        if (!app.persistent || app.isolated) {
17827            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17828                    "Removing non-persistent process during cleanup: " + app);
17829            if (!replacingPid) {
17830                removeProcessNameLocked(app.processName, app.uid, app);
17831            }
17832            if (mHeavyWeightProcess == app) {
17833                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17834                        mHeavyWeightProcess.userId, 0));
17835                mHeavyWeightProcess = null;
17836            }
17837        } else if (!app.removed) {
17838            // This app is persistent, so we need to keep its record around.
17839            // If it is not already on the pending app list, add it there
17840            // and start a new process for it.
17841            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17842                mPersistentStartingProcesses.add(app);
17843                restart = true;
17844            }
17845        }
17846        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17847                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17848        mProcessesOnHold.remove(app);
17849
17850        if (app == mHomeProcess) {
17851            mHomeProcess = null;
17852        }
17853        if (app == mPreviousProcess) {
17854            mPreviousProcess = null;
17855        }
17856
17857        if (restart && !app.isolated) {
17858            // We have components that still need to be running in the
17859            // process, so re-launch it.
17860            if (index < 0) {
17861                ProcessList.remove(app.pid);
17862            }
17863            addProcessNameLocked(app);
17864            startProcessLocked(app, "restart", app.processName);
17865            return true;
17866        } else if (app.pid > 0 && app.pid != MY_PID) {
17867            // Goodbye!
17868            boolean removed;
17869            synchronized (mPidsSelfLocked) {
17870                mPidsSelfLocked.remove(app.pid);
17871                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17872            }
17873            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17874            if (app.isolated) {
17875                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17876            }
17877            app.setPid(0);
17878        }
17879        return false;
17880    }
17881
17882    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17883        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17884            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17885            if (cpr.launchingApp == app) {
17886                return true;
17887            }
17888        }
17889        return false;
17890    }
17891
17892    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17893        // Look through the content providers we are waiting to have launched,
17894        // and if any run in this process then either schedule a restart of
17895        // the process or kill the client waiting for it if this process has
17896        // gone bad.
17897        boolean restart = false;
17898        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17899            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17900            if (cpr.launchingApp == app) {
17901                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17902                    restart = true;
17903                } else {
17904                    removeDyingProviderLocked(app, cpr, true);
17905                }
17906            }
17907        }
17908        return restart;
17909    }
17910
17911    // =========================================================
17912    // SERVICES
17913    // =========================================================
17914
17915    @Override
17916    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17917            int flags) {
17918        enforceNotIsolatedCaller("getServices");
17919
17920        final int callingUid = Binder.getCallingUid();
17921        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
17922            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
17923        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
17924            callingUid);
17925        synchronized (this) {
17926            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
17927                allowed, canInteractAcrossUsers);
17928        }
17929    }
17930
17931    @Override
17932    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17933        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17934        synchronized (this) {
17935            return mServices.getRunningServiceControlPanelLocked(name);
17936        }
17937    }
17938
17939    @Override
17940    public ComponentName startService(IApplicationThread caller, Intent service,
17941            String resolvedType, boolean requireForeground, String callingPackage, int userId)
17942            throws TransactionTooLargeException {
17943        enforceNotIsolatedCaller("startService");
17944        // Refuse possible leaked file descriptors
17945        if (service != null && service.hasFileDescriptors() == true) {
17946            throw new IllegalArgumentException("File descriptors passed in Intent");
17947        }
17948
17949        if (callingPackage == null) {
17950            throw new IllegalArgumentException("callingPackage cannot be null");
17951        }
17952
17953        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17954                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
17955        synchronized(this) {
17956            final int callingPid = Binder.getCallingPid();
17957            final int callingUid = Binder.getCallingUid();
17958            final long origId = Binder.clearCallingIdentity();
17959            ComponentName res;
17960            try {
17961                res = mServices.startServiceLocked(caller, service,
17962                        resolvedType, callingPid, callingUid,
17963                        requireForeground, callingPackage, userId);
17964            } finally {
17965                Binder.restoreCallingIdentity(origId);
17966            }
17967            return res;
17968        }
17969    }
17970
17971    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17972            boolean fgRequired, String callingPackage, int userId)
17973            throws TransactionTooLargeException {
17974        synchronized(this) {
17975            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17976                    "startServiceInPackage: " + service + " type=" + resolvedType);
17977            final long origId = Binder.clearCallingIdentity();
17978            ComponentName res;
17979            try {
17980                res = mServices.startServiceLocked(null, service,
17981                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
17982            } finally {
17983                Binder.restoreCallingIdentity(origId);
17984            }
17985            return res;
17986        }
17987    }
17988
17989    @Override
17990    public int stopService(IApplicationThread caller, Intent service,
17991            String resolvedType, int userId) {
17992        enforceNotIsolatedCaller("stopService");
17993        // Refuse possible leaked file descriptors
17994        if (service != null && service.hasFileDescriptors() == true) {
17995            throw new IllegalArgumentException("File descriptors passed in Intent");
17996        }
17997
17998        synchronized(this) {
17999            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18000        }
18001    }
18002
18003    @Override
18004    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18005        enforceNotIsolatedCaller("peekService");
18006        // Refuse possible leaked file descriptors
18007        if (service != null && service.hasFileDescriptors() == true) {
18008            throw new IllegalArgumentException("File descriptors passed in Intent");
18009        }
18010
18011        if (callingPackage == null) {
18012            throw new IllegalArgumentException("callingPackage cannot be null");
18013        }
18014
18015        synchronized(this) {
18016            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18017        }
18018    }
18019
18020    @Override
18021    public boolean stopServiceToken(ComponentName className, IBinder token,
18022            int startId) {
18023        synchronized(this) {
18024            return mServices.stopServiceTokenLocked(className, token, startId);
18025        }
18026    }
18027
18028    @Override
18029    public void setServiceForeground(ComponentName className, IBinder token,
18030            int id, Notification notification, int flags) {
18031        synchronized(this) {
18032            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18033        }
18034    }
18035
18036    @Override
18037    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18038            boolean requireFull, String name, String callerPackage) {
18039        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18040                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18041    }
18042
18043    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18044            String className, int flags) {
18045        boolean result = false;
18046        // For apps that don't have pre-defined UIDs, check for permission
18047        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18048            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18049                if (ActivityManager.checkUidPermission(
18050                        INTERACT_ACROSS_USERS,
18051                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18052                    ComponentName comp = new ComponentName(aInfo.packageName, className);
18053                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
18054                            + " requests FLAG_SINGLE_USER, but app does not hold "
18055                            + INTERACT_ACROSS_USERS;
18056                    Slog.w(TAG, msg);
18057                    throw new SecurityException(msg);
18058                }
18059                // Permission passed
18060                result = true;
18061            }
18062        } else if ("system".equals(componentProcessName)) {
18063            result = true;
18064        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18065            // Phone app and persistent apps are allowed to export singleuser providers.
18066            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18067                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18068        }
18069        if (DEBUG_MU) Slog.v(TAG_MU,
18070                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18071                + Integer.toHexString(flags) + ") = " + result);
18072        return result;
18073    }
18074
18075    /**
18076     * Checks to see if the caller is in the same app as the singleton
18077     * component, or the component is in a special app. It allows special apps
18078     * to export singleton components but prevents exporting singleton
18079     * components for regular apps.
18080     */
18081    boolean isValidSingletonCall(int callingUid, int componentUid) {
18082        int componentAppId = UserHandle.getAppId(componentUid);
18083        return UserHandle.isSameApp(callingUid, componentUid)
18084                || componentAppId == SYSTEM_UID
18085                || componentAppId == PHONE_UID
18086                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18087                        == PackageManager.PERMISSION_GRANTED;
18088    }
18089
18090    public int bindService(IApplicationThread caller, IBinder token, Intent service,
18091            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18092            int userId) throws TransactionTooLargeException {
18093        enforceNotIsolatedCaller("bindService");
18094
18095        // Refuse possible leaked file descriptors
18096        if (service != null && service.hasFileDescriptors() == true) {
18097            throw new IllegalArgumentException("File descriptors passed in Intent");
18098        }
18099
18100        if (callingPackage == null) {
18101            throw new IllegalArgumentException("callingPackage cannot be null");
18102        }
18103
18104        synchronized(this) {
18105            return mServices.bindServiceLocked(caller, token, service,
18106                    resolvedType, connection, flags, callingPackage, userId);
18107        }
18108    }
18109
18110    public boolean unbindService(IServiceConnection connection) {
18111        synchronized (this) {
18112            return mServices.unbindServiceLocked(connection);
18113        }
18114    }
18115
18116    public void publishService(IBinder token, Intent intent, IBinder service) {
18117        // Refuse possible leaked file descriptors
18118        if (intent != null && intent.hasFileDescriptors() == true) {
18119            throw new IllegalArgumentException("File descriptors passed in Intent");
18120        }
18121
18122        synchronized(this) {
18123            if (!(token instanceof ServiceRecord)) {
18124                throw new IllegalArgumentException("Invalid service token");
18125            }
18126            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18127        }
18128    }
18129
18130    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18131        // Refuse possible leaked file descriptors
18132        if (intent != null && intent.hasFileDescriptors() == true) {
18133            throw new IllegalArgumentException("File descriptors passed in Intent");
18134        }
18135
18136        synchronized(this) {
18137            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18138        }
18139    }
18140
18141    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18142        synchronized(this) {
18143            if (!(token instanceof ServiceRecord)) {
18144                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18145                throw new IllegalArgumentException("Invalid service token");
18146            }
18147            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18148        }
18149    }
18150
18151    // =========================================================
18152    // BACKUP AND RESTORE
18153    // =========================================================
18154
18155    // Cause the target app to be launched if necessary and its backup agent
18156    // instantiated.  The backup agent will invoke backupAgentCreated() on the
18157    // activity manager to announce its creation.
18158    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18159        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18160        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18161
18162        IPackageManager pm = AppGlobals.getPackageManager();
18163        ApplicationInfo app = null;
18164        try {
18165            app = pm.getApplicationInfo(packageName, 0, userId);
18166        } catch (RemoteException e) {
18167            // can't happen; package manager is process-local
18168        }
18169        if (app == null) {
18170            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18171            return false;
18172        }
18173
18174        synchronized(this) {
18175            // !!! TODO: currently no check here that we're already bound
18176            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18177            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18178            synchronized (stats) {
18179                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18180            }
18181
18182            // Backup agent is now in use, its package can't be stopped.
18183            try {
18184                AppGlobals.getPackageManager().setPackageStoppedState(
18185                        app.packageName, false, UserHandle.getUserId(app.uid));
18186            } catch (RemoteException e) {
18187            } catch (IllegalArgumentException e) {
18188                Slog.w(TAG, "Failed trying to unstop package "
18189                        + app.packageName + ": " + e);
18190            }
18191
18192            BackupRecord r = new BackupRecord(ss, app, backupMode);
18193            ComponentName hostingName =
18194                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18195                            ? new ComponentName(app.packageName, app.backupAgentName)
18196                            : new ComponentName("android", "FullBackupAgent");
18197            // startProcessLocked() returns existing proc's record if it's already running
18198            ProcessRecord proc = startProcessLocked(app.processName, app,
18199                    false, 0, "backup", hostingName, false, false, false);
18200            if (proc == null) {
18201                Slog.e(TAG, "Unable to start backup agent process " + r);
18202                return false;
18203            }
18204
18205            // If the app is a regular app (uid >= 10000) and not the system server or phone
18206            // process, etc, then mark it as being in full backup so that certain calls to the
18207            // process can be blocked. This is not reset to false anywhere because we kill the
18208            // process after the full backup is done and the ProcessRecord will vaporize anyway.
18209            if (UserHandle.isApp(app.uid) &&
18210                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18211                proc.inFullBackup = true;
18212            }
18213            r.app = proc;
18214            mBackupTarget = r;
18215            mBackupAppName = app.packageName;
18216
18217            // Try not to kill the process during backup
18218            updateOomAdjLocked(proc);
18219
18220            // If the process is already attached, schedule the creation of the backup agent now.
18221            // If it is not yet live, this will be done when it attaches to the framework.
18222            if (proc.thread != null) {
18223                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18224                try {
18225                    proc.thread.scheduleCreateBackupAgent(app,
18226                            compatibilityInfoForPackageLocked(app), backupMode);
18227                } catch (RemoteException e) {
18228                    // Will time out on the backup manager side
18229                }
18230            } else {
18231                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18232            }
18233            // Invariants: at this point, the target app process exists and the application
18234            // is either already running or in the process of coming up.  mBackupTarget and
18235            // mBackupAppName describe the app, so that when it binds back to the AM we
18236            // know that it's scheduled for a backup-agent operation.
18237        }
18238
18239        return true;
18240    }
18241
18242    @Override
18243    public void clearPendingBackup() {
18244        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18245        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18246
18247        synchronized (this) {
18248            mBackupTarget = null;
18249            mBackupAppName = null;
18250        }
18251    }
18252
18253    // A backup agent has just come up
18254    public void backupAgentCreated(String agentPackageName, IBinder agent) {
18255        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18256                + " = " + agent);
18257
18258        synchronized(this) {
18259            if (!agentPackageName.equals(mBackupAppName)) {
18260                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18261                return;
18262            }
18263        }
18264
18265        long oldIdent = Binder.clearCallingIdentity();
18266        try {
18267            IBackupManager bm = IBackupManager.Stub.asInterface(
18268                    ServiceManager.getService(Context.BACKUP_SERVICE));
18269            bm.agentConnected(agentPackageName, agent);
18270        } catch (RemoteException e) {
18271            // can't happen; the backup manager service is local
18272        } catch (Exception e) {
18273            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18274            e.printStackTrace();
18275        } finally {
18276            Binder.restoreCallingIdentity(oldIdent);
18277        }
18278    }
18279
18280    // done with this agent
18281    public void unbindBackupAgent(ApplicationInfo appInfo) {
18282        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18283        if (appInfo == null) {
18284            Slog.w(TAG, "unbind backup agent for null app");
18285            return;
18286        }
18287
18288        synchronized(this) {
18289            try {
18290                if (mBackupAppName == null) {
18291                    Slog.w(TAG, "Unbinding backup agent with no active backup");
18292                    return;
18293                }
18294
18295                if (!mBackupAppName.equals(appInfo.packageName)) {
18296                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18297                    return;
18298                }
18299
18300                // Not backing this app up any more; reset its OOM adjustment
18301                final ProcessRecord proc = mBackupTarget.app;
18302                updateOomAdjLocked(proc);
18303                proc.inFullBackup = false;
18304
18305                // If the app crashed during backup, 'thread' will be null here
18306                if (proc.thread != null) {
18307                    try {
18308                        proc.thread.scheduleDestroyBackupAgent(appInfo,
18309                                compatibilityInfoForPackageLocked(appInfo));
18310                    } catch (Exception e) {
18311                        Slog.e(TAG, "Exception when unbinding backup agent:");
18312                        e.printStackTrace();
18313                    }
18314                }
18315            } finally {
18316                mBackupTarget = null;
18317                mBackupAppName = null;
18318            }
18319        }
18320    }
18321    // =========================================================
18322    // BROADCASTS
18323    // =========================================================
18324
18325    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18326        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18327            return false;
18328        }
18329        // Easy case -- we have the app's ProcessRecord.
18330        if (record != null) {
18331            return record.info.isInstantApp();
18332        }
18333        // Otherwise check with PackageManager.
18334        if (callerPackage == null) {
18335            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18336            throw new IllegalArgumentException("Calling application did not provide package name");
18337        }
18338        mAppOpsService.checkPackage(uid, callerPackage);
18339        try {
18340            IPackageManager pm = AppGlobals.getPackageManager();
18341            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18342        } catch (RemoteException e) {
18343            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18344            return true;
18345        }
18346    }
18347
18348    boolean isPendingBroadcastProcessLocked(int pid) {
18349        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18350                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18351    }
18352
18353    void skipPendingBroadcastLocked(int pid) {
18354            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18355            for (BroadcastQueue queue : mBroadcastQueues) {
18356                queue.skipPendingBroadcastLocked(pid);
18357            }
18358    }
18359
18360    // The app just attached; send any pending broadcasts that it should receive
18361    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18362        boolean didSomething = false;
18363        for (BroadcastQueue queue : mBroadcastQueues) {
18364            didSomething |= queue.sendPendingBroadcastsLocked(app);
18365        }
18366        return didSomething;
18367    }
18368
18369    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18370            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18371            int flags) {
18372        enforceNotIsolatedCaller("registerReceiver");
18373        ArrayList<Intent> stickyIntents = null;
18374        ProcessRecord callerApp = null;
18375        final boolean visibleToInstantApps
18376                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18377        int callingUid;
18378        int callingPid;
18379        boolean instantApp;
18380        synchronized(this) {
18381            if (caller != null) {
18382                callerApp = getRecordForAppLocked(caller);
18383                if (callerApp == null) {
18384                    throw new SecurityException(
18385                            "Unable to find app for caller " + caller
18386                            + " (pid=" + Binder.getCallingPid()
18387                            + ") when registering receiver " + receiver);
18388                }
18389                if (callerApp.info.uid != SYSTEM_UID &&
18390                        !callerApp.pkgList.containsKey(callerPackage) &&
18391                        !"android".equals(callerPackage)) {
18392                    throw new SecurityException("Given caller package " + callerPackage
18393                            + " is not running in process " + callerApp);
18394                }
18395                callingUid = callerApp.info.uid;
18396                callingPid = callerApp.pid;
18397            } else {
18398                callerPackage = null;
18399                callingUid = Binder.getCallingUid();
18400                callingPid = Binder.getCallingPid();
18401            }
18402
18403            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18404            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18405                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18406
18407            Iterator<String> actions = filter.actionsIterator();
18408            if (actions == null) {
18409                ArrayList<String> noAction = new ArrayList<String>(1);
18410                noAction.add(null);
18411                actions = noAction.iterator();
18412            }
18413
18414            // Collect stickies of users
18415            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18416            while (actions.hasNext()) {
18417                String action = actions.next();
18418                for (int id : userIds) {
18419                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18420                    if (stickies != null) {
18421                        ArrayList<Intent> intents = stickies.get(action);
18422                        if (intents != null) {
18423                            if (stickyIntents == null) {
18424                                stickyIntents = new ArrayList<Intent>();
18425                            }
18426                            stickyIntents.addAll(intents);
18427                        }
18428                    }
18429                }
18430            }
18431        }
18432
18433        ArrayList<Intent> allSticky = null;
18434        if (stickyIntents != null) {
18435            final ContentResolver resolver = mContext.getContentResolver();
18436            // Look for any matching sticky broadcasts...
18437            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18438                Intent intent = stickyIntents.get(i);
18439                // Don't provided intents that aren't available to instant apps.
18440                if (instantApp &&
18441                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18442                    continue;
18443                }
18444                // If intent has scheme "content", it will need to acccess
18445                // provider that needs to lock mProviderMap in ActivityThread
18446                // and also it may need to wait application response, so we
18447                // cannot lock ActivityManagerService here.
18448                if (filter.match(resolver, intent, true, TAG) >= 0) {
18449                    if (allSticky == null) {
18450                        allSticky = new ArrayList<Intent>();
18451                    }
18452                    allSticky.add(intent);
18453                }
18454            }
18455        }
18456
18457        // The first sticky in the list is returned directly back to the client.
18458        Intent sticky = allSticky != null ? allSticky.get(0) : null;
18459        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18460        if (receiver == null) {
18461            return sticky;
18462        }
18463
18464        synchronized (this) {
18465            if (callerApp != null && (callerApp.thread == null
18466                    || callerApp.thread.asBinder() != caller.asBinder())) {
18467                // Original caller already died
18468                return null;
18469            }
18470            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18471            if (rl == null) {
18472                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18473                        userId, receiver);
18474                if (rl.app != null) {
18475                    rl.app.receivers.add(rl);
18476                } else {
18477                    try {
18478                        receiver.asBinder().linkToDeath(rl, 0);
18479                    } catch (RemoteException e) {
18480                        return sticky;
18481                    }
18482                    rl.linkedToDeath = true;
18483                }
18484                mRegisteredReceivers.put(receiver.asBinder(), rl);
18485            } else if (rl.uid != callingUid) {
18486                throw new IllegalArgumentException(
18487                        "Receiver requested to register for uid " + callingUid
18488                        + " was previously registered for uid " + rl.uid
18489                        + " callerPackage is " + callerPackage);
18490            } else if (rl.pid != callingPid) {
18491                throw new IllegalArgumentException(
18492                        "Receiver requested to register for pid " + callingPid
18493                        + " was previously registered for pid " + rl.pid
18494                        + " callerPackage is " + callerPackage);
18495            } else if (rl.userId != userId) {
18496                throw new IllegalArgumentException(
18497                        "Receiver requested to register for user " + userId
18498                        + " was previously registered for user " + rl.userId
18499                        + " callerPackage is " + callerPackage);
18500            }
18501            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18502                    permission, callingUid, userId, instantApp, visibleToInstantApps);
18503            rl.add(bf);
18504            if (!bf.debugCheck()) {
18505                Slog.w(TAG, "==> For Dynamic broadcast");
18506            }
18507            mReceiverResolver.addFilter(bf);
18508
18509            // Enqueue broadcasts for all existing stickies that match
18510            // this filter.
18511            if (allSticky != null) {
18512                ArrayList receivers = new ArrayList();
18513                receivers.add(bf);
18514
18515                final int stickyCount = allSticky.size();
18516                for (int i = 0; i < stickyCount; i++) {
18517                    Intent intent = allSticky.get(i);
18518                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18519                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18520                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18521                            null, 0, null, null, false, true, true, -1);
18522                    queue.enqueueParallelBroadcastLocked(r);
18523                    queue.scheduleBroadcastsLocked();
18524                }
18525            }
18526
18527            return sticky;
18528        }
18529    }
18530
18531    public void unregisterReceiver(IIntentReceiver receiver) {
18532        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18533
18534        final long origId = Binder.clearCallingIdentity();
18535        try {
18536            boolean doTrim = false;
18537
18538            synchronized(this) {
18539                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18540                if (rl != null) {
18541                    final BroadcastRecord r = rl.curBroadcast;
18542                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18543                        final boolean doNext = r.queue.finishReceiverLocked(
18544                                r, r.resultCode, r.resultData, r.resultExtras,
18545                                r.resultAbort, false);
18546                        if (doNext) {
18547                            doTrim = true;
18548                            r.queue.processNextBroadcast(false);
18549                        }
18550                    }
18551
18552                    if (rl.app != null) {
18553                        rl.app.receivers.remove(rl);
18554                    }
18555                    removeReceiverLocked(rl);
18556                    if (rl.linkedToDeath) {
18557                        rl.linkedToDeath = false;
18558                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18559                    }
18560                }
18561            }
18562
18563            // If we actually concluded any broadcasts, we might now be able
18564            // to trim the recipients' apps from our working set
18565            if (doTrim) {
18566                trimApplications();
18567                return;
18568            }
18569
18570        } finally {
18571            Binder.restoreCallingIdentity(origId);
18572        }
18573    }
18574
18575    void removeReceiverLocked(ReceiverList rl) {
18576        mRegisteredReceivers.remove(rl.receiver.asBinder());
18577        for (int i = rl.size() - 1; i >= 0; i--) {
18578            mReceiverResolver.removeFilter(rl.get(i));
18579        }
18580    }
18581
18582    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18583        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18584            ProcessRecord r = mLruProcesses.get(i);
18585            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18586                try {
18587                    r.thread.dispatchPackageBroadcast(cmd, packages);
18588                } catch (RemoteException ex) {
18589                }
18590            }
18591        }
18592    }
18593
18594    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18595            int callingUid, int[] users) {
18596        // TODO: come back and remove this assumption to triage all broadcasts
18597        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18598
18599        List<ResolveInfo> receivers = null;
18600        try {
18601            HashSet<ComponentName> singleUserReceivers = null;
18602            boolean scannedFirstReceivers = false;
18603            for (int user : users) {
18604                // Skip users that have Shell restrictions, with exception of always permitted
18605                // Shell broadcasts
18606                if (callingUid == SHELL_UID
18607                        && mUserController.hasUserRestriction(
18608                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18609                        && !isPermittedShellBroadcast(intent)) {
18610                    continue;
18611                }
18612                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18613                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18614                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18615                    // If this is not the system user, we need to check for
18616                    // any receivers that should be filtered out.
18617                    for (int i=0; i<newReceivers.size(); i++) {
18618                        ResolveInfo ri = newReceivers.get(i);
18619                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18620                            newReceivers.remove(i);
18621                            i--;
18622                        }
18623                    }
18624                }
18625                if (newReceivers != null && newReceivers.size() == 0) {
18626                    newReceivers = null;
18627                }
18628                if (receivers == null) {
18629                    receivers = newReceivers;
18630                } else if (newReceivers != null) {
18631                    // We need to concatenate the additional receivers
18632                    // found with what we have do far.  This would be easy,
18633                    // but we also need to de-dup any receivers that are
18634                    // singleUser.
18635                    if (!scannedFirstReceivers) {
18636                        // Collect any single user receivers we had already retrieved.
18637                        scannedFirstReceivers = true;
18638                        for (int i=0; i<receivers.size(); i++) {
18639                            ResolveInfo ri = receivers.get(i);
18640                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18641                                ComponentName cn = new ComponentName(
18642                                        ri.activityInfo.packageName, ri.activityInfo.name);
18643                                if (singleUserReceivers == null) {
18644                                    singleUserReceivers = new HashSet<ComponentName>();
18645                                }
18646                                singleUserReceivers.add(cn);
18647                            }
18648                        }
18649                    }
18650                    // Add the new results to the existing results, tracking
18651                    // and de-dupping single user receivers.
18652                    for (int i=0; i<newReceivers.size(); i++) {
18653                        ResolveInfo ri = newReceivers.get(i);
18654                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18655                            ComponentName cn = new ComponentName(
18656                                    ri.activityInfo.packageName, ri.activityInfo.name);
18657                            if (singleUserReceivers == null) {
18658                                singleUserReceivers = new HashSet<ComponentName>();
18659                            }
18660                            if (!singleUserReceivers.contains(cn)) {
18661                                singleUserReceivers.add(cn);
18662                                receivers.add(ri);
18663                            }
18664                        } else {
18665                            receivers.add(ri);
18666                        }
18667                    }
18668                }
18669            }
18670        } catch (RemoteException ex) {
18671            // pm is in same process, this will never happen.
18672        }
18673        return receivers;
18674    }
18675
18676    private boolean isPermittedShellBroadcast(Intent intent) {
18677        // remote bugreport should always be allowed to be taken
18678        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18679    }
18680
18681    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18682            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18683        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18684            // Don't yell about broadcasts sent via shell
18685            return;
18686        }
18687
18688        final String action = intent.getAction();
18689        if (isProtectedBroadcast
18690                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18691                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18692                || Intent.ACTION_MEDIA_BUTTON.equals(action)
18693                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18694                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18695                || Intent.ACTION_MASTER_CLEAR.equals(action)
18696                || Intent.ACTION_FACTORY_RESET.equals(action)
18697                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18698                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18699                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18700                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18701                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18702                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18703                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18704            // Broadcast is either protected, or it's a public action that
18705            // we've relaxed, so it's fine for system internals to send.
18706            return;
18707        }
18708
18709        // This broadcast may be a problem...  but there are often system components that
18710        // want to send an internal broadcast to themselves, which is annoying to have to
18711        // explicitly list each action as a protected broadcast, so we will check for that
18712        // one safe case and allow it: an explicit broadcast, only being received by something
18713        // that has protected itself.
18714        if (receivers != null && receivers.size() > 0
18715                && (intent.getPackage() != null || intent.getComponent() != null)) {
18716            boolean allProtected = true;
18717            for (int i = receivers.size()-1; i >= 0; i--) {
18718                Object target = receivers.get(i);
18719                if (target instanceof ResolveInfo) {
18720                    ResolveInfo ri = (ResolveInfo)target;
18721                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18722                        allProtected = false;
18723                        break;
18724                    }
18725                } else {
18726                    BroadcastFilter bf = (BroadcastFilter)target;
18727                    if (bf.requiredPermission == null) {
18728                        allProtected = false;
18729                        break;
18730                    }
18731                }
18732            }
18733            if (allProtected) {
18734                // All safe!
18735                return;
18736            }
18737        }
18738
18739        // The vast majority of broadcasts sent from system internals
18740        // should be protected to avoid security holes, so yell loudly
18741        // to ensure we examine these cases.
18742        if (callerApp != null) {
18743            Log.wtf(TAG, "Sending non-protected broadcast " + action
18744                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
18745                    new Throwable());
18746        } else {
18747            Log.wtf(TAG, "Sending non-protected broadcast " + action
18748                            + " from system uid " + UserHandle.formatUid(callingUid)
18749                            + " pkg " + callerPackage,
18750                    new Throwable());
18751        }
18752    }
18753
18754    final int broadcastIntentLocked(ProcessRecord callerApp,
18755            String callerPackage, Intent intent, String resolvedType,
18756            IIntentReceiver resultTo, int resultCode, String resultData,
18757            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
18758            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
18759        intent = new Intent(intent);
18760
18761        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
18762        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
18763        if (callerInstantApp) {
18764            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
18765        }
18766
18767        // By default broadcasts do not go to stopped apps.
18768        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
18769
18770        // If we have not finished booting, don't allow this to launch new processes.
18771        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
18772            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18773        }
18774
18775        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
18776                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
18777                + " ordered=" + ordered + " userid=" + userId);
18778        if ((resultTo != null) && !ordered) {
18779            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
18780        }
18781
18782        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18783                ALLOW_NON_FULL, "broadcast", callerPackage);
18784
18785        // Make sure that the user who is receiving this broadcast is running.
18786        // If not, we will just skip it. Make an exception for shutdown broadcasts
18787        // and upgrade steps.
18788
18789        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
18790            if ((callingUid != SYSTEM_UID
18791                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
18792                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
18793                Slog.w(TAG, "Skipping broadcast of " + intent
18794                        + ": user " + userId + " is stopped");
18795                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
18796            }
18797        }
18798
18799        BroadcastOptions brOptions = null;
18800        if (bOptions != null) {
18801            brOptions = new BroadcastOptions(bOptions);
18802            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
18803                // See if the caller is allowed to do this.  Note we are checking against
18804                // the actual real caller (not whoever provided the operation as say a
18805                // PendingIntent), because that who is actually supplied the arguments.
18806                if (checkComponentPermission(
18807                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
18808                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
18809                        != PackageManager.PERMISSION_GRANTED) {
18810                    String msg = "Permission Denial: " + intent.getAction()
18811                            + " broadcast from " + callerPackage + " (pid=" + callingPid
18812                            + ", uid=" + callingUid + ")"
18813                            + " requires "
18814                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
18815                    Slog.w(TAG, msg);
18816                    throw new SecurityException(msg);
18817                }
18818            }
18819        }
18820
18821        // Verify that protected broadcasts are only being sent by system code,
18822        // and that system code is only sending protected broadcasts.
18823        final String action = intent.getAction();
18824        final boolean isProtectedBroadcast;
18825        try {
18826            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18827        } catch (RemoteException e) {
18828            Slog.w(TAG, "Remote exception", e);
18829            return ActivityManager.BROADCAST_SUCCESS;
18830        }
18831
18832        final boolean isCallerSystem;
18833        switch (UserHandle.getAppId(callingUid)) {
18834            case ROOT_UID:
18835            case SYSTEM_UID:
18836            case PHONE_UID:
18837            case BLUETOOTH_UID:
18838            case NFC_UID:
18839                isCallerSystem = true;
18840                break;
18841            default:
18842                isCallerSystem = (callerApp != null) && callerApp.persistent;
18843                break;
18844        }
18845
18846        // First line security check before anything else: stop non-system apps from
18847        // sending protected broadcasts.
18848        if (!isCallerSystem) {
18849            if (isProtectedBroadcast) {
18850                String msg = "Permission Denial: not allowed to send broadcast "
18851                        + action + " from pid="
18852                        + callingPid + ", uid=" + callingUid;
18853                Slog.w(TAG, msg);
18854                throw new SecurityException(msg);
18855
18856            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18857                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18858                // Special case for compatibility: we don't want apps to send this,
18859                // but historically it has not been protected and apps may be using it
18860                // to poke their own app widget.  So, instead of making it protected,
18861                // just limit it to the caller.
18862                if (callerPackage == null) {
18863                    String msg = "Permission Denial: not allowed to send broadcast "
18864                            + action + " from unknown caller.";
18865                    Slog.w(TAG, msg);
18866                    throw new SecurityException(msg);
18867                } else if (intent.getComponent() != null) {
18868                    // They are good enough to send to an explicit component...  verify
18869                    // it is being sent to the calling app.
18870                    if (!intent.getComponent().getPackageName().equals(
18871                            callerPackage)) {
18872                        String msg = "Permission Denial: not allowed to send broadcast "
18873                                + action + " to "
18874                                + intent.getComponent().getPackageName() + " from "
18875                                + callerPackage;
18876                        Slog.w(TAG, msg);
18877                        throw new SecurityException(msg);
18878                    }
18879                } else {
18880                    // Limit broadcast to their own package.
18881                    intent.setPackage(callerPackage);
18882                }
18883            }
18884        }
18885
18886        if (action != null) {
18887            if (getBackgroundLaunchBroadcasts().contains(action)) {
18888                if (DEBUG_BACKGROUND_CHECK) {
18889                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
18890                }
18891                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
18892            }
18893
18894            switch (action) {
18895                case Intent.ACTION_UID_REMOVED:
18896                case Intent.ACTION_PACKAGE_REMOVED:
18897                case Intent.ACTION_PACKAGE_CHANGED:
18898                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18899                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18900                case Intent.ACTION_PACKAGES_SUSPENDED:
18901                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18902                    // Handle special intents: if this broadcast is from the package
18903                    // manager about a package being removed, we need to remove all of
18904                    // its activities from the history stack.
18905                    if (checkComponentPermission(
18906                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18907                            callingPid, callingUid, -1, true)
18908                            != PackageManager.PERMISSION_GRANTED) {
18909                        String msg = "Permission Denial: " + intent.getAction()
18910                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18911                                + ", uid=" + callingUid + ")"
18912                                + " requires "
18913                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18914                        Slog.w(TAG, msg);
18915                        throw new SecurityException(msg);
18916                    }
18917                    switch (action) {
18918                        case Intent.ACTION_UID_REMOVED:
18919                            final int uid = getUidFromIntent(intent);
18920                            if (uid >= 0) {
18921                                mBatteryStatsService.removeUid(uid);
18922                                mAppOpsService.uidRemoved(uid);
18923                            }
18924                            break;
18925                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18926                            // If resources are unavailable just force stop all those packages
18927                            // and flush the attribute cache as well.
18928                            String list[] =
18929                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18930                            if (list != null && list.length > 0) {
18931                                for (int i = 0; i < list.length; i++) {
18932                                    forceStopPackageLocked(list[i], -1, false, true, true,
18933                                            false, false, userId, "storage unmount");
18934                                }
18935                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18936                                sendPackageBroadcastLocked(
18937                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
18938                                        list, userId);
18939                            }
18940                            break;
18941                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18942                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18943                            break;
18944                        case Intent.ACTION_PACKAGE_REMOVED:
18945                        case Intent.ACTION_PACKAGE_CHANGED:
18946                            Uri data = intent.getData();
18947                            String ssp;
18948                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18949                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18950                                final boolean replacing =
18951                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18952                                final boolean killProcess =
18953                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18954                                final boolean fullUninstall = removed && !replacing;
18955                                if (removed) {
18956                                    if (killProcess) {
18957                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18958                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18959                                                false, true, true, false, fullUninstall, userId,
18960                                                removed ? "pkg removed" : "pkg changed");
18961                                    }
18962                                    final int cmd = killProcess
18963                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18964                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
18965                                    sendPackageBroadcastLocked(cmd,
18966                                            new String[] {ssp}, userId);
18967                                    if (fullUninstall) {
18968                                        mAppOpsService.packageRemoved(
18969                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18970
18971                                        // Remove all permissions granted from/to this package
18972                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18973
18974                                        removeTasksByPackageNameLocked(ssp, userId);
18975
18976                                        // Hide the "unsupported display" dialog if necessary.
18977                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18978                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18979                                            mUnsupportedDisplaySizeDialog.dismiss();
18980                                            mUnsupportedDisplaySizeDialog = null;
18981                                        }
18982                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18983                                        mBatteryStatsService.notePackageUninstalled(ssp);
18984                                    }
18985                                } else {
18986                                    if (killProcess) {
18987                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18988                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18989                                                userId, ProcessList.INVALID_ADJ,
18990                                                false, true, true, false, "change " + ssp);
18991                                    }
18992                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18993                                            intent.getStringArrayExtra(
18994                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18995                                }
18996                            }
18997                            break;
18998                        case Intent.ACTION_PACKAGES_SUSPENDED:
18999                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
19000                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19001                                    intent.getAction());
19002                            final String[] packageNames = intent.getStringArrayExtra(
19003                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
19004                            final int userHandle = intent.getIntExtra(
19005                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19006
19007                            synchronized(ActivityManagerService.this) {
19008                                mRecentTasks.onPackagesSuspendedChanged(
19009                                        packageNames, suspended, userHandle);
19010                            }
19011                            break;
19012                    }
19013                    break;
19014                case Intent.ACTION_PACKAGE_REPLACED:
19015                {
19016                    final Uri data = intent.getData();
19017                    final String ssp;
19018                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19019                        final ApplicationInfo aInfo =
19020                                getPackageManagerInternalLocked().getApplicationInfo(
19021                                        ssp,
19022                                        userId);
19023                        if (aInfo == null) {
19024                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19025                                    + " ssp=" + ssp + " data=" + data);
19026                            return ActivityManager.BROADCAST_SUCCESS;
19027                        }
19028                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19029                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19030                                new String[] {ssp}, userId);
19031                    }
19032                    break;
19033                }
19034                case Intent.ACTION_PACKAGE_ADDED:
19035                {
19036                    // Special case for adding a package: by default turn on compatibility mode.
19037                    Uri data = intent.getData();
19038                    String ssp;
19039                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19040                        final boolean replacing =
19041                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19042                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19043
19044                        try {
19045                            ApplicationInfo ai = AppGlobals.getPackageManager().
19046                                    getApplicationInfo(ssp, 0, 0);
19047                            mBatteryStatsService.notePackageInstalled(ssp,
19048                                    ai != null ? ai.versionCode : 0);
19049                        } catch (RemoteException e) {
19050                        }
19051                    }
19052                    break;
19053                }
19054                case Intent.ACTION_PACKAGE_DATA_CLEARED:
19055                {
19056                    Uri data = intent.getData();
19057                    String ssp;
19058                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19059                        // Hide the "unsupported display" dialog if necessary.
19060                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19061                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19062                            mUnsupportedDisplaySizeDialog.dismiss();
19063                            mUnsupportedDisplaySizeDialog = null;
19064                        }
19065                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
19066                    }
19067                    break;
19068                }
19069                case Intent.ACTION_TIMEZONE_CHANGED:
19070                    // If this is the time zone changed action, queue up a message that will reset
19071                    // the timezone of all currently running processes. This message will get
19072                    // queued up before the broadcast happens.
19073                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19074                    break;
19075                case Intent.ACTION_TIME_CHANGED:
19076                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19077                    // the tri-state value it may contain and "unknown".
19078                    // For convenience we re-use the Intent extra values.
19079                    final int NO_EXTRA_VALUE_FOUND = -1;
19080                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19081                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19082                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
19083                    // Only send a message if the time preference is available.
19084                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19085                        Message updateTimePreferenceMsg =
19086                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19087                                        timeFormatPreferenceMsgValue, 0);
19088                        mHandler.sendMessage(updateTimePreferenceMsg);
19089                    }
19090                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19091                    synchronized (stats) {
19092                        stats.noteCurrentTimeChangedLocked();
19093                    }
19094                    break;
19095                case Intent.ACTION_CLEAR_DNS_CACHE:
19096                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19097                    break;
19098                case Proxy.PROXY_CHANGE_ACTION:
19099                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19100                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19101                    break;
19102                case android.hardware.Camera.ACTION_NEW_PICTURE:
19103                case android.hardware.Camera.ACTION_NEW_VIDEO:
19104                    // In N we just turned these off; in O we are turing them back on partly,
19105                    // only for registered receivers.  This will still address the main problem
19106                    // (a spam of apps waking up when a picture is taken putting significant
19107                    // memory pressure on the system at a bad point), while still allowing apps
19108                    // that are already actively running to know about this happening.
19109                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19110                    break;
19111                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19112                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19113                    break;
19114            }
19115
19116            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19117                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19118                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19119                final int uid = getUidFromIntent(intent);
19120                if (uid != -1) {
19121                    final UidRecord uidRec = mActiveUids.get(uid);
19122                    if (uidRec != null) {
19123                        uidRec.updateHasInternetPermission();
19124                    }
19125                }
19126            }
19127        }
19128
19129        // Add to the sticky list if requested.
19130        if (sticky) {
19131            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19132                    callingPid, callingUid)
19133                    != PackageManager.PERMISSION_GRANTED) {
19134                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19135                        + callingPid + ", uid=" + callingUid
19136                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19137                Slog.w(TAG, msg);
19138                throw new SecurityException(msg);
19139            }
19140            if (requiredPermissions != null && requiredPermissions.length > 0) {
19141                Slog.w(TAG, "Can't broadcast sticky intent " + intent
19142                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
19143                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19144            }
19145            if (intent.getComponent() != null) {
19146                throw new SecurityException(
19147                        "Sticky broadcasts can't target a specific component");
19148            }
19149            // We use userId directly here, since the "all" target is maintained
19150            // as a separate set of sticky broadcasts.
19151            if (userId != UserHandle.USER_ALL) {
19152                // But first, if this is not a broadcast to all users, then
19153                // make sure it doesn't conflict with an existing broadcast to
19154                // all users.
19155                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19156                        UserHandle.USER_ALL);
19157                if (stickies != null) {
19158                    ArrayList<Intent> list = stickies.get(intent.getAction());
19159                    if (list != null) {
19160                        int N = list.size();
19161                        int i;
19162                        for (i=0; i<N; i++) {
19163                            if (intent.filterEquals(list.get(i))) {
19164                                throw new IllegalArgumentException(
19165                                        "Sticky broadcast " + intent + " for user "
19166                                        + userId + " conflicts with existing global broadcast");
19167                            }
19168                        }
19169                    }
19170                }
19171            }
19172            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19173            if (stickies == null) {
19174                stickies = new ArrayMap<>();
19175                mStickyBroadcasts.put(userId, stickies);
19176            }
19177            ArrayList<Intent> list = stickies.get(intent.getAction());
19178            if (list == null) {
19179                list = new ArrayList<>();
19180                stickies.put(intent.getAction(), list);
19181            }
19182            final int stickiesCount = list.size();
19183            int i;
19184            for (i = 0; i < stickiesCount; i++) {
19185                if (intent.filterEquals(list.get(i))) {
19186                    // This sticky already exists, replace it.
19187                    list.set(i, new Intent(intent));
19188                    break;
19189                }
19190            }
19191            if (i >= stickiesCount) {
19192                list.add(new Intent(intent));
19193            }
19194        }
19195
19196        int[] users;
19197        if (userId == UserHandle.USER_ALL) {
19198            // Caller wants broadcast to go to all started users.
19199            users = mUserController.getStartedUserArrayLocked();
19200        } else {
19201            // Caller wants broadcast to go to one specific user.
19202            users = new int[] {userId};
19203        }
19204
19205        // Figure out who all will receive this broadcast.
19206        List receivers = null;
19207        List<BroadcastFilter> registeredReceivers = null;
19208        // Need to resolve the intent to interested receivers...
19209        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19210                 == 0) {
19211            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19212        }
19213        if (intent.getComponent() == null) {
19214            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19215                // Query one target user at a time, excluding shell-restricted users
19216                for (int i = 0; i < users.length; i++) {
19217                    if (mUserController.hasUserRestriction(
19218                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19219                        continue;
19220                    }
19221                    List<BroadcastFilter> registeredReceiversForUser =
19222                            mReceiverResolver.queryIntent(intent,
19223                                    resolvedType, false /*defaultOnly*/, users[i]);
19224                    if (registeredReceivers == null) {
19225                        registeredReceivers = registeredReceiversForUser;
19226                    } else if (registeredReceiversForUser != null) {
19227                        registeredReceivers.addAll(registeredReceiversForUser);
19228                    }
19229                }
19230            } else {
19231                registeredReceivers = mReceiverResolver.queryIntent(intent,
19232                        resolvedType, false /*defaultOnly*/, userId);
19233            }
19234        }
19235
19236        final boolean replacePending =
19237                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19238
19239        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19240                + " replacePending=" + replacePending);
19241
19242        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19243        if (!ordered && NR > 0) {
19244            // If we are not serializing this broadcast, then send the
19245            // registered receivers separately so they don't wait for the
19246            // components to be launched.
19247            if (isCallerSystem) {
19248                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19249                        isProtectedBroadcast, registeredReceivers);
19250            }
19251            final BroadcastQueue queue = broadcastQueueForIntent(intent);
19252            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19253                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19254                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19255                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19256            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19257            final boolean replaced = replacePending
19258                    && (queue.replaceParallelBroadcastLocked(r) != null);
19259            // Note: We assume resultTo is null for non-ordered broadcasts.
19260            if (!replaced) {
19261                queue.enqueueParallelBroadcastLocked(r);
19262                queue.scheduleBroadcastsLocked();
19263            }
19264            registeredReceivers = null;
19265            NR = 0;
19266        }
19267
19268        // Merge into one list.
19269        int ir = 0;
19270        if (receivers != null) {
19271            // A special case for PACKAGE_ADDED: do not allow the package
19272            // being added to see this broadcast.  This prevents them from
19273            // using this as a back door to get run as soon as they are
19274            // installed.  Maybe in the future we want to have a special install
19275            // broadcast or such for apps, but we'd like to deliberately make
19276            // this decision.
19277            String skipPackages[] = null;
19278            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19279                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19280                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19281                Uri data = intent.getData();
19282                if (data != null) {
19283                    String pkgName = data.getSchemeSpecificPart();
19284                    if (pkgName != null) {
19285                        skipPackages = new String[] { pkgName };
19286                    }
19287                }
19288            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19289                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19290            }
19291            if (skipPackages != null && (skipPackages.length > 0)) {
19292                for (String skipPackage : skipPackages) {
19293                    if (skipPackage != null) {
19294                        int NT = receivers.size();
19295                        for (int it=0; it<NT; it++) {
19296                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
19297                            if (curt.activityInfo.packageName.equals(skipPackage)) {
19298                                receivers.remove(it);
19299                                it--;
19300                                NT--;
19301                            }
19302                        }
19303                    }
19304                }
19305            }
19306
19307            int NT = receivers != null ? receivers.size() : 0;
19308            int it = 0;
19309            ResolveInfo curt = null;
19310            BroadcastFilter curr = null;
19311            while (it < NT && ir < NR) {
19312                if (curt == null) {
19313                    curt = (ResolveInfo)receivers.get(it);
19314                }
19315                if (curr == null) {
19316                    curr = registeredReceivers.get(ir);
19317                }
19318                if (curr.getPriority() >= curt.priority) {
19319                    // Insert this broadcast record into the final list.
19320                    receivers.add(it, curr);
19321                    ir++;
19322                    curr = null;
19323                    it++;
19324                    NT++;
19325                } else {
19326                    // Skip to the next ResolveInfo in the final list.
19327                    it++;
19328                    curt = null;
19329                }
19330            }
19331        }
19332        while (ir < NR) {
19333            if (receivers == null) {
19334                receivers = new ArrayList();
19335            }
19336            receivers.add(registeredReceivers.get(ir));
19337            ir++;
19338        }
19339
19340        if (isCallerSystem) {
19341            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19342                    isProtectedBroadcast, receivers);
19343        }
19344
19345        if ((receivers != null && receivers.size() > 0)
19346                || resultTo != null) {
19347            BroadcastQueue queue = broadcastQueueForIntent(intent);
19348            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19349                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19350                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19351                    resultData, resultExtras, ordered, sticky, false, userId);
19352
19353            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19354                    + ": prev had " + queue.mOrderedBroadcasts.size());
19355            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19356                    "Enqueueing broadcast " + r.intent.getAction());
19357
19358            final BroadcastRecord oldRecord =
19359                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19360            if (oldRecord != null) {
19361                // Replaced, fire the result-to receiver.
19362                if (oldRecord.resultTo != null) {
19363                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19364                    try {
19365                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19366                                oldRecord.intent,
19367                                Activity.RESULT_CANCELED, null, null,
19368                                false, false, oldRecord.userId);
19369                    } catch (RemoteException e) {
19370                        Slog.w(TAG, "Failure ["
19371                                + queue.mQueueName + "] sending broadcast result of "
19372                                + intent, e);
19373
19374                    }
19375                }
19376            } else {
19377                queue.enqueueOrderedBroadcastLocked(r);
19378                queue.scheduleBroadcastsLocked();
19379            }
19380        } else {
19381            // There was nobody interested in the broadcast, but we still want to record
19382            // that it happened.
19383            if (intent.getComponent() == null && intent.getPackage() == null
19384                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19385                // This was an implicit broadcast... let's record it for posterity.
19386                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19387            }
19388        }
19389
19390        return ActivityManager.BROADCAST_SUCCESS;
19391    }
19392
19393    /**
19394     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19395     */
19396    private int getUidFromIntent(Intent intent) {
19397        if (intent == null) {
19398            return -1;
19399        }
19400        final Bundle intentExtras = intent.getExtras();
19401        return intent.hasExtra(Intent.EXTRA_UID)
19402                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19403    }
19404
19405    final void rotateBroadcastStatsIfNeededLocked() {
19406        final long now = SystemClock.elapsedRealtime();
19407        if (mCurBroadcastStats == null ||
19408                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19409            mLastBroadcastStats = mCurBroadcastStats;
19410            if (mLastBroadcastStats != null) {
19411                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19412                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19413            }
19414            mCurBroadcastStats = new BroadcastStats();
19415        }
19416    }
19417
19418    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19419            int skipCount, long dispatchTime) {
19420        rotateBroadcastStatsIfNeededLocked();
19421        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19422    }
19423
19424    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19425        rotateBroadcastStatsIfNeededLocked();
19426        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19427    }
19428
19429    final Intent verifyBroadcastLocked(Intent intent) {
19430        // Refuse possible leaked file descriptors
19431        if (intent != null && intent.hasFileDescriptors() == true) {
19432            throw new IllegalArgumentException("File descriptors passed in Intent");
19433        }
19434
19435        int flags = intent.getFlags();
19436
19437        if (!mProcessesReady) {
19438            // if the caller really truly claims to know what they're doing, go
19439            // ahead and allow the broadcast without launching any receivers
19440            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19441                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19442            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19443                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19444                        + " before boot completion");
19445                throw new IllegalStateException("Cannot broadcast before boot completed");
19446            }
19447        }
19448
19449        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19450            throw new IllegalArgumentException(
19451                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19452        }
19453
19454        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19455            switch (Binder.getCallingUid()) {
19456                case ROOT_UID:
19457                case SHELL_UID:
19458                    break;
19459                default:
19460                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19461                            + Binder.getCallingUid());
19462                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19463                    break;
19464            }
19465        }
19466
19467        return intent;
19468    }
19469
19470    public final int broadcastIntent(IApplicationThread caller,
19471            Intent intent, String resolvedType, IIntentReceiver resultTo,
19472            int resultCode, String resultData, Bundle resultExtras,
19473            String[] requiredPermissions, int appOp, Bundle bOptions,
19474            boolean serialized, boolean sticky, int userId) {
19475        enforceNotIsolatedCaller("broadcastIntent");
19476        synchronized(this) {
19477            intent = verifyBroadcastLocked(intent);
19478
19479            final ProcessRecord callerApp = getRecordForAppLocked(caller);
19480            final int callingPid = Binder.getCallingPid();
19481            final int callingUid = Binder.getCallingUid();
19482            final long origId = Binder.clearCallingIdentity();
19483            int res = broadcastIntentLocked(callerApp,
19484                    callerApp != null ? callerApp.info.packageName : null,
19485                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19486                    requiredPermissions, appOp, bOptions, serialized, sticky,
19487                    callingPid, callingUid, userId);
19488            Binder.restoreCallingIdentity(origId);
19489            return res;
19490        }
19491    }
19492
19493
19494    int broadcastIntentInPackage(String packageName, int uid,
19495            Intent intent, String resolvedType, IIntentReceiver resultTo,
19496            int resultCode, String resultData, Bundle resultExtras,
19497            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19498            int userId) {
19499        synchronized(this) {
19500            intent = verifyBroadcastLocked(intent);
19501
19502            final long origId = Binder.clearCallingIdentity();
19503            String[] requiredPermissions = requiredPermission == null ? null
19504                    : new String[] {requiredPermission};
19505            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19506                    resultTo, resultCode, resultData, resultExtras,
19507                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19508                    sticky, -1, uid, userId);
19509            Binder.restoreCallingIdentity(origId);
19510            return res;
19511        }
19512    }
19513
19514    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19515        // Refuse possible leaked file descriptors
19516        if (intent != null && intent.hasFileDescriptors() == true) {
19517            throw new IllegalArgumentException("File descriptors passed in Intent");
19518        }
19519
19520        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19521                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19522
19523        synchronized(this) {
19524            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19525                    != PackageManager.PERMISSION_GRANTED) {
19526                String msg = "Permission Denial: unbroadcastIntent() from pid="
19527                        + Binder.getCallingPid()
19528                        + ", uid=" + Binder.getCallingUid()
19529                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19530                Slog.w(TAG, msg);
19531                throw new SecurityException(msg);
19532            }
19533            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19534            if (stickies != null) {
19535                ArrayList<Intent> list = stickies.get(intent.getAction());
19536                if (list != null) {
19537                    int N = list.size();
19538                    int i;
19539                    for (i=0; i<N; i++) {
19540                        if (intent.filterEquals(list.get(i))) {
19541                            list.remove(i);
19542                            break;
19543                        }
19544                    }
19545                    if (list.size() <= 0) {
19546                        stickies.remove(intent.getAction());
19547                    }
19548                }
19549                if (stickies.size() <= 0) {
19550                    mStickyBroadcasts.remove(userId);
19551                }
19552            }
19553        }
19554    }
19555
19556    void backgroundServicesFinishedLocked(int userId) {
19557        for (BroadcastQueue queue : mBroadcastQueues) {
19558            queue.backgroundServicesFinishedLocked(userId);
19559        }
19560    }
19561
19562    public void finishReceiver(IBinder who, int resultCode, String resultData,
19563            Bundle resultExtras, boolean resultAbort, int flags) {
19564        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19565
19566        // Refuse possible leaked file descriptors
19567        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19568            throw new IllegalArgumentException("File descriptors passed in Bundle");
19569        }
19570
19571        final long origId = Binder.clearCallingIdentity();
19572        try {
19573            boolean doNext = false;
19574            BroadcastRecord r;
19575
19576            synchronized(this) {
19577                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19578                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19579                r = queue.getMatchingOrderedReceiver(who);
19580                if (r != null) {
19581                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19582                        resultData, resultExtras, resultAbort, true);
19583                }
19584            }
19585
19586            if (doNext) {
19587                r.queue.processNextBroadcast(false);
19588            }
19589            trimApplications();
19590        } finally {
19591            Binder.restoreCallingIdentity(origId);
19592        }
19593    }
19594
19595    // =========================================================
19596    // INSTRUMENTATION
19597    // =========================================================
19598
19599    public boolean startInstrumentation(ComponentName className,
19600            String profileFile, int flags, Bundle arguments,
19601            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19602            int userId, String abiOverride) {
19603        enforceNotIsolatedCaller("startInstrumentation");
19604        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19605                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19606        // Refuse possible leaked file descriptors
19607        if (arguments != null && arguments.hasFileDescriptors()) {
19608            throw new IllegalArgumentException("File descriptors passed in Bundle");
19609        }
19610
19611        synchronized(this) {
19612            InstrumentationInfo ii = null;
19613            ApplicationInfo ai = null;
19614            try {
19615                ii = mContext.getPackageManager().getInstrumentationInfo(
19616                    className, STOCK_PM_FLAGS);
19617                ai = AppGlobals.getPackageManager().getApplicationInfo(
19618                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19619            } catch (PackageManager.NameNotFoundException e) {
19620            } catch (RemoteException e) {
19621            }
19622            if (ii == null) {
19623                reportStartInstrumentationFailureLocked(watcher, className,
19624                        "Unable to find instrumentation info for: " + className);
19625                return false;
19626            }
19627            if (ai == null) {
19628                reportStartInstrumentationFailureLocked(watcher, className,
19629                        "Unable to find instrumentation target package: " + ii.targetPackage);
19630                return false;
19631            }
19632            if (!ai.hasCode()) {
19633                reportStartInstrumentationFailureLocked(watcher, className,
19634                        "Instrumentation target has no code: " + ii.targetPackage);
19635                return false;
19636            }
19637
19638            int match = mContext.getPackageManager().checkSignatures(
19639                    ii.targetPackage, ii.packageName);
19640            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19641                String msg = "Permission Denial: starting instrumentation "
19642                        + className + " from pid="
19643                        + Binder.getCallingPid()
19644                        + ", uid=" + Binder.getCallingPid()
19645                        + " not allowed because package " + ii.packageName
19646                        + " does not have a signature matching the target "
19647                        + ii.targetPackage;
19648                reportStartInstrumentationFailureLocked(watcher, className, msg);
19649                throw new SecurityException(msg);
19650            }
19651
19652            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19653            activeInstr.mClass = className;
19654            String defProcess = ai.processName;;
19655            if (ii.targetProcess == null) {
19656                activeInstr.mTargetProcesses = new String[]{ai.processName};
19657            } else if (ii.targetProcess.equals("*")) {
19658                activeInstr.mTargetProcesses = new String[0];
19659            } else {
19660                activeInstr.mTargetProcesses = ii.targetProcess.split(",");
19661                defProcess = activeInstr.mTargetProcesses[0];
19662            }
19663            activeInstr.mTargetInfo = ai;
19664            activeInstr.mProfileFile = profileFile;
19665            activeInstr.mArguments = arguments;
19666            activeInstr.mWatcher = watcher;
19667            activeInstr.mUiAutomationConnection = uiAutomationConnection;
19668            activeInstr.mResultClass = className;
19669
19670            final long origId = Binder.clearCallingIdentity();
19671            // Instrumentation can kill and relaunch even persistent processes
19672            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19673                    "start instr");
19674            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19675            app.instr = activeInstr;
19676            activeInstr.mFinished = false;
19677            activeInstr.mRunningProcesses.add(app);
19678            if (!mActiveInstrumentation.contains(activeInstr)) {
19679                mActiveInstrumentation.add(activeInstr);
19680            }
19681            Binder.restoreCallingIdentity(origId);
19682        }
19683
19684        return true;
19685    }
19686
19687    /**
19688     * Report errors that occur while attempting to start Instrumentation.  Always writes the
19689     * error to the logs, but if somebody is watching, send the report there too.  This enables
19690     * the "am" command to report errors with more information.
19691     *
19692     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19693     * @param cn The component name of the instrumentation.
19694     * @param report The error report.
19695     */
19696    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19697            ComponentName cn, String report) {
19698        Slog.w(TAG, report);
19699        if (watcher != null) {
19700            Bundle results = new Bundle();
19701            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19702            results.putString("Error", report);
19703            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19704        }
19705    }
19706
19707    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19708        if (app.instr == null) {
19709            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19710            return;
19711        }
19712
19713        if (!app.instr.mFinished && results != null) {
19714            if (app.instr.mCurResults == null) {
19715                app.instr.mCurResults = new Bundle(results);
19716            } else {
19717                app.instr.mCurResults.putAll(results);
19718            }
19719        }
19720    }
19721
19722    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
19723        int userId = UserHandle.getCallingUserId();
19724        // Refuse possible leaked file descriptors
19725        if (results != null && results.hasFileDescriptors()) {
19726            throw new IllegalArgumentException("File descriptors passed in Intent");
19727        }
19728
19729        synchronized(this) {
19730            ProcessRecord app = getRecordForAppLocked(target);
19731            if (app == null) {
19732                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
19733                return;
19734            }
19735            final long origId = Binder.clearCallingIdentity();
19736            addInstrumentationResultsLocked(app, results);
19737            Binder.restoreCallingIdentity(origId);
19738        }
19739    }
19740
19741    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
19742        if (app.instr == null) {
19743            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19744            return;
19745        }
19746
19747        if (!app.instr.mFinished) {
19748            if (app.instr.mWatcher != null) {
19749                Bundle finalResults = app.instr.mCurResults;
19750                if (finalResults != null) {
19751                    if (app.instr.mCurResults != null && results != null) {
19752                        finalResults.putAll(results);
19753                    }
19754                } else {
19755                    finalResults = results;
19756                }
19757                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
19758                        app.instr.mClass, resultCode, finalResults);
19759            }
19760
19761            // Can't call out of the system process with a lock held, so post a message.
19762            if (app.instr.mUiAutomationConnection != null) {
19763                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
19764                        app.instr.mUiAutomationConnection).sendToTarget();
19765            }
19766            app.instr.mFinished = true;
19767        }
19768
19769        app.instr.removeProcess(app);
19770        app.instr = null;
19771
19772        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
19773                "finished inst");
19774    }
19775
19776    public void finishInstrumentation(IApplicationThread target,
19777            int resultCode, Bundle results) {
19778        int userId = UserHandle.getCallingUserId();
19779        // Refuse possible leaked file descriptors
19780        if (results != null && results.hasFileDescriptors()) {
19781            throw new IllegalArgumentException("File descriptors passed in Intent");
19782        }
19783
19784        synchronized(this) {
19785            ProcessRecord app = getRecordForAppLocked(target);
19786            if (app == null) {
19787                Slog.w(TAG, "finishInstrumentation: no app for " + target);
19788                return;
19789            }
19790            final long origId = Binder.clearCallingIdentity();
19791            finishInstrumentationLocked(app, resultCode, results);
19792            Binder.restoreCallingIdentity(origId);
19793        }
19794    }
19795
19796    // =========================================================
19797    // CONFIGURATION
19798    // =========================================================
19799
19800    public ConfigurationInfo getDeviceConfigurationInfo() {
19801        ConfigurationInfo config = new ConfigurationInfo();
19802        synchronized (this) {
19803            final Configuration globalConfig = getGlobalConfiguration();
19804            config.reqTouchScreen = globalConfig.touchscreen;
19805            config.reqKeyboardType = globalConfig.keyboard;
19806            config.reqNavigation = globalConfig.navigation;
19807            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
19808                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
19809                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
19810            }
19811            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
19812                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
19813                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
19814            }
19815            config.reqGlEsVersion = GL_ES_VERSION;
19816        }
19817        return config;
19818    }
19819
19820    ActivityStack getFocusedStack() {
19821        return mStackSupervisor.getFocusedStack();
19822    }
19823
19824    @Override
19825    public int getFocusedStackId() throws RemoteException {
19826        ActivityStack focusedStack = getFocusedStack();
19827        if (focusedStack != null) {
19828            return focusedStack.getStackId();
19829        }
19830        return -1;
19831    }
19832
19833    public Configuration getConfiguration() {
19834        Configuration ci;
19835        synchronized(this) {
19836            ci = new Configuration(getGlobalConfiguration());
19837            ci.userSetLocale = false;
19838        }
19839        return ci;
19840    }
19841
19842    @Override
19843    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
19844        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
19845        synchronized (this) {
19846            mSuppressResizeConfigChanges = suppress;
19847        }
19848    }
19849
19850    /**
19851     * NOTE: For the pinned stack, this method is only called after the bounds animation has
19852     *       animated the stack to the fullscreen.
19853     */
19854    @Override
19855    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
19856        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
19857        if (StackId.isHomeOrRecentsStack(fromStackId)) {
19858            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
19859        }
19860        synchronized (this) {
19861            final long origId = Binder.clearCallingIdentity();
19862            try {
19863                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
19864            } finally {
19865                Binder.restoreCallingIdentity(origId);
19866            }
19867        }
19868    }
19869
19870    @Override
19871    public void updatePersistentConfiguration(Configuration values) {
19872        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
19873        enforceWriteSettingsPermission("updatePersistentConfiguration()");
19874        if (values == null) {
19875            throw new NullPointerException("Configuration must not be null");
19876        }
19877
19878        int userId = UserHandle.getCallingUserId();
19879
19880        synchronized(this) {
19881            updatePersistentConfigurationLocked(values, userId);
19882        }
19883    }
19884
19885    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
19886        final long origId = Binder.clearCallingIdentity();
19887        try {
19888            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
19889        } finally {
19890            Binder.restoreCallingIdentity(origId);
19891        }
19892    }
19893
19894    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
19895        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
19896                FONT_SCALE, 1.0f, userId);
19897
19898        synchronized (this) {
19899            if (getGlobalConfiguration().fontScale == scaleFactor) {
19900                return;
19901            }
19902
19903            final Configuration configuration
19904                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19905            configuration.fontScale = scaleFactor;
19906            updatePersistentConfigurationLocked(configuration, userId);
19907        }
19908    }
19909
19910    private void enforceWriteSettingsPermission(String func) {
19911        int uid = Binder.getCallingUid();
19912        if (uid == ROOT_UID) {
19913            return;
19914        }
19915
19916        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
19917                Settings.getPackageNameForUid(mContext, uid), false)) {
19918            return;
19919        }
19920
19921        String msg = "Permission Denial: " + func + " from pid="
19922                + Binder.getCallingPid()
19923                + ", uid=" + uid
19924                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
19925        Slog.w(TAG, msg);
19926        throw new SecurityException(msg);
19927    }
19928
19929    @Override
19930    public boolean updateConfiguration(Configuration values) {
19931        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
19932
19933        synchronized(this) {
19934            if (values == null && mWindowManager != null) {
19935                // sentinel: fetch the current configuration from the window manager
19936                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19937            }
19938
19939            if (mWindowManager != null) {
19940                // Update OOM levels based on display size.
19941                mProcessList.applyDisplaySize(mWindowManager);
19942            }
19943
19944            final long origId = Binder.clearCallingIdentity();
19945            try {
19946                if (values != null) {
19947                    Settings.System.clearConfiguration(values);
19948                }
19949                updateConfigurationLocked(values, null, false, false /* persistent */,
19950                        UserHandle.USER_NULL, false /* deferResume */,
19951                        mTmpUpdateConfigurationResult);
19952                return mTmpUpdateConfigurationResult.changes != 0;
19953            } finally {
19954                Binder.restoreCallingIdentity(origId);
19955            }
19956        }
19957    }
19958
19959    void updateUserConfigurationLocked() {
19960        final Configuration configuration = new Configuration(getGlobalConfiguration());
19961        final int currentUserId = mUserController.getCurrentUserIdLocked();
19962        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
19963                currentUserId, Settings.System.canWrite(mContext));
19964        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
19965                false /* persistent */, currentUserId, false /* deferResume */);
19966    }
19967
19968    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19969            boolean initLocale) {
19970        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19971    }
19972
19973    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19974            boolean initLocale, boolean deferResume) {
19975        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19976        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19977                UserHandle.USER_NULL, deferResume);
19978    }
19979
19980    // To cache the list of supported system locales
19981    private String[] mSupportedSystemLocales = null;
19982
19983    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19984            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19985        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
19986                deferResume, null /* result */);
19987    }
19988
19989    /**
19990     * Do either or both things: (1) change the current configuration, and (2)
19991     * make sure the given activity is running with the (now) current
19992     * configuration.  Returns true if the activity has been left running, or
19993     * false if <var>starting</var> is being destroyed to match the new
19994     * configuration.
19995     *
19996     * @param userId is only used when persistent parameter is set to true to persist configuration
19997     *               for that particular user
19998     */
19999    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20000            boolean initLocale, boolean persistent, int userId, boolean deferResume,
20001            UpdateConfigurationResult result) {
20002        int changes = 0;
20003        boolean kept = true;
20004
20005        if (mWindowManager != null) {
20006            mWindowManager.deferSurfaceLayout();
20007        }
20008        try {
20009            if (values != null) {
20010                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20011                        deferResume);
20012            }
20013
20014            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20015        } finally {
20016            if (mWindowManager != null) {
20017                mWindowManager.continueSurfaceLayout();
20018            }
20019        }
20020
20021        if (result != null) {
20022            result.changes = changes;
20023            result.activityRelaunched = !kept;
20024        }
20025        return kept;
20026    }
20027
20028    /** Update default (global) configuration and notify listeners about changes. */
20029    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20030            boolean persistent, int userId, boolean deferResume) {
20031        mTempConfig.setTo(getGlobalConfiguration());
20032        final int changes = mTempConfig.updateFrom(values);
20033        if (changes == 0) {
20034            return 0;
20035        }
20036
20037        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20038                "Updating global configuration to: " + values);
20039
20040        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20041
20042        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20043            final LocaleList locales = values.getLocales();
20044            int bestLocaleIndex = 0;
20045            if (locales.size() > 1) {
20046                if (mSupportedSystemLocales == null) {
20047                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20048                }
20049                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20050            }
20051            SystemProperties.set("persist.sys.locale",
20052                    locales.get(bestLocaleIndex).toLanguageTag());
20053            LocaleList.setDefault(locales, bestLocaleIndex);
20054            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20055                    locales.get(bestLocaleIndex)));
20056        }
20057
20058        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20059        mTempConfig.seq = mConfigurationSeq;
20060
20061        // Update stored global config and notify everyone about the change.
20062        mStackSupervisor.onConfigurationChanged(mTempConfig);
20063
20064        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20065        // TODO(multi-display): Update UsageEvents#Event to include displayId.
20066        mUsageStatsService.reportConfigurationChange(mTempConfig,
20067                mUserController.getCurrentUserIdLocked());
20068
20069        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20070        mShowDialogs = shouldShowDialogs(mTempConfig);
20071
20072        AttributeCache ac = AttributeCache.instance();
20073        if (ac != null) {
20074            ac.updateConfiguration(mTempConfig);
20075        }
20076
20077        // Make sure all resources in our process are updated right now, so that anyone who is going
20078        // to retrieve resource values after we return will be sure to get the new ones. This is
20079        // especially important during boot, where the first config change needs to guarantee all
20080        // resources have that config before following boot code is executed.
20081        mSystemThread.applyConfigurationToResources(mTempConfig);
20082
20083        // We need another copy of global config because we're scheduling some calls instead of
20084        // running them in place. We need to be sure that object we send will be handled unchanged.
20085        final Configuration configCopy = new Configuration(mTempConfig);
20086        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20087            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20088            msg.obj = configCopy;
20089            msg.arg1 = userId;
20090            mHandler.sendMessage(msg);
20091        }
20092
20093        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20094            ProcessRecord app = mLruProcesses.get(i);
20095            try {
20096                if (app.thread != null) {
20097                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20098                            + app.processName + " new config " + configCopy);
20099                    app.thread.scheduleConfigurationChanged(configCopy);
20100                }
20101            } catch (Exception e) {
20102            }
20103        }
20104
20105        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20106        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20107                | Intent.FLAG_RECEIVER_FOREGROUND
20108                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20109        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20110                AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20111                UserHandle.USER_ALL);
20112        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20113            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20114            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20115                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20116                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20117            if (initLocale || !mProcessesReady) {
20118                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20119            }
20120            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20121                    AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20122                    UserHandle.USER_ALL);
20123        }
20124
20125        // Override configuration of the default display duplicates global config, so we need to
20126        // update it also. This will also notify WindowManager about changes.
20127        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20128                DEFAULT_DISPLAY);
20129
20130        return changes;
20131    }
20132
20133    @Override
20134    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20135        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20136
20137        synchronized (this) {
20138            // Check if display is initialized in AM.
20139            if (!mStackSupervisor.isDisplayAdded(displayId)) {
20140                // Call might come when display is not yet added or has already been removed.
20141                if (DEBUG_CONFIGURATION) {
20142                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20143                            + displayId);
20144                }
20145                return false;
20146            }
20147
20148            if (values == null && mWindowManager != null) {
20149                // sentinel: fetch the current configuration from the window manager
20150                values = mWindowManager.computeNewConfiguration(displayId);
20151            }
20152
20153            if (mWindowManager != null) {
20154                // Update OOM levels based on display size.
20155                mProcessList.applyDisplaySize(mWindowManager);
20156            }
20157
20158            final long origId = Binder.clearCallingIdentity();
20159            try {
20160                if (values != null) {
20161                    Settings.System.clearConfiguration(values);
20162                }
20163                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20164                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20165                return mTmpUpdateConfigurationResult.changes != 0;
20166            } finally {
20167                Binder.restoreCallingIdentity(origId);
20168            }
20169        }
20170    }
20171
20172    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20173            boolean deferResume, int displayId) {
20174        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20175                displayId, null /* result */);
20176    }
20177
20178    /**
20179     * Updates override configuration specific for the selected display. If no config is provided,
20180     * new one will be computed in WM based on current display info.
20181     */
20182    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20183            ActivityRecord starting, boolean deferResume, int displayId,
20184            UpdateConfigurationResult result) {
20185        int changes = 0;
20186        boolean kept = true;
20187
20188        if (mWindowManager != null) {
20189            mWindowManager.deferSurfaceLayout();
20190        }
20191        try {
20192            if (values != null) {
20193                if (displayId == DEFAULT_DISPLAY) {
20194                    // Override configuration of the default display duplicates global config, so
20195                    // we're calling global config update instead for default display. It will also
20196                    // apply the correct override config.
20197                    changes = updateGlobalConfiguration(values, false /* initLocale */,
20198                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20199                } else {
20200                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20201                }
20202            }
20203
20204            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20205        } finally {
20206            if (mWindowManager != null) {
20207                mWindowManager.continueSurfaceLayout();
20208            }
20209        }
20210
20211        if (result != null) {
20212            result.changes = changes;
20213            result.activityRelaunched = !kept;
20214        }
20215        return kept;
20216    }
20217
20218    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20219            int displayId) {
20220        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20221        final int changes = mTempConfig.updateFrom(values);
20222        if (changes == 0) {
20223            return 0;
20224        }
20225
20226        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
20227                + " for displayId=" + displayId);
20228        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20229
20230        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20231        if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20232            // Reset the unsupported display size dialog.
20233            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20234
20235            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20236        }
20237
20238        // Update the configuration with WM first and check if any of the stacks need to be resized
20239        // due to the configuration change. If so, resize the stacks now and do any relaunches if
20240        // necessary. This way we don't need to relaunch again afterwards in
20241        // ensureActivityConfigurationLocked().
20242        if (mWindowManager != null) {
20243            final int[] resizedStacks =
20244                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20245            if (resizedStacks != null) {
20246                for (int stackId : resizedStacks) {
20247                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20248                }
20249            }
20250        }
20251
20252        return changes;
20253    }
20254
20255    /** Applies latest configuration and/or visibility updates if needed. */
20256    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20257        boolean kept = true;
20258        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20259        // mainStack is null during startup.
20260        if (mainStack != null) {
20261            if (changes != 0 && starting == null) {
20262                // If the configuration changed, and the caller is not already
20263                // in the process of starting an activity, then find the top
20264                // activity to check if its configuration needs to change.
20265                starting = mainStack.topRunningActivityLocked();
20266            }
20267
20268            if (starting != null) {
20269                kept = starting.ensureActivityConfigurationLocked(changes,
20270                        false /* preserveWindow */);
20271                // And we need to make sure at this point that all other activities
20272                // are made visible with the correct configuration.
20273                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20274                        !PRESERVE_WINDOWS);
20275            }
20276        }
20277
20278        return kept;
20279    }
20280
20281    /** Helper method that requests bounds from WM and applies them to stack. */
20282    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20283        final Rect newStackBounds = new Rect();
20284        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20285        mStackSupervisor.resizeStackLocked(
20286                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20287                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20288                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20289    }
20290
20291    /**
20292     * Decide based on the configuration whether we should show the ANR,
20293     * crash, etc dialogs.  The idea is that if there is no affordance to
20294     * press the on-screen buttons, or the user experience would be more
20295     * greatly impacted than the crash itself, we shouldn't show the dialog.
20296     *
20297     * A thought: SystemUI might also want to get told about this, the Power
20298     * dialog / global actions also might want different behaviors.
20299     */
20300    private static boolean shouldShowDialogs(Configuration config) {
20301        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20302                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20303                                   && config.navigation == Configuration.NAVIGATION_NONAV);
20304        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20305        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20306                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20307                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20308                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20309        return inputMethodExists && uiModeSupportsDialogs;
20310    }
20311
20312    @Override
20313    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20314        synchronized (this) {
20315            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20316            if (srec != null) {
20317                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20318            }
20319        }
20320        return false;
20321    }
20322
20323    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20324            Intent resultData) {
20325
20326        synchronized (this) {
20327            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20328            if (r != null) {
20329                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20330            }
20331            return false;
20332        }
20333    }
20334
20335    public int getLaunchedFromUid(IBinder activityToken) {
20336        ActivityRecord srec;
20337        synchronized (this) {
20338            srec = ActivityRecord.forTokenLocked(activityToken);
20339        }
20340        if (srec == null) {
20341            return -1;
20342        }
20343        return srec.launchedFromUid;
20344    }
20345
20346    public String getLaunchedFromPackage(IBinder activityToken) {
20347        ActivityRecord srec;
20348        synchronized (this) {
20349            srec = ActivityRecord.forTokenLocked(activityToken);
20350        }
20351        if (srec == null) {
20352            return null;
20353        }
20354        return srec.launchedFromPackage;
20355    }
20356
20357    // =========================================================
20358    // LIFETIME MANAGEMENT
20359    // =========================================================
20360
20361    // Returns whether the app is receiving broadcast.
20362    // If receiving, fetch all broadcast queues which the app is
20363    // the current [or imminent] receiver on.
20364    private boolean isReceivingBroadcastLocked(ProcessRecord app,
20365            ArraySet<BroadcastQueue> receivingQueues) {
20366        if (!app.curReceivers.isEmpty()) {
20367            for (BroadcastRecord r : app.curReceivers) {
20368                receivingQueues.add(r.queue);
20369            }
20370            return true;
20371        }
20372
20373        // It's not the current receiver, but it might be starting up to become one
20374        for (BroadcastQueue queue : mBroadcastQueues) {
20375            final BroadcastRecord r = queue.mPendingBroadcast;
20376            if (r != null && r.curApp == app) {
20377                // found it; report which queue it's in
20378                receivingQueues.add(queue);
20379            }
20380        }
20381
20382        return !receivingQueues.isEmpty();
20383    }
20384
20385    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20386            int targetUid, ComponentName targetComponent, String targetProcess) {
20387        if (!mTrackingAssociations) {
20388            return null;
20389        }
20390        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20391                = mAssociations.get(targetUid);
20392        if (components == null) {
20393            components = new ArrayMap<>();
20394            mAssociations.put(targetUid, components);
20395        }
20396        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20397        if (sourceUids == null) {
20398            sourceUids = new SparseArray<>();
20399            components.put(targetComponent, sourceUids);
20400        }
20401        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20402        if (sourceProcesses == null) {
20403            sourceProcesses = new ArrayMap<>();
20404            sourceUids.put(sourceUid, sourceProcesses);
20405        }
20406        Association ass = sourceProcesses.get(sourceProcess);
20407        if (ass == null) {
20408            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20409                    targetProcess);
20410            sourceProcesses.put(sourceProcess, ass);
20411        }
20412        ass.mCount++;
20413        ass.mNesting++;
20414        if (ass.mNesting == 1) {
20415            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20416            ass.mLastState = sourceState;
20417        }
20418        return ass;
20419    }
20420
20421    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20422            ComponentName targetComponent) {
20423        if (!mTrackingAssociations) {
20424            return;
20425        }
20426        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20427                = mAssociations.get(targetUid);
20428        if (components == null) {
20429            return;
20430        }
20431        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20432        if (sourceUids == null) {
20433            return;
20434        }
20435        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20436        if (sourceProcesses == null) {
20437            return;
20438        }
20439        Association ass = sourceProcesses.get(sourceProcess);
20440        if (ass == null || ass.mNesting <= 0) {
20441            return;
20442        }
20443        ass.mNesting--;
20444        if (ass.mNesting == 0) {
20445            long uptime = SystemClock.uptimeMillis();
20446            ass.mTime += uptime - ass.mStartTime;
20447            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20448                    += uptime - ass.mLastStateUptime;
20449            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20450        }
20451    }
20452
20453    private void noteUidProcessState(final int uid, final int state) {
20454        mBatteryStatsService.noteUidProcessState(uid, state);
20455        if (mTrackingAssociations) {
20456            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20457                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20458                        = mAssociations.valueAt(i1);
20459                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20460                    SparseArray<ArrayMap<String, Association>> sourceUids
20461                            = targetComponents.valueAt(i2);
20462                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20463                    if (sourceProcesses != null) {
20464                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20465                            Association ass = sourceProcesses.valueAt(i4);
20466                            if (ass.mNesting >= 1) {
20467                                // currently associated
20468                                long uptime = SystemClock.uptimeMillis();
20469                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20470                                        += uptime - ass.mLastStateUptime;
20471                                ass.mLastState = state;
20472                                ass.mLastStateUptime = uptime;
20473                            }
20474                        }
20475                    }
20476                }
20477            }
20478        }
20479    }
20480
20481    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20482            boolean doingAll, long now) {
20483        if (mAdjSeq == app.adjSeq) {
20484            // This adjustment has already been computed.
20485            return app.curRawAdj;
20486        }
20487
20488        if (app.thread == null) {
20489            app.adjSeq = mAdjSeq;
20490            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20491            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20492            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20493        }
20494
20495        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20496        app.adjSource = null;
20497        app.adjTarget = null;
20498        app.empty = false;
20499        app.cached = false;
20500
20501        final int activitiesSize = app.activities.size();
20502
20503        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20504            // The max adjustment doesn't allow this app to be anything
20505            // below foreground, so it is not worth doing work for it.
20506            app.adjType = "fixed";
20507            app.adjSeq = mAdjSeq;
20508            app.curRawAdj = app.maxAdj;
20509            app.foregroundActivities = false;
20510            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20511            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20512            // System processes can do UI, and when they do we want to have
20513            // them trim their memory after the user leaves the UI.  To
20514            // facilitate this, here we need to determine whether or not it
20515            // is currently showing UI.
20516            app.systemNoUi = true;
20517            if (app == TOP_APP) {
20518                app.systemNoUi = false;
20519                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20520                app.adjType = "pers-top-activity";
20521            } else if (app.hasTopUi) {
20522                app.systemNoUi = false;
20523                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20524                app.adjType = "pers-top-ui";
20525            } else if (activitiesSize > 0) {
20526                for (int j = 0; j < activitiesSize; j++) {
20527                    final ActivityRecord r = app.activities.get(j);
20528                    if (r.visible) {
20529                        app.systemNoUi = false;
20530                    }
20531                }
20532            }
20533            if (!app.systemNoUi) {
20534                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20535            }
20536            return (app.curAdj=app.maxAdj);
20537        }
20538
20539        app.systemNoUi = false;
20540
20541        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20542
20543        // Determine the importance of the process, starting with most
20544        // important to least, and assign an appropriate OOM adjustment.
20545        int adj;
20546        int schedGroup;
20547        int procState;
20548        boolean foregroundActivities = false;
20549        mTmpBroadcastQueue.clear();
20550        if (app == TOP_APP) {
20551            // The last app on the list is the foreground app.
20552            adj = ProcessList.FOREGROUND_APP_ADJ;
20553            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20554            app.adjType = "top-activity";
20555            foregroundActivities = true;
20556            procState = PROCESS_STATE_CUR_TOP;
20557        } else if (app.instr != null) {
20558            // Don't want to kill running instrumentation.
20559            adj = ProcessList.FOREGROUND_APP_ADJ;
20560            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20561            app.adjType = "instrumentation";
20562            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20563        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20564            // An app that is currently receiving a broadcast also
20565            // counts as being in the foreground for OOM killer purposes.
20566            // It's placed in a sched group based on the nature of the
20567            // broadcast as reflected by which queue it's active in.
20568            adj = ProcessList.FOREGROUND_APP_ADJ;
20569            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20570                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20571            app.adjType = "broadcast";
20572            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20573        } else if (app.executingServices.size() > 0) {
20574            // An app that is currently executing a service callback also
20575            // counts as being in the foreground.
20576            adj = ProcessList.FOREGROUND_APP_ADJ;
20577            schedGroup = app.execServicesFg ?
20578                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20579            app.adjType = "exec-service";
20580            procState = ActivityManager.PROCESS_STATE_SERVICE;
20581            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20582        } else {
20583            // As far as we know the process is empty.  We may change our mind later.
20584            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20585            // At this point we don't actually know the adjustment.  Use the cached adj
20586            // value that the caller wants us to.
20587            adj = cachedAdj;
20588            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20589            app.cached = true;
20590            app.empty = true;
20591            app.adjType = "cch-empty";
20592        }
20593
20594        // Examine all activities if not already foreground.
20595        if (!foregroundActivities && activitiesSize > 0) {
20596            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20597            for (int j = 0; j < activitiesSize; j++) {
20598                final ActivityRecord r = app.activities.get(j);
20599                if (r.app != app) {
20600                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20601                            + " instead of expected " + app);
20602                    if (r.app == null || (r.app.uid == app.uid)) {
20603                        // Only fix things up when they look sane
20604                        r.app = app;
20605                    } else {
20606                        continue;
20607                    }
20608                }
20609                if (r.visible) {
20610                    // App has a visible activity; only upgrade adjustment.
20611                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20612                        adj = ProcessList.VISIBLE_APP_ADJ;
20613                        app.adjType = "visible";
20614                    }
20615                    if (procState > PROCESS_STATE_CUR_TOP) {
20616                        procState = PROCESS_STATE_CUR_TOP;
20617                    }
20618                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20619                    app.cached = false;
20620                    app.empty = false;
20621                    foregroundActivities = true;
20622                    final TaskRecord task = r.getTask();
20623                    if (task != null && minLayer > 0) {
20624                        final int layer = task.mLayerRank;
20625                        if (layer >= 0 && minLayer > layer) {
20626                            minLayer = layer;
20627                        }
20628                    }
20629                    break;
20630                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20631                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20632                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20633                        app.adjType = "pausing";
20634                    }
20635                    if (procState > PROCESS_STATE_CUR_TOP) {
20636                        procState = PROCESS_STATE_CUR_TOP;
20637                    }
20638                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20639                    app.cached = false;
20640                    app.empty = false;
20641                    foregroundActivities = true;
20642                } else if (r.state == ActivityState.STOPPING) {
20643                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20644                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20645                        app.adjType = "stopping";
20646                    }
20647                    // For the process state, we will at this point consider the
20648                    // process to be cached.  It will be cached either as an activity
20649                    // or empty depending on whether the activity is finishing.  We do
20650                    // this so that we can treat the process as cached for purposes of
20651                    // memory trimming (determing current memory level, trim command to
20652                    // send to process) since there can be an arbitrary number of stopping
20653                    // processes and they should soon all go into the cached state.
20654                    if (!r.finishing) {
20655                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20656                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20657                        }
20658                    }
20659                    app.cached = false;
20660                    app.empty = false;
20661                    foregroundActivities = true;
20662                } else {
20663                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20664                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20665                        app.adjType = "cch-act";
20666                    }
20667                }
20668            }
20669            if (adj == ProcessList.VISIBLE_APP_ADJ) {
20670                adj += minLayer;
20671            }
20672        }
20673
20674        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20675                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20676            if (app.foregroundServices) {
20677                // The user is aware of this app, so make it visible.
20678                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20679                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20680                app.cached = false;
20681                app.adjType = "fg-service";
20682                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20683            } else if (app.forcingToForeground != null) {
20684                // The user is aware of this app, so make it visible.
20685                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20686                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20687                app.cached = false;
20688                app.adjType = "force-fg";
20689                app.adjSource = app.forcingToForeground;
20690                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20691            } else if (app.hasOverlayUi) {
20692                // The process is display an overlay UI.
20693                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20694                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20695                app.cached = false;
20696                app.adjType = "has-overlay-ui";
20697                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20698            }
20699        }
20700
20701        if (app == mHeavyWeightProcess) {
20702            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
20703                // We don't want to kill the current heavy-weight process.
20704                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
20705                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20706                app.cached = false;
20707                app.adjType = "heavy";
20708            }
20709            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20710                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
20711            }
20712        }
20713
20714        if (app == mHomeProcess) {
20715            if (adj > ProcessList.HOME_APP_ADJ) {
20716                // This process is hosting what we currently consider to be the
20717                // home app, so we don't want to let it go into the background.
20718                adj = ProcessList.HOME_APP_ADJ;
20719                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20720                app.cached = false;
20721                app.adjType = "home";
20722            }
20723            if (procState > ActivityManager.PROCESS_STATE_HOME) {
20724                procState = ActivityManager.PROCESS_STATE_HOME;
20725            }
20726        }
20727
20728        if (app == mPreviousProcess && app.activities.size() > 0) {
20729            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20730                // This was the previous process that showed UI to the user.
20731                // We want to try to keep it around more aggressively, to give
20732                // a good experience around switching between two apps.
20733                adj = ProcessList.PREVIOUS_APP_ADJ;
20734                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20735                app.cached = false;
20736                app.adjType = "previous";
20737            }
20738            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20739                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20740            }
20741        }
20742
20743        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
20744                + " reason=" + app.adjType);
20745
20746        // By default, we use the computed adjustment.  It may be changed if
20747        // there are applications dependent on our services or providers, but
20748        // this gives us a baseline and makes sure we don't get into an
20749        // infinite recursion.
20750        app.adjSeq = mAdjSeq;
20751        app.curRawAdj = adj;
20752        app.hasStartedServices = false;
20753
20754        if (mBackupTarget != null && app == mBackupTarget.app) {
20755            // If possible we want to avoid killing apps while they're being backed up
20756            if (adj > ProcessList.BACKUP_APP_ADJ) {
20757                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
20758                adj = ProcessList.BACKUP_APP_ADJ;
20759                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20760                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20761                }
20762                app.adjType = "backup";
20763                app.cached = false;
20764            }
20765            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
20766                procState = ActivityManager.PROCESS_STATE_BACKUP;
20767            }
20768        }
20769
20770        boolean mayBeTop = false;
20771
20772        for (int is = app.services.size()-1;
20773                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20774                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20775                        || procState > ActivityManager.PROCESS_STATE_TOP);
20776                is--) {
20777            ServiceRecord s = app.services.valueAt(is);
20778            if (s.startRequested) {
20779                app.hasStartedServices = true;
20780                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
20781                    procState = ActivityManager.PROCESS_STATE_SERVICE;
20782                }
20783                if (app.hasShownUi && app != mHomeProcess) {
20784                    // If this process has shown some UI, let it immediately
20785                    // go to the LRU list because it may be pretty heavy with
20786                    // UI stuff.  We'll tag it with a label just to help
20787                    // debug and understand what is going on.
20788                    if (adj > ProcessList.SERVICE_ADJ) {
20789                        app.adjType = "cch-started-ui-services";
20790                    }
20791                } else {
20792                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20793                        // This service has seen some activity within
20794                        // recent memory, so we will keep its process ahead
20795                        // of the background processes.
20796                        if (adj > ProcessList.SERVICE_ADJ) {
20797                            adj = ProcessList.SERVICE_ADJ;
20798                            app.adjType = "started-services";
20799                            app.cached = false;
20800                        }
20801                    }
20802                    // If we have let the service slide into the background
20803                    // state, still have some text describing what it is doing
20804                    // even though the service no longer has an impact.
20805                    if (adj > ProcessList.SERVICE_ADJ) {
20806                        app.adjType = "cch-started-services";
20807                    }
20808                }
20809            }
20810
20811            for (int conni = s.connections.size()-1;
20812                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20813                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20814                            || procState > ActivityManager.PROCESS_STATE_TOP);
20815                    conni--) {
20816                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
20817                for (int i = 0;
20818                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
20819                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20820                                || procState > ActivityManager.PROCESS_STATE_TOP);
20821                        i++) {
20822                    // XXX should compute this based on the max of
20823                    // all connected clients.
20824                    ConnectionRecord cr = clist.get(i);
20825                    if (cr.binding.client == app) {
20826                        // Binding to ourself is not interesting.
20827                        continue;
20828                    }
20829
20830                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
20831                        ProcessRecord client = cr.binding.client;
20832                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
20833                                TOP_APP, doingAll, now);
20834                        int clientProcState = client.curProcState;
20835                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20836                            // If the other app is cached for any reason, for purposes here
20837                            // we are going to consider it empty.  The specific cached state
20838                            // doesn't propagate except under certain conditions.
20839                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20840                        }
20841                        String adjType = null;
20842                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
20843                            // Not doing bind OOM management, so treat
20844                            // this guy more like a started service.
20845                            if (app.hasShownUi && app != mHomeProcess) {
20846                                // If this process has shown some UI, let it immediately
20847                                // go to the LRU list because it may be pretty heavy with
20848                                // UI stuff.  We'll tag it with a label just to help
20849                                // debug and understand what is going on.
20850                                if (adj > clientAdj) {
20851                                    adjType = "cch-bound-ui-services";
20852                                }
20853                                app.cached = false;
20854                                clientAdj = adj;
20855                                clientProcState = procState;
20856                            } else {
20857                                if (now >= (s.lastActivity
20858                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20859                                    // This service has not seen activity within
20860                                    // recent memory, so allow it to drop to the
20861                                    // LRU list if there is no other reason to keep
20862                                    // it around.  We'll also tag it with a label just
20863                                    // to help debug and undertand what is going on.
20864                                    if (adj > clientAdj) {
20865                                        adjType = "cch-bound-services";
20866                                    }
20867                                    clientAdj = adj;
20868                                }
20869                            }
20870                        }
20871                        if (adj > clientAdj) {
20872                            // If this process has recently shown UI, and
20873                            // the process that is binding to it is less
20874                            // important than being visible, then we don't
20875                            // care about the binding as much as we care
20876                            // about letting this process get into the LRU
20877                            // list to be killed and restarted if needed for
20878                            // memory.
20879                            if (app.hasShownUi && app != mHomeProcess
20880                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20881                                adjType = "cch-bound-ui-services";
20882                            } else {
20883                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
20884                                        |Context.BIND_IMPORTANT)) != 0) {
20885                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
20886                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
20887                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
20888                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
20889                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20890                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20891                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
20892                                    adj = clientAdj;
20893                                } else {
20894                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20895                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
20896                                    }
20897                                }
20898                                if (!client.cached) {
20899                                    app.cached = false;
20900                                }
20901                                adjType = "service";
20902                            }
20903                        }
20904                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20905                            // This will treat important bound services identically to
20906                            // the top app, which may behave differently than generic
20907                            // foreground work.
20908                            if (client.curSchedGroup > schedGroup) {
20909                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20910                                    schedGroup = client.curSchedGroup;
20911                                } else {
20912                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20913                                }
20914                            }
20915                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20916                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20917                                    // Special handling of clients who are in the top state.
20918                                    // We *may* want to consider this process to be in the
20919                                    // top state as well, but only if there is not another
20920                                    // reason for it to be running.  Being on the top is a
20921                                    // special state, meaning you are specifically running
20922                                    // for the current top app.  If the process is already
20923                                    // running in the background for some other reason, it
20924                                    // is more important to continue considering it to be
20925                                    // in the background state.
20926                                    mayBeTop = true;
20927                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20928                                } else {
20929                                    // Special handling for above-top states (persistent
20930                                    // processes).  These should not bring the current process
20931                                    // into the top state, since they are not on top.  Instead
20932                                    // give them the best state after that.
20933                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
20934                                        clientProcState =
20935                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20936                                    } else if (mWakefulness
20937                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
20938                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
20939                                                    != 0) {
20940                                        clientProcState =
20941                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20942                                    } else {
20943                                        clientProcState =
20944                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20945                                    }
20946                                }
20947                            }
20948                        } else {
20949                            if (clientProcState <
20950                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20951                                clientProcState =
20952                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20953                            }
20954                        }
20955                        if (procState > clientProcState) {
20956                            procState = clientProcState;
20957                        }
20958                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20959                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
20960                            app.pendingUiClean = true;
20961                        }
20962                        if (adjType != null) {
20963                            app.adjType = adjType;
20964                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20965                                    .REASON_SERVICE_IN_USE;
20966                            app.adjSource = cr.binding.client;
20967                            app.adjSourceProcState = clientProcState;
20968                            app.adjTarget = s.name;
20969                        }
20970                    }
20971                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
20972                        app.treatLikeActivity = true;
20973                    }
20974                    final ActivityRecord a = cr.activity;
20975                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
20976                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
20977                            (a.visible || a.state == ActivityState.RESUMED ||
20978                             a.state == ActivityState.PAUSING)) {
20979                            adj = ProcessList.FOREGROUND_APP_ADJ;
20980                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20981                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20982                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
20983                                } else {
20984                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20985                                }
20986                            }
20987                            app.cached = false;
20988                            app.adjType = "service";
20989                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20990                                    .REASON_SERVICE_IN_USE;
20991                            app.adjSource = a;
20992                            app.adjSourceProcState = procState;
20993                            app.adjTarget = s.name;
20994                        }
20995                    }
20996                }
20997            }
20998        }
20999
21000        for (int provi = app.pubProviders.size()-1;
21001                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21002                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21003                        || procState > ActivityManager.PROCESS_STATE_TOP);
21004                provi--) {
21005            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21006            for (int i = cpr.connections.size()-1;
21007                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21008                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21009                            || procState > ActivityManager.PROCESS_STATE_TOP);
21010                    i--) {
21011                ContentProviderConnection conn = cpr.connections.get(i);
21012                ProcessRecord client = conn.client;
21013                if (client == app) {
21014                    // Being our own client is not interesting.
21015                    continue;
21016                }
21017                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21018                int clientProcState = client.curProcState;
21019                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21020                    // If the other app is cached for any reason, for purposes here
21021                    // we are going to consider it empty.
21022                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21023                }
21024                if (adj > clientAdj) {
21025                    if (app.hasShownUi && app != mHomeProcess
21026                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21027                        app.adjType = "cch-ui-provider";
21028                    } else {
21029                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21030                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21031                        app.adjType = "provider";
21032                    }
21033                    app.cached &= client.cached;
21034                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21035                            .REASON_PROVIDER_IN_USE;
21036                    app.adjSource = client;
21037                    app.adjSourceProcState = clientProcState;
21038                    app.adjTarget = cpr.name;
21039                }
21040                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21041                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21042                        // Special handling of clients who are in the top state.
21043                        // We *may* want to consider this process to be in the
21044                        // top state as well, but only if there is not another
21045                        // reason for it to be running.  Being on the top is a
21046                        // special state, meaning you are specifically running
21047                        // for the current top app.  If the process is already
21048                        // running in the background for some other reason, it
21049                        // is more important to continue considering it to be
21050                        // in the background state.
21051                        mayBeTop = true;
21052                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21053                    } else {
21054                        // Special handling for above-top states (persistent
21055                        // processes).  These should not bring the current process
21056                        // into the top state, since they are not on top.  Instead
21057                        // give them the best state after that.
21058                        clientProcState =
21059                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21060                    }
21061                }
21062                if (procState > clientProcState) {
21063                    procState = clientProcState;
21064                }
21065                if (client.curSchedGroup > schedGroup) {
21066                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21067                }
21068            }
21069            // If the provider has external (non-framework) process
21070            // dependencies, ensure that its adjustment is at least
21071            // FOREGROUND_APP_ADJ.
21072            if (cpr.hasExternalProcessHandles()) {
21073                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21074                    adj = ProcessList.FOREGROUND_APP_ADJ;
21075                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21076                    app.cached = false;
21077                    app.adjType = "provider";
21078                    app.adjTarget = cpr.name;
21079                }
21080                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21081                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21082                }
21083            }
21084        }
21085
21086        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
21087            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21088                adj = ProcessList.PREVIOUS_APP_ADJ;
21089                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21090                app.cached = false;
21091                app.adjType = "provider";
21092            }
21093            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21094                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21095            }
21096        }
21097
21098        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21099            // A client of one of our services or providers is in the top state.  We
21100            // *may* want to be in the top state, but not if we are already running in
21101            // the background for some other reason.  For the decision here, we are going
21102            // to pick out a few specific states that we want to remain in when a client
21103            // is top (states that tend to be longer-term) and otherwise allow it to go
21104            // to the top state.
21105            switch (procState) {
21106                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21107                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21108                case ActivityManager.PROCESS_STATE_SERVICE:
21109                    // These all are longer-term states, so pull them up to the top
21110                    // of the background states, but not all the way to the top state.
21111                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21112                    break;
21113                default:
21114                    // Otherwise, top is a better choice, so take it.
21115                    procState = ActivityManager.PROCESS_STATE_TOP;
21116                    break;
21117            }
21118        }
21119
21120        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21121            if (app.hasClientActivities) {
21122                // This is a cached process, but with client activities.  Mark it so.
21123                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21124                app.adjType = "cch-client-act";
21125            } else if (app.treatLikeActivity) {
21126                // This is a cached process, but somebody wants us to treat it like it has
21127                // an activity, okay!
21128                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21129                app.adjType = "cch-as-act";
21130            }
21131        }
21132
21133        if (adj == ProcessList.SERVICE_ADJ) {
21134            if (doingAll) {
21135                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21136                mNewNumServiceProcs++;
21137                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21138                if (!app.serviceb) {
21139                    // This service isn't far enough down on the LRU list to
21140                    // normally be a B service, but if we are low on RAM and it
21141                    // is large we want to force it down since we would prefer to
21142                    // keep launcher over it.
21143                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21144                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21145                        app.serviceHighRam = true;
21146                        app.serviceb = true;
21147                        //Slog.i(TAG, "ADJ " + app + " high ram!");
21148                    } else {
21149                        mNewNumAServiceProcs++;
21150                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
21151                    }
21152                } else {
21153                    app.serviceHighRam = false;
21154                }
21155            }
21156            if (app.serviceb) {
21157                adj = ProcessList.SERVICE_B_ADJ;
21158            }
21159        }
21160
21161        app.curRawAdj = adj;
21162
21163        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21164        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21165        if (adj > app.maxAdj) {
21166            adj = app.maxAdj;
21167            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21168                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21169            }
21170        }
21171
21172        // Do final modification to adj.  Everything we do between here and applying
21173        // the final setAdj must be done in this function, because we will also use
21174        // it when computing the final cached adj later.  Note that we don't need to
21175        // worry about this for max adj above, since max adj will always be used to
21176        // keep it out of the cached vaues.
21177        app.curAdj = app.modifyRawOomAdj(adj);
21178        app.curSchedGroup = schedGroup;
21179        app.curProcState = procState;
21180        app.foregroundActivities = foregroundActivities;
21181
21182        return app.curRawAdj;
21183    }
21184
21185    /**
21186     * Record new PSS sample for a process.
21187     */
21188    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21189            long now) {
21190        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21191                swapPss * 1024);
21192        proc.lastPssTime = now;
21193        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21194        if (DEBUG_PSS) Slog.d(TAG_PSS,
21195                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21196                + " state=" + ProcessList.makeProcStateString(procState));
21197        if (proc.initialIdlePss == 0) {
21198            proc.initialIdlePss = pss;
21199        }
21200        proc.lastPss = pss;
21201        proc.lastSwapPss = swapPss;
21202        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21203            proc.lastCachedPss = pss;
21204            proc.lastCachedSwapPss = swapPss;
21205        }
21206
21207        final SparseArray<Pair<Long, String>> watchUids
21208                = mMemWatchProcesses.getMap().get(proc.processName);
21209        Long check = null;
21210        if (watchUids != null) {
21211            Pair<Long, String> val = watchUids.get(proc.uid);
21212            if (val == null) {
21213                val = watchUids.get(0);
21214            }
21215            if (val != null) {
21216                check = val.first;
21217            }
21218        }
21219        if (check != null) {
21220            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21221                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21222                if (!isDebuggable) {
21223                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21224                        isDebuggable = true;
21225                    }
21226                }
21227                if (isDebuggable) {
21228                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21229                    final ProcessRecord myProc = proc;
21230                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
21231                    mMemWatchDumpProcName = proc.processName;
21232                    mMemWatchDumpFile = heapdumpFile.toString();
21233                    mMemWatchDumpPid = proc.pid;
21234                    mMemWatchDumpUid = proc.uid;
21235                    BackgroundThread.getHandler().post(new Runnable() {
21236                        @Override
21237                        public void run() {
21238                            revokeUriPermission(ActivityThread.currentActivityThread()
21239                                            .getApplicationThread(),
21240                                    null, DumpHeapActivity.JAVA_URI,
21241                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
21242                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21243                                    UserHandle.myUserId());
21244                            ParcelFileDescriptor fd = null;
21245                            try {
21246                                heapdumpFile.delete();
21247                                fd = ParcelFileDescriptor.open(heapdumpFile,
21248                                        ParcelFileDescriptor.MODE_CREATE |
21249                                                ParcelFileDescriptor.MODE_TRUNCATE |
21250                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
21251                                                ParcelFileDescriptor.MODE_APPEND);
21252                                IApplicationThread thread = myProc.thread;
21253                                if (thread != null) {
21254                                    try {
21255                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
21256                                                "Requesting dump heap from "
21257                                                + myProc + " to " + heapdumpFile);
21258                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
21259                                    } catch (RemoteException e) {
21260                                    }
21261                                }
21262                            } catch (FileNotFoundException e) {
21263                                e.printStackTrace();
21264                            } finally {
21265                                if (fd != null) {
21266                                    try {
21267                                        fd.close();
21268                                    } catch (IOException e) {
21269                                    }
21270                                }
21271                            }
21272                        }
21273                    });
21274                } else {
21275                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21276                            + ", but debugging not enabled");
21277                }
21278            }
21279        }
21280    }
21281
21282    /**
21283     * Schedule PSS collection of a process.
21284     */
21285    void requestPssLocked(ProcessRecord proc, int procState) {
21286        if (mPendingPssProcesses.contains(proc)) {
21287            return;
21288        }
21289        if (mPendingPssProcesses.size() == 0) {
21290            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21291        }
21292        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21293        proc.pssProcState = procState;
21294        mPendingPssProcesses.add(proc);
21295    }
21296
21297    /**
21298     * Schedule PSS collection of all processes.
21299     */
21300    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21301        if (!always) {
21302            if (now < (mLastFullPssTime +
21303                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
21304                return;
21305            }
21306        }
21307        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21308        mLastFullPssTime = now;
21309        mFullPssPending = true;
21310        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21311        mPendingPssProcesses.clear();
21312        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21313            ProcessRecord app = mLruProcesses.get(i);
21314            if (app.thread == null
21315                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21316                continue;
21317            }
21318            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21319                app.pssProcState = app.setProcState;
21320                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21321                        mTestPssMode, isSleepingLocked(), now);
21322                mPendingPssProcesses.add(app);
21323            }
21324        }
21325        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21326    }
21327
21328    public void setTestPssMode(boolean enabled) {
21329        synchronized (this) {
21330            mTestPssMode = enabled;
21331            if (enabled) {
21332                // Whenever we enable the mode, we want to take a snapshot all of current
21333                // process mem use.
21334                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21335            }
21336        }
21337    }
21338
21339    /**
21340     * Ask a given process to GC right now.
21341     */
21342    final void performAppGcLocked(ProcessRecord app) {
21343        try {
21344            app.lastRequestedGc = SystemClock.uptimeMillis();
21345            if (app.thread != null) {
21346                if (app.reportLowMemory) {
21347                    app.reportLowMemory = false;
21348                    app.thread.scheduleLowMemory();
21349                } else {
21350                    app.thread.processInBackground();
21351                }
21352            }
21353        } catch (Exception e) {
21354            // whatever.
21355        }
21356    }
21357
21358    /**
21359     * Returns true if things are idle enough to perform GCs.
21360     */
21361    private final boolean canGcNowLocked() {
21362        boolean processingBroadcasts = false;
21363        for (BroadcastQueue q : mBroadcastQueues) {
21364            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21365                processingBroadcasts = true;
21366            }
21367        }
21368        return !processingBroadcasts
21369                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21370    }
21371
21372    /**
21373     * Perform GCs on all processes that are waiting for it, but only
21374     * if things are idle.
21375     */
21376    final void performAppGcsLocked() {
21377        final int N = mProcessesToGc.size();
21378        if (N <= 0) {
21379            return;
21380        }
21381        if (canGcNowLocked()) {
21382            while (mProcessesToGc.size() > 0) {
21383                ProcessRecord proc = mProcessesToGc.remove(0);
21384                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21385                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
21386                            <= SystemClock.uptimeMillis()) {
21387                        // To avoid spamming the system, we will GC processes one
21388                        // at a time, waiting a few seconds between each.
21389                        performAppGcLocked(proc);
21390                        scheduleAppGcsLocked();
21391                        return;
21392                    } else {
21393                        // It hasn't been long enough since we last GCed this
21394                        // process...  put it in the list to wait for its time.
21395                        addProcessToGcListLocked(proc);
21396                        break;
21397                    }
21398                }
21399            }
21400
21401            scheduleAppGcsLocked();
21402        }
21403    }
21404
21405    /**
21406     * If all looks good, perform GCs on all processes waiting for them.
21407     */
21408    final void performAppGcsIfAppropriateLocked() {
21409        if (canGcNowLocked()) {
21410            performAppGcsLocked();
21411            return;
21412        }
21413        // Still not idle, wait some more.
21414        scheduleAppGcsLocked();
21415    }
21416
21417    /**
21418     * Schedule the execution of all pending app GCs.
21419     */
21420    final void scheduleAppGcsLocked() {
21421        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21422
21423        if (mProcessesToGc.size() > 0) {
21424            // Schedule a GC for the time to the next process.
21425            ProcessRecord proc = mProcessesToGc.get(0);
21426            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21427
21428            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
21429            long now = SystemClock.uptimeMillis();
21430            if (when < (now+GC_TIMEOUT)) {
21431                when = now + GC_TIMEOUT;
21432            }
21433            mHandler.sendMessageAtTime(msg, when);
21434        }
21435    }
21436
21437    /**
21438     * Add a process to the array of processes waiting to be GCed.  Keeps the
21439     * list in sorted order by the last GC time.  The process can't already be
21440     * on the list.
21441     */
21442    final void addProcessToGcListLocked(ProcessRecord proc) {
21443        boolean added = false;
21444        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21445            if (mProcessesToGc.get(i).lastRequestedGc <
21446                    proc.lastRequestedGc) {
21447                added = true;
21448                mProcessesToGc.add(i+1, proc);
21449                break;
21450            }
21451        }
21452        if (!added) {
21453            mProcessesToGc.add(0, proc);
21454        }
21455    }
21456
21457    /**
21458     * Set up to ask a process to GC itself.  This will either do it
21459     * immediately, or put it on the list of processes to gc the next
21460     * time things are idle.
21461     */
21462    final void scheduleAppGcLocked(ProcessRecord app) {
21463        long now = SystemClock.uptimeMillis();
21464        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
21465            return;
21466        }
21467        if (!mProcessesToGc.contains(app)) {
21468            addProcessToGcListLocked(app);
21469            scheduleAppGcsLocked();
21470        }
21471    }
21472
21473    final void checkExcessivePowerUsageLocked(boolean doKills) {
21474        updateCpuStatsNow();
21475
21476        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21477        boolean doWakeKills = doKills;
21478        boolean doCpuKills = doKills;
21479        if (mLastPowerCheckRealtime == 0) {
21480            doWakeKills = false;
21481        }
21482        if (mLastPowerCheckUptime == 0) {
21483            doCpuKills = false;
21484        }
21485        if (stats.isScreenOn()) {
21486            doWakeKills = false;
21487        }
21488        final long curRealtime = SystemClock.elapsedRealtime();
21489        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21490        final long curUptime = SystemClock.uptimeMillis();
21491        final long uptimeSince = curUptime - mLastPowerCheckUptime;
21492        mLastPowerCheckRealtime = curRealtime;
21493        mLastPowerCheckUptime = curUptime;
21494        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
21495            doWakeKills = false;
21496        }
21497        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
21498            doCpuKills = false;
21499        }
21500        int i = mLruProcesses.size();
21501        while (i > 0) {
21502            i--;
21503            ProcessRecord app = mLruProcesses.get(i);
21504            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21505                long wtime;
21506                synchronized (stats) {
21507                    wtime = stats.getProcessWakeTime(app.info.uid,
21508                            app.pid, curRealtime);
21509                }
21510                long wtimeUsed = wtime - app.lastWakeTime;
21511                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21512                if (DEBUG_POWER) {
21513                    StringBuilder sb = new StringBuilder(128);
21514                    sb.append("Wake for ");
21515                    app.toShortString(sb);
21516                    sb.append(": over ");
21517                    TimeUtils.formatDuration(realtimeSince, sb);
21518                    sb.append(" used ");
21519                    TimeUtils.formatDuration(wtimeUsed, sb);
21520                    sb.append(" (");
21521                    sb.append((wtimeUsed*100)/realtimeSince);
21522                    sb.append("%)");
21523                    Slog.i(TAG_POWER, sb.toString());
21524                    sb.setLength(0);
21525                    sb.append("CPU for ");
21526                    app.toShortString(sb);
21527                    sb.append(": over ");
21528                    TimeUtils.formatDuration(uptimeSince, sb);
21529                    sb.append(" used ");
21530                    TimeUtils.formatDuration(cputimeUsed, sb);
21531                    sb.append(" (");
21532                    sb.append((cputimeUsed*100)/uptimeSince);
21533                    sb.append("%)");
21534                    Slog.i(TAG_POWER, sb.toString());
21535                }
21536                // If a process has held a wake lock for more
21537                // than 50% of the time during this period,
21538                // that sounds bad.  Kill!
21539                if (doWakeKills && realtimeSince > 0
21540                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
21541                    synchronized (stats) {
21542                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21543                                realtimeSince, wtimeUsed);
21544                    }
21545                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21546                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21547                } else if (doCpuKills && uptimeSince > 0
21548                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
21549                    synchronized (stats) {
21550                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21551                                uptimeSince, cputimeUsed);
21552                    }
21553                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21554                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21555                } else {
21556                    app.lastWakeTime = wtime;
21557                    app.lastCpuTime = app.curCpuTime;
21558                }
21559            }
21560        }
21561    }
21562
21563    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21564            long nowElapsed) {
21565        boolean success = true;
21566
21567        if (app.curRawAdj != app.setRawAdj) {
21568            app.setRawAdj = app.curRawAdj;
21569        }
21570
21571        int changes = 0;
21572
21573        if (app.curAdj != app.setAdj) {
21574            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21575            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21576                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21577                    + app.adjType);
21578            app.setAdj = app.curAdj;
21579            app.verifiedAdj = ProcessList.INVALID_ADJ;
21580        }
21581
21582        if (app.setSchedGroup != app.curSchedGroup) {
21583            int oldSchedGroup = app.setSchedGroup;
21584            app.setSchedGroup = app.curSchedGroup;
21585            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21586                    "Setting sched group of " + app.processName
21587                    + " to " + app.curSchedGroup);
21588            if (app.waitingToKill != null && app.curReceivers.isEmpty()
21589                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21590                app.kill(app.waitingToKill, true);
21591                success = false;
21592            } else {
21593                int processGroup;
21594                switch (app.curSchedGroup) {
21595                    case ProcessList.SCHED_GROUP_BACKGROUND:
21596                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21597                        break;
21598                    case ProcessList.SCHED_GROUP_TOP_APP:
21599                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21600                        processGroup = THREAD_GROUP_TOP_APP;
21601                        break;
21602                    default:
21603                        processGroup = THREAD_GROUP_DEFAULT;
21604                        break;
21605                }
21606                long oldId = Binder.clearCallingIdentity();
21607                try {
21608                    setProcessGroup(app.pid, processGroup);
21609                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21610                        // do nothing if we already switched to RT
21611                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21612                            mVrController.onTopProcChangedLocked(app);
21613                            if (mUseFifoUiScheduling) {
21614                                // Switch UI pipeline for app to SCHED_FIFO
21615                                app.savedPriority = Process.getThreadPriority(app.pid);
21616                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
21617                                if (app.renderThreadTid != 0) {
21618                                    scheduleAsFifoPriority(app.renderThreadTid,
21619                                        /* suppressLogs */true);
21620                                    if (DEBUG_OOM_ADJ) {
21621                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
21622                                            app.renderThreadTid + ") to FIFO");
21623                                    }
21624                                } else {
21625                                    if (DEBUG_OOM_ADJ) {
21626                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
21627                                    }
21628                                }
21629                            } else {
21630                                // Boost priority for top app UI and render threads
21631                                setThreadPriority(app.pid, -10);
21632                                if (app.renderThreadTid != 0) {
21633                                    try {
21634                                        setThreadPriority(app.renderThreadTid, -10);
21635                                    } catch (IllegalArgumentException e) {
21636                                        // thread died, ignore
21637                                    }
21638                                }
21639                            }
21640                        }
21641                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
21642                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21643                        mVrController.onTopProcChangedLocked(app);
21644                        if (mUseFifoUiScheduling) {
21645                            // Reset UI pipeline to SCHED_OTHER
21646                            setThreadScheduler(app.pid, SCHED_OTHER, 0);
21647                            setThreadPriority(app.pid, app.savedPriority);
21648                            if (app.renderThreadTid != 0) {
21649                                setThreadScheduler(app.renderThreadTid,
21650                                    SCHED_OTHER, 0);
21651                                setThreadPriority(app.renderThreadTid, -4);
21652                            }
21653                        } else {
21654                            // Reset priority for top app UI and render threads
21655                            setThreadPriority(app.pid, 0);
21656                            if (app.renderThreadTid != 0) {
21657                                setThreadPriority(app.renderThreadTid, 0);
21658                            }
21659                        }
21660                    }
21661                } catch (Exception e) {
21662                    Slog.w(TAG, "Failed setting process group of " + app.pid
21663                            + " to " + app.curSchedGroup);
21664                    e.printStackTrace();
21665                } finally {
21666                    Binder.restoreCallingIdentity(oldId);
21667                }
21668            }
21669        }
21670        if (app.repForegroundActivities != app.foregroundActivities) {
21671            app.repForegroundActivities = app.foregroundActivities;
21672            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
21673        }
21674        if (app.repProcState != app.curProcState) {
21675            app.repProcState = app.curProcState;
21676            if (app.thread != null) {
21677                try {
21678                    if (false) {
21679                        //RuntimeException h = new RuntimeException("here");
21680                        Slog.i(TAG, "Sending new process state " + app.repProcState
21681                                + " to " + app /*, h*/);
21682                    }
21683                    app.thread.setProcessState(app.repProcState);
21684                } catch (RemoteException e) {
21685                }
21686            }
21687        }
21688        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
21689                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
21690            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
21691                // Experimental code to more aggressively collect pss while
21692                // running test...  the problem is that this tends to collect
21693                // the data right when a process is transitioning between process
21694                // states, which well tend to give noisy data.
21695                long start = SystemClock.uptimeMillis();
21696                long pss = Debug.getPss(app.pid, mTmpLong, null);
21697                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
21698                mPendingPssProcesses.remove(app);
21699                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
21700                        + " to " + app.curProcState + ": "
21701                        + (SystemClock.uptimeMillis()-start) + "ms");
21702            }
21703            app.lastStateTime = now;
21704            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21705                    mTestPssMode, isSleepingLocked(), now);
21706            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
21707                    + ProcessList.makeProcStateString(app.setProcState) + " to "
21708                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
21709                    + (app.nextPssTime-now) + ": " + app);
21710        } else {
21711            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
21712                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
21713                    mTestPssMode)))) {
21714                requestPssLocked(app, app.setProcState);
21715                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
21716                        mTestPssMode, isSleepingLocked(), now);
21717            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
21718                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
21719        }
21720        if (app.setProcState != app.curProcState) {
21721            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21722                    "Proc state change of " + app.processName
21723                            + " to " + app.curProcState);
21724            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
21725            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
21726            if (setImportant && !curImportant) {
21727                // This app is no longer something we consider important enough to allow to
21728                // use arbitrary amounts of battery power.  Note
21729                // its current wake lock time to later know to kill it if
21730                // it is not behaving well.
21731                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21732                synchronized (stats) {
21733                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
21734                            app.pid, nowElapsed);
21735                }
21736                app.lastCpuTime = app.curCpuTime;
21737
21738            }
21739            // Inform UsageStats of important process state change
21740            // Must be called before updating setProcState
21741            maybeUpdateUsageStatsLocked(app, nowElapsed);
21742
21743            app.setProcState = app.curProcState;
21744            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21745                app.notCachedSinceIdle = false;
21746            }
21747            if (!doingAll) {
21748                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
21749            } else {
21750                app.procStateChanged = true;
21751            }
21752        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
21753                > USAGE_STATS_INTERACTION_INTERVAL) {
21754            // For apps that sit around for a long time in the interactive state, we need
21755            // to report this at least once a day so they don't go idle.
21756            maybeUpdateUsageStatsLocked(app, nowElapsed);
21757        }
21758
21759        if (changes != 0) {
21760            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21761                    "Changes in " + app + ": " + changes);
21762            int i = mPendingProcessChanges.size()-1;
21763            ProcessChangeItem item = null;
21764            while (i >= 0) {
21765                item = mPendingProcessChanges.get(i);
21766                if (item.pid == app.pid) {
21767                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21768                            "Re-using existing item: " + item);
21769                    break;
21770                }
21771                i--;
21772            }
21773            if (i < 0) {
21774                // No existing item in pending changes; need a new one.
21775                final int NA = mAvailProcessChanges.size();
21776                if (NA > 0) {
21777                    item = mAvailProcessChanges.remove(NA-1);
21778                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21779                            "Retrieving available item: " + item);
21780                } else {
21781                    item = new ProcessChangeItem();
21782                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21783                            "Allocating new item: " + item);
21784                }
21785                item.changes = 0;
21786                item.pid = app.pid;
21787                item.uid = app.info.uid;
21788                if (mPendingProcessChanges.size() == 0) {
21789                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21790                            "*** Enqueueing dispatch processes changed!");
21791                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
21792                }
21793                mPendingProcessChanges.add(item);
21794            }
21795            item.changes |= changes;
21796            item.foregroundActivities = app.repForegroundActivities;
21797            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21798                    "Item " + Integer.toHexString(System.identityHashCode(item))
21799                    + " " + app.toShortString() + ": changes=" + item.changes
21800                    + " foreground=" + item.foregroundActivities
21801                    + " type=" + app.adjType + " source=" + app.adjSource
21802                    + " target=" + app.adjTarget);
21803        }
21804
21805        return success;
21806    }
21807
21808    private boolean isEphemeralLocked(int uid) {
21809        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
21810        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
21811            return false;
21812        }
21813        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
21814                packages[0]);
21815    }
21816
21817    @VisibleForTesting
21818    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
21819        final UidRecord.ChangeItem pendingChange;
21820        if (uidRec == null || uidRec.pendingChange == null) {
21821            if (mPendingUidChanges.size() == 0) {
21822                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21823                        "*** Enqueueing dispatch uid changed!");
21824                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
21825            }
21826            final int NA = mAvailUidChanges.size();
21827            if (NA > 0) {
21828                pendingChange = mAvailUidChanges.remove(NA-1);
21829                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21830                        "Retrieving available item: " + pendingChange);
21831            } else {
21832                pendingChange = new UidRecord.ChangeItem();
21833                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21834                        "Allocating new item: " + pendingChange);
21835            }
21836            if (uidRec != null) {
21837                uidRec.pendingChange = pendingChange;
21838                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
21839                    // If this uid is going away, and we haven't yet reported it is gone,
21840                    // then do so now.
21841                    change = UidRecord.CHANGE_GONE_IDLE;
21842                }
21843            } else if (uid < 0) {
21844                throw new IllegalArgumentException("No UidRecord or uid");
21845            }
21846            pendingChange.uidRecord = uidRec;
21847            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
21848            mPendingUidChanges.add(pendingChange);
21849        } else {
21850            pendingChange = uidRec.pendingChange;
21851            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
21852                change = UidRecord.CHANGE_GONE_IDLE;
21853            }
21854        }
21855        pendingChange.change = change;
21856        pendingChange.processState = uidRec != null
21857                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
21858        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
21859        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
21860        if (uidRec != null) {
21861            uidRec.updateLastDispatchedProcStateSeq(change);
21862        }
21863
21864        // Directly update the power manager, since we sit on top of it and it is critical
21865        // it be kept in sync (so wake locks will be held as soon as appropriate).
21866        if (mLocalPowerManager != null) {
21867            switch (change) {
21868                case UidRecord.CHANGE_GONE:
21869                case UidRecord.CHANGE_GONE_IDLE:
21870                    mLocalPowerManager.uidGone(pendingChange.uid);
21871                    break;
21872                case UidRecord.CHANGE_IDLE:
21873                    mLocalPowerManager.uidIdle(pendingChange.uid);
21874                    break;
21875                case UidRecord.CHANGE_ACTIVE:
21876                    mLocalPowerManager.uidActive(pendingChange.uid);
21877                    break;
21878                default:
21879                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
21880                            pendingChange.processState);
21881                    break;
21882            }
21883        }
21884    }
21885
21886    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
21887            String authority) {
21888        if (app == null) return;
21889        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21890            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
21891            if (userState == null) return;
21892            final long now = SystemClock.elapsedRealtime();
21893            Long lastReported = userState.mProviderLastReportedFg.get(authority);
21894            if (lastReported == null || lastReported < now - 60 * 1000L) {
21895                if (mSystemReady) {
21896                    // Cannot touch the user stats if not system ready
21897                    mUsageStatsService.reportContentProviderUsage(
21898                            authority, providerPkgName, app.userId);
21899                }
21900                userState.mProviderLastReportedFg.put(authority, now);
21901            }
21902        }
21903    }
21904
21905    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
21906        if (DEBUG_USAGE_STATS) {
21907            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
21908                    + "] state changes: old = " + app.setProcState + ", new = "
21909                    + app.curProcState);
21910        }
21911        if (mUsageStatsService == null) {
21912            return;
21913        }
21914        boolean isInteraction;
21915        // To avoid some abuse patterns, we are going to be careful about what we consider
21916        // to be an app interaction.  Being the top activity doesn't count while the display
21917        // is sleeping, nor do short foreground services.
21918        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
21919            isInteraction = true;
21920            app.fgInteractionTime = 0;
21921        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
21922            if (app.fgInteractionTime == 0) {
21923                app.fgInteractionTime = nowElapsed;
21924                isInteraction = false;
21925            } else {
21926                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
21927            }
21928        } else {
21929            // If the app was being forced to the foreground, by say a Toast, then
21930            // no need to treat it as an interaction
21931            isInteraction = app.forcingToForeground == null
21932                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21933            app.fgInteractionTime = 0;
21934        }
21935        if (isInteraction && (!app.reportedInteraction
21936                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
21937            app.interactionEventTime = nowElapsed;
21938            String[] packages = app.getPackageList();
21939            if (packages != null) {
21940                for (int i = 0; i < packages.length; i++) {
21941                    mUsageStatsService.reportEvent(packages[i], app.userId,
21942                            UsageEvents.Event.SYSTEM_INTERACTION);
21943                }
21944            }
21945        }
21946        app.reportedInteraction = isInteraction;
21947        if (!isInteraction) {
21948            app.interactionEventTime = 0;
21949        }
21950    }
21951
21952    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
21953        if (proc.thread != null) {
21954            if (proc.baseProcessTracker != null) {
21955                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
21956            }
21957        }
21958    }
21959
21960    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
21961            ProcessRecord TOP_APP, boolean doingAll, long now) {
21962        if (app.thread == null) {
21963            return false;
21964        }
21965
21966        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
21967
21968        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
21969    }
21970
21971    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
21972            boolean oomAdj) {
21973        if (isForeground != proc.foregroundServices) {
21974            proc.foregroundServices = isForeground;
21975            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
21976                    proc.info.uid);
21977            if (isForeground) {
21978                if (curProcs == null) {
21979                    curProcs = new ArrayList<ProcessRecord>();
21980                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
21981                }
21982                if (!curProcs.contains(proc)) {
21983                    curProcs.add(proc);
21984                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
21985                            proc.info.packageName, proc.info.uid);
21986                }
21987            } else {
21988                if (curProcs != null) {
21989                    if (curProcs.remove(proc)) {
21990                        mBatteryStatsService.noteEvent(
21991                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
21992                                proc.info.packageName, proc.info.uid);
21993                        if (curProcs.size() <= 0) {
21994                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
21995                        }
21996                    }
21997                }
21998            }
21999            if (oomAdj) {
22000                updateOomAdjLocked();
22001            }
22002        }
22003    }
22004
22005    private final ActivityRecord resumedAppLocked() {
22006        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22007        String pkg;
22008        int uid;
22009        if (act != null) {
22010            pkg = act.packageName;
22011            uid = act.info.applicationInfo.uid;
22012        } else {
22013            pkg = null;
22014            uid = -1;
22015        }
22016        // Has the UID or resumed package name changed?
22017        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22018                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22019            if (mCurResumedPackage != null) {
22020                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22021                        mCurResumedPackage, mCurResumedUid);
22022            }
22023            mCurResumedPackage = pkg;
22024            mCurResumedUid = uid;
22025            if (mCurResumedPackage != null) {
22026                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22027                        mCurResumedPackage, mCurResumedUid);
22028            }
22029        }
22030        return act;
22031    }
22032
22033    final boolean updateOomAdjLocked(ProcessRecord app) {
22034        final ActivityRecord TOP_ACT = resumedAppLocked();
22035        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22036        final boolean wasCached = app.cached;
22037
22038        mAdjSeq++;
22039
22040        // This is the desired cached adjusment we want to tell it to use.
22041        // If our app is currently cached, we know it, and that is it.  Otherwise,
22042        // we don't know it yet, and it needs to now be cached we will then
22043        // need to do a complete oom adj.
22044        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22045                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22046        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22047                SystemClock.uptimeMillis());
22048        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
22049            // Changed to/from cached state, so apps after it in the LRU
22050            // list may also be changed.
22051            updateOomAdjLocked();
22052        }
22053        return success;
22054    }
22055
22056    final void updateOomAdjLocked() {
22057        final ActivityRecord TOP_ACT = resumedAppLocked();
22058        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22059        final long now = SystemClock.uptimeMillis();
22060        final long nowElapsed = SystemClock.elapsedRealtime();
22061        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22062        final int N = mLruProcesses.size();
22063
22064        if (false) {
22065            RuntimeException e = new RuntimeException();
22066            e.fillInStackTrace();
22067            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22068        }
22069
22070        // Reset state in all uid records.
22071        for (int i=mActiveUids.size()-1; i>=0; i--) {
22072            final UidRecord uidRec = mActiveUids.valueAt(i);
22073            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22074                    "Starting update of " + uidRec);
22075            uidRec.reset();
22076        }
22077
22078        mStackSupervisor.rankTaskLayersIfNeeded();
22079
22080        mAdjSeq++;
22081        mNewNumServiceProcs = 0;
22082        mNewNumAServiceProcs = 0;
22083
22084        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22085        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22086
22087        // Let's determine how many processes we have running vs.
22088        // how many slots we have for background processes; we may want
22089        // to put multiple processes in a slot of there are enough of
22090        // them.
22091        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22092                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22093        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22094        if (numEmptyProcs > cachedProcessLimit) {
22095            // If there are more empty processes than our limit on cached
22096            // processes, then use the cached process limit for the factor.
22097            // This ensures that the really old empty processes get pushed
22098            // down to the bottom, so if we are running low on memory we will
22099            // have a better chance at keeping around more cached processes
22100            // instead of a gazillion empty processes.
22101            numEmptyProcs = cachedProcessLimit;
22102        }
22103        int emptyFactor = numEmptyProcs/numSlots;
22104        if (emptyFactor < 1) emptyFactor = 1;
22105        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22106        if (cachedFactor < 1) cachedFactor = 1;
22107        int stepCached = 0;
22108        int stepEmpty = 0;
22109        int numCached = 0;
22110        int numEmpty = 0;
22111        int numTrimming = 0;
22112
22113        mNumNonCachedProcs = 0;
22114        mNumCachedHiddenProcs = 0;
22115
22116        // First update the OOM adjustment for each of the
22117        // application processes based on their current state.
22118        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22119        int nextCachedAdj = curCachedAdj+1;
22120        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22121        int nextEmptyAdj = curEmptyAdj+2;
22122        for (int i=N-1; i>=0; i--) {
22123            ProcessRecord app = mLruProcesses.get(i);
22124            if (!app.killedByAm && app.thread != null) {
22125                app.procStateChanged = false;
22126                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22127
22128                // If we haven't yet assigned the final cached adj
22129                // to the process, do that now.
22130                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22131                    switch (app.curProcState) {
22132                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22133                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22134                            // This process is a cached process holding activities...
22135                            // assign it the next cached value for that type, and then
22136                            // step that cached level.
22137                            app.curRawAdj = curCachedAdj;
22138                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22139                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22140                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22141                                    + ")");
22142                            if (curCachedAdj != nextCachedAdj) {
22143                                stepCached++;
22144                                if (stepCached >= cachedFactor) {
22145                                    stepCached = 0;
22146                                    curCachedAdj = nextCachedAdj;
22147                                    nextCachedAdj += 2;
22148                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22149                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22150                                    }
22151                                }
22152                            }
22153                            break;
22154                        default:
22155                            // For everything else, assign next empty cached process
22156                            // level and bump that up.  Note that this means that
22157                            // long-running services that have dropped down to the
22158                            // cached level will be treated as empty (since their process
22159                            // state is still as a service), which is what we want.
22160                            app.curRawAdj = curEmptyAdj;
22161                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22162                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22163                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22164                                    + ")");
22165                            if (curEmptyAdj != nextEmptyAdj) {
22166                                stepEmpty++;
22167                                if (stepEmpty >= emptyFactor) {
22168                                    stepEmpty = 0;
22169                                    curEmptyAdj = nextEmptyAdj;
22170                                    nextEmptyAdj += 2;
22171                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22172                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22173                                    }
22174                                }
22175                            }
22176                            break;
22177                    }
22178                }
22179
22180                applyOomAdjLocked(app, true, now, nowElapsed);
22181
22182                // Count the number of process types.
22183                switch (app.curProcState) {
22184                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22185                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22186                        mNumCachedHiddenProcs++;
22187                        numCached++;
22188                        if (numCached > cachedProcessLimit) {
22189                            app.kill("cached #" + numCached, true);
22190                        }
22191                        break;
22192                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22193                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22194                                && app.lastActivityTime < oldTime) {
22195                            app.kill("empty for "
22196                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22197                                    / 1000) + "s", true);
22198                        } else {
22199                            numEmpty++;
22200                            if (numEmpty > emptyProcessLimit) {
22201                                app.kill("empty #" + numEmpty, true);
22202                            }
22203                        }
22204                        break;
22205                    default:
22206                        mNumNonCachedProcs++;
22207                        break;
22208                }
22209
22210                if (app.isolated && app.services.size() <= 0) {
22211                    // If this is an isolated process, and there are no
22212                    // services running in it, then the process is no longer
22213                    // needed.  We agressively kill these because we can by
22214                    // definition not re-use the same process again, and it is
22215                    // good to avoid having whatever code was running in them
22216                    // left sitting around after no longer needed.
22217                    app.kill("isolated not needed", true);
22218                } else {
22219                    // Keeping this process, update its uid.
22220                    final UidRecord uidRec = app.uidRecord;
22221                    if (uidRec != null) {
22222                        uidRec.ephemeral = app.info.isInstantApp();
22223                        if (uidRec.curProcState > app.curProcState) {
22224                            uidRec.curProcState = app.curProcState;
22225                        }
22226                    }
22227                }
22228
22229                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22230                        && !app.killedByAm) {
22231                    numTrimming++;
22232                }
22233            }
22234        }
22235
22236        incrementProcStateSeqAndNotifyAppsLocked();
22237
22238        mNumServiceProcs = mNewNumServiceProcs;
22239
22240        // Now determine the memory trimming level of background processes.
22241        // Unfortunately we need to start at the back of the list to do this
22242        // properly.  We only do this if the number of background apps we
22243        // are managing to keep around is less than half the maximum we desire;
22244        // if we are keeping a good number around, we'll let them use whatever
22245        // memory they want.
22246        final int numCachedAndEmpty = numCached + numEmpty;
22247        int memFactor;
22248        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22249                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22250            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22251                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22252            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22253                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22254            } else {
22255                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22256            }
22257        } else {
22258            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22259        }
22260        // We always allow the memory level to go up (better).  We only allow it to go
22261        // down if we are in a state where that is allowed, *and* the total number of processes
22262        // has gone down since last time.
22263        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22264                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22265                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22266        if (memFactor > mLastMemoryLevel) {
22267            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22268                memFactor = mLastMemoryLevel;
22269                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22270            }
22271        }
22272        if (memFactor != mLastMemoryLevel) {
22273            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22274        }
22275        mLastMemoryLevel = memFactor;
22276        mLastNumProcesses = mLruProcesses.size();
22277        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22278        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22279        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22280            if (mLowRamStartTime == 0) {
22281                mLowRamStartTime = now;
22282            }
22283            int step = 0;
22284            int fgTrimLevel;
22285            switch (memFactor) {
22286                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22287                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22288                    break;
22289                case ProcessStats.ADJ_MEM_FACTOR_LOW:
22290                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22291                    break;
22292                default:
22293                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22294                    break;
22295            }
22296            int factor = numTrimming/3;
22297            int minFactor = 2;
22298            if (mHomeProcess != null) minFactor++;
22299            if (mPreviousProcess != null) minFactor++;
22300            if (factor < minFactor) factor = minFactor;
22301            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22302            for (int i=N-1; i>=0; i--) {
22303                ProcessRecord app = mLruProcesses.get(i);
22304                if (allChanged || app.procStateChanged) {
22305                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22306                    app.procStateChanged = false;
22307                }
22308                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22309                        && !app.killedByAm) {
22310                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
22311                        try {
22312                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22313                                    "Trimming memory of " + app.processName + " to " + curLevel);
22314                            app.thread.scheduleTrimMemory(curLevel);
22315                        } catch (RemoteException e) {
22316                        }
22317                        if (false) {
22318                            // For now we won't do this; our memory trimming seems
22319                            // to be good enough at this point that destroying
22320                            // activities causes more harm than good.
22321                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22322                                    && app != mHomeProcess && app != mPreviousProcess) {
22323                                // Need to do this on its own message because the stack may not
22324                                // be in a consistent state at this point.
22325                                // For these apps we will also finish their activities
22326                                // to help them free memory.
22327                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22328                            }
22329                        }
22330                    }
22331                    app.trimMemoryLevel = curLevel;
22332                    step++;
22333                    if (step >= factor) {
22334                        step = 0;
22335                        switch (curLevel) {
22336                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22337                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22338                                break;
22339                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22340                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22341                                break;
22342                        }
22343                    }
22344                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22345                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22346                            && app.thread != null) {
22347                        try {
22348                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22349                                    "Trimming memory of heavy-weight " + app.processName
22350                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22351                            app.thread.scheduleTrimMemory(
22352                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22353                        } catch (RemoteException e) {
22354                        }
22355                    }
22356                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22357                } else {
22358                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22359                            || app.systemNoUi) && app.pendingUiClean) {
22360                        // If this application is now in the background and it
22361                        // had done UI, then give it the special trim level to
22362                        // have it free UI resources.
22363                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22364                        if (app.trimMemoryLevel < level && app.thread != null) {
22365                            try {
22366                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22367                                        "Trimming memory of bg-ui " + app.processName
22368                                        + " to " + level);
22369                                app.thread.scheduleTrimMemory(level);
22370                            } catch (RemoteException e) {
22371                            }
22372                        }
22373                        app.pendingUiClean = false;
22374                    }
22375                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22376                        try {
22377                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22378                                    "Trimming memory of fg " + app.processName
22379                                    + " to " + fgTrimLevel);
22380                            app.thread.scheduleTrimMemory(fgTrimLevel);
22381                        } catch (RemoteException e) {
22382                        }
22383                    }
22384                    app.trimMemoryLevel = fgTrimLevel;
22385                }
22386            }
22387        } else {
22388            if (mLowRamStartTime != 0) {
22389                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22390                mLowRamStartTime = 0;
22391            }
22392            for (int i=N-1; i>=0; i--) {
22393                ProcessRecord app = mLruProcesses.get(i);
22394                if (allChanged || app.procStateChanged) {
22395                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22396                    app.procStateChanged = false;
22397                }
22398                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22399                        || app.systemNoUi) && app.pendingUiClean) {
22400                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22401                            && app.thread != null) {
22402                        try {
22403                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22404                                    "Trimming memory of ui hidden " + app.processName
22405                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22406                            app.thread.scheduleTrimMemory(
22407                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22408                        } catch (RemoteException e) {
22409                        }
22410                    }
22411                    app.pendingUiClean = false;
22412                }
22413                app.trimMemoryLevel = 0;
22414            }
22415        }
22416
22417        if (mAlwaysFinishActivities) {
22418            // Need to do this on its own message because the stack may not
22419            // be in a consistent state at this point.
22420            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22421        }
22422
22423        if (allChanged) {
22424            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22425        }
22426
22427        // Update from any uid changes.
22428        if (mLocalPowerManager != null) {
22429            mLocalPowerManager.startUidChanges();
22430        }
22431        for (int i=mActiveUids.size()-1; i>=0; i--) {
22432            final UidRecord uidRec = mActiveUids.valueAt(i);
22433            int uidChange = UidRecord.CHANGE_PROCSTATE;
22434            if (uidRec.setProcState != uidRec.curProcState
22435                    || uidRec.setWhitelist != uidRec.curWhitelist) {
22436                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22437                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22438                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22439                        + " to " + uidRec.curWhitelist);
22440                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22441                        && !uidRec.curWhitelist) {
22442                    // UID is now in the background (and not on the temp whitelist).  Was it
22443                    // previously in the foreground (or on the temp whitelist)?
22444                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22445                            || uidRec.setWhitelist) {
22446                        uidRec.lastBackgroundTime = nowElapsed;
22447                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22448                            // Note: the background settle time is in elapsed realtime, while
22449                            // the handler time base is uptime.  All this means is that we may
22450                            // stop background uids later than we had intended, but that only
22451                            // happens because the device was sleeping so we are okay anyway.
22452                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
22453                        }
22454                    }
22455                } else {
22456                    if (uidRec.idle) {
22457                        uidChange = UidRecord.CHANGE_ACTIVE;
22458                        uidRec.idle = false;
22459                    }
22460                    uidRec.lastBackgroundTime = 0;
22461                }
22462                uidRec.setProcState = uidRec.curProcState;
22463                uidRec.setWhitelist = uidRec.curWhitelist;
22464                enqueueUidChangeLocked(uidRec, -1, uidChange);
22465                noteUidProcessState(uidRec.uid, uidRec.curProcState);
22466            }
22467        }
22468        if (mLocalPowerManager != null) {
22469            mLocalPowerManager.finishUidChanges();
22470        }
22471
22472        if (mProcessStats.shouldWriteNowLocked(now)) {
22473            mHandler.post(new Runnable() {
22474                @Override public void run() {
22475                    synchronized (ActivityManagerService.this) {
22476                        mProcessStats.writeStateAsyncLocked();
22477                    }
22478                }
22479            });
22480        }
22481
22482        if (DEBUG_OOM_ADJ) {
22483            final long duration = SystemClock.uptimeMillis() - now;
22484            if (false) {
22485                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22486                        new RuntimeException("here").fillInStackTrace());
22487            } else {
22488                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22489            }
22490        }
22491    }
22492
22493    @Override
22494    public void makePackageIdle(String packageName, int userId) {
22495        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22496                != PackageManager.PERMISSION_GRANTED) {
22497            String msg = "Permission Denial: makePackageIdle() from pid="
22498                    + Binder.getCallingPid()
22499                    + ", uid=" + Binder.getCallingUid()
22500                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22501            Slog.w(TAG, msg);
22502            throw new SecurityException(msg);
22503        }
22504        final int callingPid = Binder.getCallingPid();
22505        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22506                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22507        long callingId = Binder.clearCallingIdentity();
22508        synchronized(this) {
22509            try {
22510                IPackageManager pm = AppGlobals.getPackageManager();
22511                int pkgUid = -1;
22512                try {
22513                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22514                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22515                } catch (RemoteException e) {
22516                }
22517                if (pkgUid == -1) {
22518                    throw new IllegalArgumentException("Unknown package name " + packageName);
22519                }
22520
22521                if (mLocalPowerManager != null) {
22522                    mLocalPowerManager.startUidChanges();
22523                }
22524                final int appId = UserHandle.getAppId(pkgUid);
22525                final int N = mActiveUids.size();
22526                for (int i=N-1; i>=0; i--) {
22527                    final UidRecord uidRec = mActiveUids.valueAt(i);
22528                    final long bgTime = uidRec.lastBackgroundTime;
22529                    if (bgTime > 0 && !uidRec.idle) {
22530                        if (UserHandle.getAppId(uidRec.uid) == appId) {
22531                            if (userId == UserHandle.USER_ALL ||
22532                                    userId == UserHandle.getUserId(uidRec.uid)) {
22533                                uidRec.idle = true;
22534                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22535                                        + " from package " + packageName + " user " + userId);
22536                                doStopUidLocked(uidRec.uid, uidRec);
22537                            }
22538                        }
22539                    }
22540                }
22541            } finally {
22542                if (mLocalPowerManager != null) {
22543                    mLocalPowerManager.finishUidChanges();
22544                }
22545                Binder.restoreCallingIdentity(callingId);
22546            }
22547        }
22548    }
22549
22550    final void idleUids() {
22551        synchronized (this) {
22552            final int N = mActiveUids.size();
22553            if (N <= 0) {
22554                return;
22555            }
22556            final long nowElapsed = SystemClock.elapsedRealtime();
22557            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
22558            long nextTime = 0;
22559            if (mLocalPowerManager != null) {
22560                mLocalPowerManager.startUidChanges();
22561            }
22562            for (int i=N-1; i>=0; i--) {
22563                final UidRecord uidRec = mActiveUids.valueAt(i);
22564                final long bgTime = uidRec.lastBackgroundTime;
22565                if (bgTime > 0 && !uidRec.idle) {
22566                    if (bgTime <= maxBgTime) {
22567                        uidRec.idle = true;
22568                        doStopUidLocked(uidRec.uid, uidRec);
22569                    } else {
22570                        if (nextTime == 0 || nextTime > bgTime) {
22571                            nextTime = bgTime;
22572                        }
22573                    }
22574                }
22575            }
22576            if (mLocalPowerManager != null) {
22577                mLocalPowerManager.finishUidChanges();
22578            }
22579            if (nextTime > 0) {
22580                mHandler.removeMessages(IDLE_UIDS_MSG);
22581                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22582                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
22583            }
22584        }
22585    }
22586
22587    /**
22588     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
22589     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
22590     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
22591     */
22592    @VisibleForTesting
22593    @GuardedBy("this")
22594    void incrementProcStateSeqAndNotifyAppsLocked() {
22595        if (mWaitForNetworkTimeoutMs <= 0) {
22596            return;
22597        }
22598        // Used for identifying which uids need to block for network.
22599        ArrayList<Integer> blockingUids = null;
22600        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
22601            final UidRecord uidRec = mActiveUids.valueAt(i);
22602            // If the network is not restricted for uid, then nothing to do here.
22603            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
22604                continue;
22605            }
22606            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
22607                continue;
22608            }
22609            // If process state is not changed, then there's nothing to do.
22610            if (uidRec.setProcState == uidRec.curProcState) {
22611                continue;
22612            }
22613            final int blockState = getBlockStateForUid(uidRec);
22614            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
22615            // there's nothing the app needs to do in this scenario.
22616            if (blockState == NETWORK_STATE_NO_CHANGE) {
22617                continue;
22618            }
22619            synchronized (uidRec.networkStateLock) {
22620                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
22621                if (blockState == NETWORK_STATE_BLOCK) {
22622                    if (blockingUids == null) {
22623                        blockingUids = new ArrayList<>();
22624                    }
22625                    blockingUids.add(uidRec.uid);
22626                } else {
22627                    if (DEBUG_NETWORK) {
22628                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
22629                                + " threads for uid: " + uidRec);
22630                    }
22631                    if (uidRec.waitingForNetwork) {
22632                        uidRec.networkStateLock.notifyAll();
22633                    }
22634                }
22635            }
22636        }
22637
22638        // There are no uids that need to block, so nothing more to do.
22639        if (blockingUids == null) {
22640            return;
22641        }
22642
22643        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
22644            final ProcessRecord app = mLruProcesses.get(i);
22645            if (!blockingUids.contains(app.uid)) {
22646                continue;
22647            }
22648            if (!app.killedByAm && app.thread != null) {
22649                final UidRecord uidRec = mActiveUids.get(app.uid);
22650                try {
22651                    if (DEBUG_NETWORK) {
22652                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
22653                                + uidRec);
22654                    }
22655                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
22656                } catch (RemoteException ignored) {
22657                }
22658            }
22659        }
22660    }
22661
22662    /**
22663     * Checks if the uid is coming from background to foreground or vice versa and returns
22664     * appropriate block state based on this.
22665     *
22666     * @return blockState based on whether the uid is coming from background to foreground or
22667     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
22668     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
22669     *         {@link #NETWORK_STATE_NO_CHANGE}.
22670     */
22671    @VisibleForTesting
22672    int getBlockStateForUid(UidRecord uidRec) {
22673        // Denotes whether uid's process state is currently allowed network access.
22674        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
22675                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
22676        // Denotes whether uid's process state was previously allowed network access.
22677        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
22678                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
22679
22680        // When the uid is coming to foreground, AMS should inform the app thread that it should
22681        // block for the network rules to get updated before launching an activity.
22682        if (!wasAllowed && isAllowed) {
22683            return NETWORK_STATE_BLOCK;
22684        }
22685        // When the uid is going to background, AMS should inform the app thread that if an
22686        // activity launch is blocked for the network rules to get updated, it should be unblocked.
22687        if (wasAllowed && !isAllowed) {
22688            return NETWORK_STATE_UNBLOCK;
22689        }
22690        return NETWORK_STATE_NO_CHANGE;
22691    }
22692
22693    final void runInBackgroundDisabled(int uid) {
22694        synchronized (this) {
22695            UidRecord uidRec = mActiveUids.get(uid);
22696            if (uidRec != null) {
22697                // This uid is actually running...  should it be considered background now?
22698                if (uidRec.idle) {
22699                    doStopUidLocked(uidRec.uid, uidRec);
22700                }
22701            } else {
22702                // This uid isn't actually running...  still send a report about it being "stopped".
22703                doStopUidLocked(uid, null);
22704            }
22705        }
22706    }
22707
22708    final void doStopUidLocked(int uid, final UidRecord uidRec) {
22709        mServices.stopInBackgroundLocked(uid);
22710        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
22711    }
22712
22713    /**
22714     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
22715     */
22716    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
22717            long duration, String tag) {
22718        if (DEBUG_WHITELISTS) {
22719            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
22720                    + targetUid + ", " + duration + ")");
22721        }
22722
22723        synchronized (mPidsSelfLocked) {
22724            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
22725            if (pr == null) {
22726                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
22727                        + callerPid);
22728                return;
22729            }
22730            if (!pr.whitelistManager) {
22731                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
22732                        != PackageManager.PERMISSION_GRANTED) {
22733                    if (DEBUG_WHITELISTS) {
22734                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
22735                                + ": pid " + callerPid + " is not allowed");
22736                    }
22737                    return;
22738                }
22739            }
22740        }
22741
22742        tempWhitelistUidLocked(targetUid, duration, tag);
22743    }
22744
22745    /**
22746     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
22747     */
22748    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
22749        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
22750        setUidTempWhitelistStateLocked(targetUid, true);
22751        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
22752    }
22753
22754    void pushTempWhitelist() {
22755        final int N;
22756        final PendingTempWhitelist[] list;
22757
22758        // First copy out the pending changes...  we need to leave them in the map for now,
22759        // in case someone needs to check what is coming up while we don't have the lock held.
22760        synchronized(this) {
22761            N = mPendingTempWhitelist.size();
22762            list = new PendingTempWhitelist[N];
22763            for (int i = 0; i < N; i++) {
22764                list[i] = mPendingTempWhitelist.valueAt(i);
22765            }
22766        }
22767
22768        // Now safely dispatch changes to device idle controller.
22769        for (int i = 0; i < N; i++) {
22770            PendingTempWhitelist ptw = list[i];
22771            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
22772                    ptw.duration, true, ptw.tag);
22773        }
22774
22775        // And now we can safely remove them from the map.
22776        synchronized(this) {
22777            for (int i = 0; i < N; i++) {
22778                PendingTempWhitelist ptw = list[i];
22779                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
22780                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
22781                    mPendingTempWhitelist.removeAt(index);
22782                }
22783            }
22784        }
22785    }
22786
22787    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
22788        boolean changed = false;
22789        for (int i=mActiveUids.size()-1; i>=0; i--) {
22790            final UidRecord uidRec = mActiveUids.valueAt(i);
22791            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
22792                uidRec.curWhitelist = onWhitelist;
22793                changed = true;
22794            }
22795        }
22796        if (changed) {
22797            updateOomAdjLocked();
22798        }
22799    }
22800
22801    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
22802        boolean changed = false;
22803        final UidRecord uidRec = mActiveUids.get(uid);
22804        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
22805            uidRec.curWhitelist = onWhitelist;
22806            updateOomAdjLocked();
22807        }
22808    }
22809
22810    final void trimApplications() {
22811        synchronized (this) {
22812            int i;
22813
22814            // First remove any unused application processes whose package
22815            // has been removed.
22816            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
22817                final ProcessRecord app = mRemovedProcesses.get(i);
22818                if (app.activities.size() == 0
22819                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
22820                    Slog.i(
22821                        TAG, "Exiting empty application process "
22822                        + app.toShortString() + " ("
22823                        + (app.thread != null ? app.thread.asBinder() : null)
22824                        + ")\n");
22825                    if (app.pid > 0 && app.pid != MY_PID) {
22826                        app.kill("empty", false);
22827                    } else {
22828                        try {
22829                            app.thread.scheduleExit();
22830                        } catch (Exception e) {
22831                            // Ignore exceptions.
22832                        }
22833                    }
22834                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
22835                    mRemovedProcesses.remove(i);
22836
22837                    if (app.persistent) {
22838                        addAppLocked(app.info, null, false, null /* ABI override */);
22839                    }
22840                }
22841            }
22842
22843            // Now update the oom adj for all processes.
22844            updateOomAdjLocked();
22845        }
22846    }
22847
22848    /** This method sends the specified signal to each of the persistent apps */
22849    public void signalPersistentProcesses(int sig) throws RemoteException {
22850        if (sig != SIGNAL_USR1) {
22851            throw new SecurityException("Only SIGNAL_USR1 is allowed");
22852        }
22853
22854        synchronized (this) {
22855            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
22856                    != PackageManager.PERMISSION_GRANTED) {
22857                throw new SecurityException("Requires permission "
22858                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
22859            }
22860
22861            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
22862                ProcessRecord r = mLruProcesses.get(i);
22863                if (r.thread != null && r.persistent) {
22864                    sendSignal(r.pid, sig);
22865                }
22866            }
22867        }
22868    }
22869
22870    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
22871        if (proc == null || proc == mProfileProc) {
22872            proc = mProfileProc;
22873            profileType = mProfileType;
22874            clearProfilerLocked();
22875        }
22876        if (proc == null) {
22877            return;
22878        }
22879        try {
22880            proc.thread.profilerControl(false, null, profileType);
22881        } catch (RemoteException e) {
22882            throw new IllegalStateException("Process disappeared");
22883        }
22884    }
22885
22886    private void clearProfilerLocked() {
22887        if (mProfileFd != null) {
22888            try {
22889                mProfileFd.close();
22890            } catch (IOException e) {
22891            }
22892        }
22893        mProfileApp = null;
22894        mProfileProc = null;
22895        mProfileFile = null;
22896        mProfileType = 0;
22897        mAutoStopProfiler = false;
22898        mStreamingOutput = false;
22899        mSamplingInterval = 0;
22900    }
22901
22902    public boolean profileControl(String process, int userId, boolean start,
22903            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
22904
22905        try {
22906            synchronized (this) {
22907                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
22908                // its own permission.
22909                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22910                        != PackageManager.PERMISSION_GRANTED) {
22911                    throw new SecurityException("Requires permission "
22912                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22913                }
22914
22915                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
22916                    throw new IllegalArgumentException("null profile info or fd");
22917                }
22918
22919                ProcessRecord proc = null;
22920                if (process != null) {
22921                    proc = findProcessLocked(process, userId, "profileControl");
22922                }
22923
22924                if (start && (proc == null || proc.thread == null)) {
22925                    throw new IllegalArgumentException("Unknown process: " + process);
22926                }
22927
22928                if (start) {
22929                    stopProfilerLocked(null, 0);
22930                    setProfileApp(proc.info, proc.processName, profilerInfo);
22931                    mProfileProc = proc;
22932                    mProfileType = profileType;
22933                    ParcelFileDescriptor fd = profilerInfo.profileFd;
22934                    try {
22935                        fd = fd.dup();
22936                    } catch (IOException e) {
22937                        fd = null;
22938                    }
22939                    profilerInfo.profileFd = fd;
22940                    proc.thread.profilerControl(start, profilerInfo, profileType);
22941                    fd = null;
22942                    try {
22943                        mProfileFd.close();
22944                    } catch (IOException e) {
22945                    }
22946                    mProfileFd = null;
22947                } else {
22948                    stopProfilerLocked(proc, profileType);
22949                    if (profilerInfo != null && profilerInfo.profileFd != null) {
22950                        try {
22951                            profilerInfo.profileFd.close();
22952                        } catch (IOException e) {
22953                        }
22954                    }
22955                }
22956
22957                return true;
22958            }
22959        } catch (RemoteException e) {
22960            throw new IllegalStateException("Process disappeared");
22961        } finally {
22962            if (profilerInfo != null && profilerInfo.profileFd != null) {
22963                try {
22964                    profilerInfo.profileFd.close();
22965                } catch (IOException e) {
22966                }
22967            }
22968        }
22969    }
22970
22971    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
22972        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22973                userId, true, ALLOW_FULL_ONLY, callName, null);
22974        ProcessRecord proc = null;
22975        try {
22976            int pid = Integer.parseInt(process);
22977            synchronized (mPidsSelfLocked) {
22978                proc = mPidsSelfLocked.get(pid);
22979            }
22980        } catch (NumberFormatException e) {
22981        }
22982
22983        if (proc == null) {
22984            ArrayMap<String, SparseArray<ProcessRecord>> all
22985                    = mProcessNames.getMap();
22986            SparseArray<ProcessRecord> procs = all.get(process);
22987            if (procs != null && procs.size() > 0) {
22988                proc = procs.valueAt(0);
22989                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
22990                    for (int i=1; i<procs.size(); i++) {
22991                        ProcessRecord thisProc = procs.valueAt(i);
22992                        if (thisProc.userId == userId) {
22993                            proc = thisProc;
22994                            break;
22995                        }
22996                    }
22997                }
22998            }
22999        }
23000
23001        return proc;
23002    }
23003
23004    public boolean dumpHeap(String process, int userId, boolean managed,
23005            String path, ParcelFileDescriptor fd) throws RemoteException {
23006
23007        try {
23008            synchronized (this) {
23009                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23010                // its own permission (same as profileControl).
23011                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23012                        != PackageManager.PERMISSION_GRANTED) {
23013                    throw new SecurityException("Requires permission "
23014                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23015                }
23016
23017                if (fd == null) {
23018                    throw new IllegalArgumentException("null fd");
23019                }
23020
23021                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23022                if (proc == null || proc.thread == null) {
23023                    throw new IllegalArgumentException("Unknown process: " + process);
23024                }
23025
23026                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23027                if (!isDebuggable) {
23028                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23029                        throw new SecurityException("Process not debuggable: " + proc);
23030                    }
23031                }
23032
23033                proc.thread.dumpHeap(managed, path, fd);
23034                fd = null;
23035                return true;
23036            }
23037        } catch (RemoteException e) {
23038            throw new IllegalStateException("Process disappeared");
23039        } finally {
23040            if (fd != null) {
23041                try {
23042                    fd.close();
23043                } catch (IOException e) {
23044                }
23045            }
23046        }
23047    }
23048
23049    @Override
23050    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23051            String reportPackage) {
23052        if (processName != null) {
23053            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23054                    "setDumpHeapDebugLimit()");
23055        } else {
23056            synchronized (mPidsSelfLocked) {
23057                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23058                if (proc == null) {
23059                    throw new SecurityException("No process found for calling pid "
23060                            + Binder.getCallingPid());
23061                }
23062                if (!Build.IS_DEBUGGABLE
23063                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23064                    throw new SecurityException("Not running a debuggable build");
23065                }
23066                processName = proc.processName;
23067                uid = proc.uid;
23068                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23069                    throw new SecurityException("Package " + reportPackage + " is not running in "
23070                            + proc);
23071                }
23072            }
23073        }
23074        synchronized (this) {
23075            if (maxMemSize > 0) {
23076                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23077            } else {
23078                if (uid != 0) {
23079                    mMemWatchProcesses.remove(processName, uid);
23080                } else {
23081                    mMemWatchProcesses.getMap().remove(processName);
23082                }
23083            }
23084        }
23085    }
23086
23087    @Override
23088    public void dumpHeapFinished(String path) {
23089        synchronized (this) {
23090            if (Binder.getCallingPid() != mMemWatchDumpPid) {
23091                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23092                        + " does not match last pid " + mMemWatchDumpPid);
23093                return;
23094            }
23095            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23096                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23097                        + " does not match last path " + mMemWatchDumpFile);
23098                return;
23099            }
23100            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23101            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23102        }
23103    }
23104
23105    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23106    public void monitor() {
23107        synchronized (this) { }
23108    }
23109
23110    void onCoreSettingsChange(Bundle settings) {
23111        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23112            ProcessRecord processRecord = mLruProcesses.get(i);
23113            try {
23114                if (processRecord.thread != null) {
23115                    processRecord.thread.setCoreSettings(settings);
23116                }
23117            } catch (RemoteException re) {
23118                /* ignore */
23119            }
23120        }
23121    }
23122
23123    // Multi-user methods
23124
23125    /**
23126     * Start user, if its not already running, but don't bring it to foreground.
23127     */
23128    @Override
23129    public boolean startUserInBackground(final int userId) {
23130        return mUserController.startUser(userId, /* foreground */ false);
23131    }
23132
23133    @Override
23134    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23135        return mUserController.unlockUser(userId, token, secret, listener);
23136    }
23137
23138    @Override
23139    public boolean switchUser(final int targetUserId) {
23140        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23141        int currentUserId;
23142        UserInfo targetUserInfo;
23143        synchronized (this) {
23144            currentUserId = mUserController.getCurrentUserIdLocked();
23145            targetUserInfo = mUserController.getUserInfo(targetUserId);
23146            if (targetUserId == currentUserId) {
23147                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23148                return true;
23149            }
23150            if (targetUserInfo == null) {
23151                Slog.w(TAG, "No user info for user #" + targetUserId);
23152                return false;
23153            }
23154            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23155                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23156                        + " when device is in demo mode");
23157                return false;
23158            }
23159            if (!targetUserInfo.supportsSwitchTo()) {
23160                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23161                return false;
23162            }
23163            if (targetUserInfo.isManagedProfile()) {
23164                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23165                return false;
23166            }
23167            mUserController.setTargetUserIdLocked(targetUserId);
23168        }
23169        if (mUserController.mUserSwitchUiEnabled) {
23170            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23171            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23172            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23173            mUiHandler.sendMessage(mHandler.obtainMessage(
23174                    START_USER_SWITCH_UI_MSG, userNames));
23175        } else {
23176            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23177            mHandler.sendMessage(mHandler.obtainMessage(
23178                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
23179        }
23180        return true;
23181    }
23182
23183    void scheduleStartProfilesLocked() {
23184        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23185            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23186                    DateUtils.SECOND_IN_MILLIS);
23187        }
23188    }
23189
23190    @Override
23191    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23192        return mUserController.stopUser(userId, force, callback);
23193    }
23194
23195    @Override
23196    public UserInfo getCurrentUser() {
23197        return mUserController.getCurrentUser();
23198    }
23199
23200    String getStartedUserState(int userId) {
23201        synchronized (this) {
23202            final UserState userState = mUserController.getStartedUserStateLocked(userId);
23203            return UserState.stateToString(userState.state);
23204        }
23205    }
23206
23207    @Override
23208    public boolean isUserRunning(int userId, int flags) {
23209        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23210                && checkCallingPermission(INTERACT_ACROSS_USERS)
23211                    != PackageManager.PERMISSION_GRANTED) {
23212            String msg = "Permission Denial: isUserRunning() from pid="
23213                    + Binder.getCallingPid()
23214                    + ", uid=" + Binder.getCallingUid()
23215                    + " requires " + INTERACT_ACROSS_USERS;
23216            Slog.w(TAG, msg);
23217            throw new SecurityException(msg);
23218        }
23219        synchronized (this) {
23220            return mUserController.isUserRunningLocked(userId, flags);
23221        }
23222    }
23223
23224    @Override
23225    public int[] getRunningUserIds() {
23226        if (checkCallingPermission(INTERACT_ACROSS_USERS)
23227                != PackageManager.PERMISSION_GRANTED) {
23228            String msg = "Permission Denial: isUserRunning() from pid="
23229                    + Binder.getCallingPid()
23230                    + ", uid=" + Binder.getCallingUid()
23231                    + " requires " + INTERACT_ACROSS_USERS;
23232            Slog.w(TAG, msg);
23233            throw new SecurityException(msg);
23234        }
23235        synchronized (this) {
23236            return mUserController.getStartedUserArrayLocked();
23237        }
23238    }
23239
23240    @Override
23241    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23242        mUserController.registerUserSwitchObserver(observer, name);
23243    }
23244
23245    @Override
23246    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23247        mUserController.unregisterUserSwitchObserver(observer);
23248    }
23249
23250    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23251        if (info == null) return null;
23252        ApplicationInfo newInfo = new ApplicationInfo(info);
23253        newInfo.initForUser(userId);
23254        return newInfo;
23255    }
23256
23257    public boolean isUserStopped(int userId) {
23258        synchronized (this) {
23259            return mUserController.getStartedUserStateLocked(userId) == null;
23260        }
23261    }
23262
23263    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23264        if (aInfo == null
23265                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23266            return aInfo;
23267        }
23268
23269        ActivityInfo info = new ActivityInfo(aInfo);
23270        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23271        return info;
23272    }
23273
23274    private boolean processSanityChecksLocked(ProcessRecord process) {
23275        if (process == null || process.thread == null) {
23276            return false;
23277        }
23278
23279        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23280        if (!isDebuggable) {
23281            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23282                return false;
23283            }
23284        }
23285
23286        return true;
23287    }
23288
23289    public boolean startBinderTracking() throws RemoteException {
23290        synchronized (this) {
23291            mBinderTransactionTrackingEnabled = true;
23292            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23293            // permission (same as profileControl).
23294            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23295                    != PackageManager.PERMISSION_GRANTED) {
23296                throw new SecurityException("Requires permission "
23297                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23298            }
23299
23300            for (int i = 0; i < mLruProcesses.size(); i++) {
23301                ProcessRecord process = mLruProcesses.get(i);
23302                if (!processSanityChecksLocked(process)) {
23303                    continue;
23304                }
23305                try {
23306                    process.thread.startBinderTracking();
23307                } catch (RemoteException e) {
23308                    Log.v(TAG, "Process disappared");
23309                }
23310            }
23311            return true;
23312        }
23313    }
23314
23315    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23316        try {
23317            synchronized (this) {
23318                mBinderTransactionTrackingEnabled = false;
23319                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23320                // permission (same as profileControl).
23321                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23322                        != PackageManager.PERMISSION_GRANTED) {
23323                    throw new SecurityException("Requires permission "
23324                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23325                }
23326
23327                if (fd == null) {
23328                    throw new IllegalArgumentException("null fd");
23329                }
23330
23331                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23332                pw.println("Binder transaction traces for all processes.\n");
23333                for (ProcessRecord process : mLruProcesses) {
23334                    if (!processSanityChecksLocked(process)) {
23335                        continue;
23336                    }
23337
23338                    pw.println("Traces for process: " + process.processName);
23339                    pw.flush();
23340                    try {
23341                        TransferPipe tp = new TransferPipe();
23342                        try {
23343                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23344                            tp.go(fd.getFileDescriptor());
23345                        } finally {
23346                            tp.kill();
23347                        }
23348                    } catch (IOException e) {
23349                        pw.println("Failure while dumping IPC traces from " + process +
23350                                ".  Exception: " + e);
23351                        pw.flush();
23352                    } catch (RemoteException e) {
23353                        pw.println("Got a RemoteException while dumping IPC traces from " +
23354                                process + ".  Exception: " + e);
23355                        pw.flush();
23356                    }
23357                }
23358                fd = null;
23359                return true;
23360            }
23361        } finally {
23362            if (fd != null) {
23363                try {
23364                    fd.close();
23365                } catch (IOException e) {
23366                }
23367            }
23368        }
23369    }
23370
23371    @VisibleForTesting
23372    final class LocalService extends ActivityManagerInternal {
23373        @Override
23374        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23375                int targetUserId) {
23376            synchronized (ActivityManagerService.this) {
23377                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23378                        targetPkg, intent, null, targetUserId);
23379            }
23380        }
23381
23382        @Override
23383        public String checkContentProviderAccess(String authority, int userId) {
23384            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23385        }
23386
23387        @Override
23388        public void onWakefulnessChanged(int wakefulness) {
23389            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23390        }
23391
23392        @Override
23393        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23394                String processName, String abiOverride, int uid, Runnable crashHandler) {
23395            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23396                    processName, abiOverride, uid, crashHandler);
23397        }
23398
23399        @Override
23400        public SleepToken acquireSleepToken(String tag) {
23401            Preconditions.checkNotNull(tag);
23402
23403            synchronized (ActivityManagerService.this) {
23404                SleepTokenImpl token = new SleepTokenImpl(tag);
23405                mSleepTokens.add(token);
23406                updateSleepIfNeededLocked();
23407                return token;
23408            }
23409        }
23410
23411        @Override
23412        public ComponentName getHomeActivityForUser(int userId) {
23413            synchronized (ActivityManagerService.this) {
23414                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23415                return homeActivity == null ? null : homeActivity.realActivity;
23416            }
23417        }
23418
23419        @Override
23420        public void onUserRemoved(int userId) {
23421            synchronized (ActivityManagerService.this) {
23422                ActivityManagerService.this.onUserStoppedLocked(userId);
23423            }
23424        }
23425
23426        @Override
23427        public void onLocalVoiceInteractionStarted(IBinder activity,
23428                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23429            synchronized (ActivityManagerService.this) {
23430                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23431                        voiceSession, voiceInteractor);
23432            }
23433        }
23434
23435        @Override
23436        public void notifyAppTransitionStarting(SparseIntArray reasons) {
23437            synchronized (ActivityManagerService.this) {
23438                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reasons);
23439            }
23440        }
23441
23442        @Override
23443        public void notifyAppTransitionFinished() {
23444            synchronized (ActivityManagerService.this) {
23445                mStackSupervisor.notifyAppTransitionDone();
23446            }
23447        }
23448
23449        @Override
23450        public void notifyAppTransitionCancelled() {
23451            synchronized (ActivityManagerService.this) {
23452                mStackSupervisor.notifyAppTransitionDone();
23453            }
23454        }
23455
23456        @Override
23457        public List<IBinder> getTopVisibleActivities() {
23458            synchronized (ActivityManagerService.this) {
23459                return mStackSupervisor.getTopVisibleActivities();
23460            }
23461        }
23462
23463        @Override
23464        public void notifyDockedStackMinimizedChanged(boolean minimized) {
23465            synchronized (ActivityManagerService.this) {
23466                mStackSupervisor.setDockedStackMinimized(minimized);
23467            }
23468        }
23469
23470        @Override
23471        public void killForegroundAppsForUser(int userHandle) {
23472            synchronized (ActivityManagerService.this) {
23473                final ArrayList<ProcessRecord> procs = new ArrayList<>();
23474                final int NP = mProcessNames.getMap().size();
23475                for (int ip = 0; ip < NP; ip++) {
23476                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23477                    final int NA = apps.size();
23478                    for (int ia = 0; ia < NA; ia++) {
23479                        final ProcessRecord app = apps.valueAt(ia);
23480                        if (app.persistent) {
23481                            // We don't kill persistent processes.
23482                            continue;
23483                        }
23484                        if (app.removed) {
23485                            procs.add(app);
23486                        } else if (app.userId == userHandle && app.foregroundActivities) {
23487                            app.removed = true;
23488                            procs.add(app);
23489                        }
23490                    }
23491                }
23492
23493                final int N = procs.size();
23494                for (int i = 0; i < N; i++) {
23495                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
23496                }
23497            }
23498        }
23499
23500        @Override
23501        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
23502            if (!(target instanceof PendingIntentRecord)) {
23503                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23504                return;
23505            }
23506            ((PendingIntentRecord) target).setWhitelistDurationLocked(duration);
23507        }
23508
23509        @Override
23510        public void setDeviceIdleWhitelist(int[] appids) {
23511            synchronized (ActivityManagerService.this) {
23512                mDeviceIdleWhitelist = appids;
23513            }
23514        }
23515
23516        @Override
23517        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23518            synchronized (ActivityManagerService.this) {
23519                mDeviceIdleTempWhitelist = appids;
23520                setAppIdTempWhitelistStateLocked(changingAppId, adding);
23521            }
23522        }
23523
23524        @Override
23525        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23526                int userId) {
23527            Preconditions.checkNotNull(values, "Configuration must not be null");
23528            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23529            synchronized (ActivityManagerService.this) {
23530                updateConfigurationLocked(values, null, false, true, userId,
23531                        false /* deferResume */);
23532            }
23533        }
23534
23535        @Override
23536        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23537                Bundle bOptions) {
23538            Preconditions.checkNotNull(intents, "intents");
23539            final String[] resolvedTypes = new String[intents.length];
23540            for (int i = 0; i < intents.length; i++) {
23541                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23542            }
23543
23544            // UID of the package on user userId.
23545            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23546            // packageUid may not be initialized.
23547            int packageUid = 0;
23548            try {
23549                packageUid = AppGlobals.getPackageManager().getPackageUid(
23550                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23551            } catch (RemoteException e) {
23552                // Shouldn't happen.
23553            }
23554
23555            synchronized (ActivityManagerService.this) {
23556                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23557                        /*resultTo*/ null, bOptions, userId);
23558            }
23559        }
23560
23561        @Override
23562        public int getUidProcessState(int uid) {
23563            return getUidState(uid);
23564        }
23565
23566        @Override
23567        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23568            synchronized (ActivityManagerService.this) {
23569
23570                // We might change the visibilities here, so prepare an empty app transition which
23571                // might be overridden later if we actually change visibilities.
23572                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
23573                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23574                mWindowManager.executeAppTransition();
23575            }
23576            if (callback != null) {
23577                callback.run();
23578            }
23579        }
23580
23581        @Override
23582        public boolean isSystemReady() {
23583            // no need to synchronize(this) just to read & return the value
23584            return mSystemReady;
23585        }
23586
23587        @Override
23588        public void notifyKeyguardTrustedChanged() {
23589            synchronized (ActivityManagerService.this) {
23590                if (mKeyguardController.isKeyguardShowing()) {
23591                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23592                }
23593            }
23594        }
23595
23596        /**
23597         * Sets if the given pid has an overlay UI or not.
23598         *
23599         * @param pid The pid we are setting overlay UI for.
23600         * @param hasOverlayUi True if the process has overlay UI.
23601         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
23602         */
23603        @Override
23604        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
23605            synchronized (ActivityManagerService.this) {
23606                final ProcessRecord pr;
23607                synchronized (mPidsSelfLocked) {
23608                    pr = mPidsSelfLocked.get(pid);
23609                    if (pr == null) {
23610                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
23611                        return;
23612                    }
23613                }
23614                if (pr.hasOverlayUi == hasOverlayUi) {
23615                    return;
23616                }
23617                pr.hasOverlayUi = hasOverlayUi;
23618                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
23619                updateOomAdjLocked(pr);
23620            }
23621        }
23622
23623        /**
23624         * Called after the network policy rules are updated by
23625         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
23626         * and {@param procStateSeq}.
23627         */
23628        @Override
23629        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
23630            if (DEBUG_NETWORK) {
23631                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
23632                        + uid + " seq: " + procStateSeq);
23633            }
23634            UidRecord record;
23635            synchronized (ActivityManagerService.this) {
23636                record = mActiveUids.get(uid);
23637                if (record == null) {
23638                    if (DEBUG_NETWORK) {
23639                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
23640                                + " procStateSeq: " + procStateSeq);
23641                    }
23642                    return;
23643                }
23644            }
23645            synchronized (record.networkStateLock) {
23646                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23647                    if (DEBUG_NETWORK) {
23648                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
23649                                + " been handled for uid: " + uid);
23650                    }
23651                    return;
23652                }
23653                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
23654                if (record.curProcStateSeq > procStateSeq) {
23655                    if (DEBUG_NETWORK) {
23656                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
23657                                + ", curProcstateSeq: " + record.curProcStateSeq
23658                                + ", procStateSeq: " + procStateSeq);
23659                    }
23660                    return;
23661                }
23662                if (record.waitingForNetwork) {
23663                    if (DEBUG_NETWORK) {
23664                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
23665                                + ", procStateSeq: " + procStateSeq);
23666                    }
23667                    record.networkStateLock.notifyAll();
23668                }
23669            }
23670        }
23671
23672        /**
23673         * Called after virtual display Id is updated by
23674         * {@link com.android.server.vr.CompatibilityDisplay} with a specific
23675         * {@param vrCompatibilityDisplayId}.
23676         */
23677        @Override
23678        public void setVrCompatibilityDisplayId(int vrCompatibilityDisplayId) {
23679            if (DEBUG_STACK) {
23680                Slog.d(TAG, "setVrCompatibilityDisplayId called for: " +
23681                        vrCompatibilityDisplayId);
23682            }
23683            synchronized (ActivityManagerService.this) {
23684                mVrCompatibilityDisplayId = vrCompatibilityDisplayId;
23685            }
23686        }
23687    }
23688
23689    /**
23690     * Called by app main thread to wait for the network policy rules to get udpated.
23691     *
23692     * @param procStateSeq The sequence number indicating the process state change that the main
23693     *                     thread is interested in.
23694     */
23695    @Override
23696    public void waitForNetworkStateUpdate(long procStateSeq) {
23697        final int callingUid = Binder.getCallingUid();
23698        if (DEBUG_NETWORK) {
23699            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
23700        }
23701        UidRecord record;
23702        synchronized (this) {
23703            record = mActiveUids.get(callingUid);
23704            if (record == null) {
23705                return;
23706            }
23707        }
23708        synchronized (record.networkStateLock) {
23709            if (record.lastDispatchedProcStateSeq < procStateSeq) {
23710                if (DEBUG_NETWORK) {
23711                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
23712                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
23713                            + " lastProcStateSeqDispatchedToObservers: "
23714                            + record.lastDispatchedProcStateSeq);
23715                }
23716                return;
23717            }
23718            if (record.curProcStateSeq > procStateSeq) {
23719                if (DEBUG_NETWORK) {
23720                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
23721                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
23722                            + ", procStateSeq: " + procStateSeq);
23723                }
23724                return;
23725            }
23726            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23727                if (DEBUG_NETWORK) {
23728                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
23729                            + procStateSeq + ", so no need to wait. Uid: "
23730                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
23731                            + record.lastNetworkUpdatedProcStateSeq);
23732                }
23733                return;
23734            }
23735            try {
23736                if (DEBUG_NETWORK) {
23737                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
23738                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
23739                }
23740                final long startTime = SystemClock.uptimeMillis();
23741                record.waitingForNetwork = true;
23742                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
23743                record.waitingForNetwork = false;
23744                final long totalTime = SystemClock.uptimeMillis() - startTime;
23745                if (totalTime >= mWaitForNetworkTimeoutMs) {
23746                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
23747                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
23748                            + procStateSeq);
23749                } else if (DEBUG_NETWORK ||  totalTime >= mWaitForNetworkTimeoutMs / 2) {
23750                    Slog.d(TAG_NETWORK, "Total time waited for network rules to get updated: "
23751                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
23752                            + procStateSeq);
23753                }
23754            } catch (InterruptedException e) {
23755                Thread.currentThread().interrupt();
23756            }
23757        }
23758    }
23759
23760    /**
23761     * Return the user id of the last resumed activity.
23762     */
23763    @Override
23764    public @UserIdInt int getLastResumedActivityUserId() {
23765        enforceCallingPermission(
23766                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
23767        synchronized (this) {
23768            if (mLastResumedActivity == null) {
23769                return mUserController.getCurrentUserIdLocked();
23770            }
23771            return mLastResumedActivity.userId;
23772        }
23773    }
23774
23775    private final class SleepTokenImpl extends SleepToken {
23776        private final String mTag;
23777        private final long mAcquireTime;
23778
23779        public SleepTokenImpl(String tag) {
23780            mTag = tag;
23781            mAcquireTime = SystemClock.uptimeMillis();
23782        }
23783
23784        @Override
23785        public void release() {
23786            synchronized (ActivityManagerService.this) {
23787                if (mSleepTokens.remove(this)) {
23788                    updateSleepIfNeededLocked();
23789                }
23790            }
23791        }
23792
23793        @Override
23794        public String toString() {
23795            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
23796        }
23797    }
23798
23799    /**
23800     * An implementation of IAppTask, that allows an app to manage its own tasks via
23801     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
23802     * only the process that calls getAppTasks() can call the AppTask methods.
23803     */
23804    class AppTaskImpl extends IAppTask.Stub {
23805        private int mTaskId;
23806        private int mCallingUid;
23807
23808        public AppTaskImpl(int taskId, int callingUid) {
23809            mTaskId = taskId;
23810            mCallingUid = callingUid;
23811        }
23812
23813        private void checkCaller() {
23814            if (mCallingUid != Binder.getCallingUid()) {
23815                throw new SecurityException("Caller " + mCallingUid
23816                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
23817            }
23818        }
23819
23820        @Override
23821        public void finishAndRemoveTask() {
23822            checkCaller();
23823
23824            synchronized (ActivityManagerService.this) {
23825                long origId = Binder.clearCallingIdentity();
23826                try {
23827                    // We remove the task from recents to preserve backwards
23828                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
23829                            REMOVE_FROM_RECENTS)) {
23830                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23831                    }
23832                } finally {
23833                    Binder.restoreCallingIdentity(origId);
23834                }
23835            }
23836        }
23837
23838        @Override
23839        public ActivityManager.RecentTaskInfo getTaskInfo() {
23840            checkCaller();
23841
23842            synchronized (ActivityManagerService.this) {
23843                long origId = Binder.clearCallingIdentity();
23844                try {
23845                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23846                    if (tr == null) {
23847                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23848                    }
23849                    return createRecentTaskInfoFromTaskRecord(tr);
23850                } finally {
23851                    Binder.restoreCallingIdentity(origId);
23852                }
23853            }
23854        }
23855
23856        @Override
23857        public void moveToFront() {
23858            checkCaller();
23859            // Will bring task to front if it already has a root activity.
23860            final long origId = Binder.clearCallingIdentity();
23861            try {
23862                synchronized (this) {
23863                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
23864                }
23865            } finally {
23866                Binder.restoreCallingIdentity(origId);
23867            }
23868        }
23869
23870        @Override
23871        public int startActivity(IBinder whoThread, String callingPackage,
23872                Intent intent, String resolvedType, Bundle bOptions) {
23873            checkCaller();
23874
23875            int callingUser = UserHandle.getCallingUserId();
23876            TaskRecord tr;
23877            IApplicationThread appThread;
23878            synchronized (ActivityManagerService.this) {
23879                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23880                if (tr == null) {
23881                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23882                }
23883                appThread = IApplicationThread.Stub.asInterface(whoThread);
23884                if (appThread == null) {
23885                    throw new IllegalArgumentException("Bad app thread " + appThread);
23886                }
23887            }
23888            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
23889                    resolvedType, null, null, null, null, 0, 0, null, null,
23890                    null, bOptions, false, callingUser, null, tr);
23891        }
23892
23893        @Override
23894        public void setExcludeFromRecents(boolean exclude) {
23895            checkCaller();
23896
23897            synchronized (ActivityManagerService.this) {
23898                long origId = Binder.clearCallingIdentity();
23899                try {
23900                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23901                    if (tr == null) {
23902                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23903                    }
23904                    Intent intent = tr.getBaseIntent();
23905                    if (exclude) {
23906                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23907                    } else {
23908                        intent.setFlags(intent.getFlags()
23909                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23910                    }
23911                } finally {
23912                    Binder.restoreCallingIdentity(origId);
23913                }
23914            }
23915        }
23916    }
23917
23918    /**
23919     * Kill processes for the user with id userId and that depend on the package named packageName
23920     */
23921    @Override
23922    public void killPackageDependents(String packageName, int userId) {
23923        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
23924        if (packageName == null) {
23925            throw new NullPointerException(
23926                    "Cannot kill the dependents of a package without its name.");
23927        }
23928
23929        long callingId = Binder.clearCallingIdentity();
23930        IPackageManager pm = AppGlobals.getPackageManager();
23931        int pkgUid = -1;
23932        try {
23933            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
23934        } catch (RemoteException e) {
23935        }
23936        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
23937            throw new IllegalArgumentException(
23938                    "Cannot kill dependents of non-existing package " + packageName);
23939        }
23940        try {
23941            synchronized(this) {
23942                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
23943                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
23944                        "dep: " + packageName);
23945            }
23946        } finally {
23947            Binder.restoreCallingIdentity(callingId);
23948        }
23949    }
23950
23951    @Override
23952    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
23953            throws RemoteException {
23954        final long callingId = Binder.clearCallingIdentity();
23955        try {
23956            mKeyguardController.dismissKeyguard(token, callback);
23957        } finally {
23958            Binder.restoreCallingIdentity(callingId);
23959        }
23960    }
23961
23962    @Override
23963    public int restartUserInBackground(final int userId) {
23964        return mUserController.restartUser(userId, /* foreground */ false);
23965    }
23966
23967    @Override
23968    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
23969        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
23970                "scheduleApplicationInfoChanged()");
23971
23972        synchronized (this) {
23973            final long origId = Binder.clearCallingIdentity();
23974            try {
23975                updateApplicationInfoLocked(packageNames, userId);
23976            } finally {
23977                Binder.restoreCallingIdentity(origId);
23978            }
23979        }
23980    }
23981
23982    @Override
23983    public long getActivityStartInitiatedTime(IBinder token) {
23984        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
23985        if (r != null) {
23986            return r.mStartInitiatedTimeMs;
23987        }
23988        return 0;
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