ActivityManagerService.java revision 5da9f2a62b298c02c8c6c449a9a3c2deb295040e
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_PROCESSES;
124import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
125import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
126import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
127import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
128import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
138import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
139import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
140import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
141import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
142import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
143import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
144import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
145import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
146import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
147import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
148import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
152import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
153import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
154import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
155import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
156import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
157import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
158import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
159import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
160import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
161import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
162import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
163import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
164import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
165import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
166import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
167import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
168import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
169import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
170import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
171import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
172import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
173import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
174import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
175import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
176import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
177import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
178import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
179import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
180import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
181import static com.android.server.wm.AppTransition.TRANSIT_NONE;
182import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
183import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
184import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
185import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
186import static org.xmlpull.v1.XmlPullParser.START_TAG;
187
188import android.Manifest;
189import android.Manifest.permission;
190import android.annotation.NonNull;
191import android.annotation.Nullable;
192import android.annotation.UserIdInt;
193import android.app.Activity;
194import android.app.ActivityManager;
195import android.app.ActivityManager.RunningTaskInfo;
196import android.app.ActivityManager.StackId;
197import android.app.ActivityManager.StackInfo;
198import android.app.ActivityManager.TaskSnapshot;
199import android.app.ActivityManager.TaskThumbnailInfo;
200import android.app.ActivityManagerInternal;
201import android.app.ActivityManagerInternal.SleepToken;
202import android.app.ActivityOptions;
203import android.app.ActivityThread;
204import android.app.AlertDialog;
205import android.app.AppGlobals;
206import android.app.AppOpsManager;
207import android.app.ApplicationErrorReport;
208import android.app.ApplicationThreadConstants;
209import android.app.BroadcastOptions;
210import android.app.ContentProviderHolder;
211import android.app.Dialog;
212import android.app.IActivityContainer;
213import android.app.IActivityContainerCallback;
214import android.app.IActivityController;
215import android.app.IActivityManager;
216import android.app.IAppTask;
217import android.app.IApplicationThread;
218import android.app.IInstrumentationWatcher;
219import android.app.INotificationManager;
220import android.app.IProcessObserver;
221import android.app.IServiceConnection;
222import android.app.IStopUserCallback;
223import android.app.ITaskStackListener;
224import android.app.IUiAutomationConnection;
225import android.app.IUidObserver;
226import android.app.IUserSwitchObserver;
227import android.app.Instrumentation;
228import android.app.Notification;
229import android.app.NotificationManager;
230import android.app.PendingIntent;
231import android.app.PictureInPictureParams;
232import android.app.ProfilerInfo;
233import android.app.RemoteAction;
234import android.app.WaitResult;
235import android.app.admin.DevicePolicyManager;
236import android.app.assist.AssistContent;
237import android.app.assist.AssistStructure;
238import android.app.backup.IBackupManager;
239import android.app.usage.UsageEvents;
240import android.app.usage.UsageStatsManagerInternal;
241import android.appwidget.AppWidgetManager;
242import android.content.ActivityNotFoundException;
243import android.content.BroadcastReceiver;
244import android.content.ClipData;
245import android.content.ComponentCallbacks2;
246import android.content.ComponentName;
247import android.content.ContentProvider;
248import android.content.ContentResolver;
249import android.content.Context;
250import android.content.DialogInterface;
251import android.content.IContentProvider;
252import android.content.IIntentReceiver;
253import android.content.IIntentSender;
254import android.content.Intent;
255import android.content.IntentFilter;
256import android.content.IntentSender;
257import android.content.pm.ActivityInfo;
258import android.content.pm.ApplicationInfo;
259import android.content.pm.ConfigurationInfo;
260import android.content.pm.IPackageDataObserver;
261import android.content.pm.IPackageManager;
262import android.content.pm.InstrumentationInfo;
263import android.content.pm.PackageInfo;
264import android.content.pm.PackageManager;
265import android.content.pm.PackageManager.NameNotFoundException;
266import android.content.pm.PackageManagerInternal;
267import android.content.pm.ParceledListSlice;
268import android.content.pm.PathPermission;
269import android.content.pm.PermissionInfo;
270import android.content.pm.ProviderInfo;
271import android.content.pm.ResolveInfo;
272import android.content.pm.SELinuxUtil;
273import android.content.pm.ServiceInfo;
274import android.content.pm.UserInfo;
275import android.content.res.CompatibilityInfo;
276import android.content.res.Configuration;
277import android.content.res.Resources;
278import android.database.ContentObserver;
279import android.graphics.Bitmap;
280import android.graphics.Point;
281import android.graphics.Rect;
282import android.location.LocationManager;
283import android.media.audiofx.AudioEffect;
284import android.metrics.LogMaker;
285import android.net.Proxy;
286import android.net.ProxyInfo;
287import android.net.Uri;
288import android.os.BatteryStats;
289import android.os.Binder;
290import android.os.Build;
291import android.os.Bundle;
292import android.os.Debug;
293import android.os.DropBoxManager;
294import android.os.Environment;
295import android.os.FactoryTest;
296import android.os.FileObserver;
297import android.os.FileUtils;
298import android.os.Handler;
299import android.os.IBinder;
300import android.os.IDeviceIdentifiersPolicyService;
301import android.os.IPermissionController;
302import android.os.IProcessInfoService;
303import android.os.IProgressListener;
304import android.os.LocaleList;
305import android.os.Looper;
306import android.os.Message;
307import android.os.Parcel;
308import android.os.ParcelFileDescriptor;
309import android.os.PersistableBundle;
310import android.os.PowerManager;
311import android.os.PowerManagerInternal;
312import android.os.Process;
313import android.os.RemoteCallbackList;
314import android.os.RemoteException;
315import android.os.ResultReceiver;
316import android.os.ServiceManager;
317import android.os.ShellCallback;
318import android.os.StrictMode;
319import android.os.SystemClock;
320import android.os.SystemProperties;
321import android.os.Trace;
322import android.os.TransactionTooLargeException;
323import android.os.UpdateLock;
324import android.os.UserHandle;
325import android.os.UserManager;
326import android.os.WorkSource;
327import android.os.storage.IStorageManager;
328import android.os.storage.StorageManager;
329import android.os.storage.StorageManagerInternal;
330import android.provider.Downloads;
331import android.provider.Settings;
332import android.service.voice.IVoiceInteractionSession;
333import android.service.voice.VoiceInteractionManagerInternal;
334import android.service.voice.VoiceInteractionSession;
335import android.telecom.TelecomManager;
336import android.text.TextUtils;
337import android.text.format.DateUtils;
338import android.text.format.Time;
339import android.text.style.SuggestionSpan;
340import android.util.ArrayMap;
341import android.util.ArraySet;
342import android.util.AtomicFile;
343import android.util.BootTimingsTraceLog;
344import android.util.DebugUtils;
345import android.util.DisplayMetrics;
346import android.util.EventLog;
347import android.util.Log;
348import android.util.Pair;
349import android.util.PrintWriterPrinter;
350import android.util.Slog;
351import android.util.SparseArray;
352import android.util.SparseIntArray;
353import android.util.TimeUtils;
354import android.util.Xml;
355import android.view.Gravity;
356import android.view.LayoutInflater;
357import android.view.View;
358import android.view.WindowManager;
359
360import com.android.server.job.JobSchedulerInternal;
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.PinnedStackWindowController;
414import com.android.server.wm.WindowManagerService;
415
416import org.xmlpull.v1.XmlPullParser;
417import org.xmlpull.v1.XmlPullParserException;
418import org.xmlpull.v1.XmlSerializer;
419
420import java.io.File;
421import java.io.FileDescriptor;
422import java.io.FileInputStream;
423import java.io.FileNotFoundException;
424import java.io.FileOutputStream;
425import java.io.IOException;
426import java.io.InputStreamReader;
427import java.io.PrintWriter;
428import java.io.StringWriter;
429import java.io.UnsupportedEncodingException;
430import java.lang.ref.WeakReference;
431import java.nio.charset.StandardCharsets;
432import java.util.ArrayList;
433import java.util.Arrays;
434import java.util.Collections;
435import java.util.Comparator;
436import java.util.HashMap;
437import java.util.HashSet;
438import java.util.Iterator;
439import java.util.List;
440import java.util.Locale;
441import java.util.Map;
442import java.util.Objects;
443import java.util.Set;
444import java.util.concurrent.CountDownLatch;
445import java.util.concurrent.atomic.AtomicBoolean;
446import java.util.concurrent.atomic.AtomicLong;
447
448import dalvik.system.VMRuntime;
449import libcore.io.IoUtils;
450import libcore.util.EmptyArray;
451
452public class ActivityManagerService extends IActivityManager.Stub
453        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
454
455    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
456    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
457    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
458    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
459    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
460    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
461    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
462    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
463    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
464    private static final String TAG_LRU = TAG + POSTFIX_LRU;
465    private static final String TAG_MU = TAG + POSTFIX_MU;
466    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
467    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
468    private static final String TAG_POWER = TAG + POSTFIX_POWER;
469    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
470    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
471    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
472    private static final String TAG_PSS = TAG + POSTFIX_PSS;
473    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
474    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
475    private static final String TAG_STACK = TAG + POSTFIX_STACK;
476    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
477    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
478    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
479    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
480    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
481
482    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
483    // here so that while the job scheduler can depend on AMS, the other way around
484    // need not be the case.
485    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
486
487    /** Control over CPU and battery monitoring */
488    // write battery stats every 30 minutes.
489    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
490    static final boolean MONITOR_CPU_USAGE = true;
491    // don't sample cpu less than every 5 seconds.
492    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
493    // wait possibly forever for next cpu sample.
494    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
495    static final boolean MONITOR_THREAD_CPU_USAGE = false;
496
497    // The flags that are set for all calls we make to the package manager.
498    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
499
500    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
501
502    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
503
504    // Amount of time after a call to stopAppSwitches() during which we will
505    // prevent further untrusted switches from happening.
506    static final long APP_SWITCH_DELAY_TIME = 5*1000;
507
508    // How long we wait for a launched process to attach to the activity manager
509    // before we decide it's never going to come up for real.
510    static final int PROC_START_TIMEOUT = 10*1000;
511    // How long we wait for an attached process to publish its content providers
512    // before we decide it must be hung.
513    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
514
515    // How long we wait for a launched process to attach to the activity manager
516    // before we decide it's never going to come up for real, when the process was
517    // started with a wrapper for instrumentation (such as Valgrind) because it
518    // could take much longer than usual.
519    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
520
521    // How long we allow a receiver to run before giving up on it.
522    static final int BROADCAST_FG_TIMEOUT = 10*1000;
523    static final int BROADCAST_BG_TIMEOUT = 60*1000;
524
525    // How long we wait until we timeout on key dispatching.
526    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
527
528    // How long we wait until we timeout on key dispatching during instrumentation.
529    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
530
531    // How long to wait in getAssistContextExtras for the activity and foreground services
532    // to respond with the result.
533    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
534
535    // How long top wait when going through the modern assist (which doesn't need to block
536    // on getting this result before starting to launch its UI).
537    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
538
539    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
540    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
541
542    // Maximum number of persisted Uri grants a package is allowed
543    static final int MAX_PERSISTED_URI_GRANTS = 128;
544
545    static final int MY_PID = myPid();
546
547    static final String[] EMPTY_STRING_ARRAY = new String[0];
548
549    // How many bytes to write into the dropbox log before truncating
550    static final int DROPBOX_MAX_SIZE = 192 * 1024;
551    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
552    // as one line, but close enough for now.
553    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
554
555    // Access modes for handleIncomingUser.
556    static final int ALLOW_NON_FULL = 0;
557    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
558    static final int ALLOW_FULL_ONLY = 2;
559
560    // Necessary ApplicationInfo flags to mark an app as persistent
561    private static final int PERSISTENT_MASK =
562            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
563
564    // Intent sent when remote bugreport collection has been completed
565    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
566            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
567
568    // Used to indicate that an app transition should be animated.
569    static final boolean ANIMATE = true;
570
571    // Determines whether to take full screen screenshots
572    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
573
574    /**
575     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
576     */
577    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
578
579    /**
580     * State indicating that there is no need for any blocking for network.
581     */
582    @VisibleForTesting
583    static final int NETWORK_STATE_NO_CHANGE = 0;
584
585    /**
586     * State indicating that the main thread needs to be informed about the network wait.
587     */
588    @VisibleForTesting
589    static final int NETWORK_STATE_BLOCK = 1;
590
591    /**
592     * State indicating that any threads waiting for network state to get updated can be unblocked.
593     */
594    @VisibleForTesting
595    static final int NETWORK_STATE_UNBLOCK = 2;
596
597    // Max character limit for a notification title. If the notification title is larger than this
598    // the notification will not be legible to the user.
599    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
600
601    /** All system services */
602    SystemServiceManager mSystemServiceManager;
603    AssistUtils mAssistUtils;
604
605    private Installer mInstaller;
606
607    /** Run all ActivityStacks through this */
608    final ActivityStackSupervisor mStackSupervisor;
609    private final KeyguardController mKeyguardController;
610
611    final ActivityStarter mActivityStarter;
612
613    final TaskChangeNotificationController mTaskChangeNotificationController;
614
615    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
616
617    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
618
619    public final IntentFirewall mIntentFirewall;
620
621    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
622    // default action automatically.  Important for devices without direct input
623    // devices.
624    private boolean mShowDialogs = true;
625
626    private final VrController mVrController;
627
628    // VR Vr2d Display Id.
629    int mVr2dDisplayId = INVALID_DISPLAY;
630
631    // Whether we should use SCHED_FIFO for UI and RenderThreads.
632    private boolean mUseFifoUiScheduling = false;
633
634    BroadcastQueue mFgBroadcastQueue;
635    BroadcastQueue mBgBroadcastQueue;
636    // Convenient for easy iteration over the queues. Foreground is first
637    // so that dispatch of foreground broadcasts gets precedence.
638    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
639
640    BroadcastStats mLastBroadcastStats;
641    BroadcastStats mCurBroadcastStats;
642
643    BroadcastQueue broadcastQueueForIntent(Intent intent) {
644        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
645        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
646                "Broadcast intent " + intent + " on "
647                + (isFg ? "foreground" : "background") + " queue");
648        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
649    }
650
651    /**
652     * The last resumed activity. This is identical to the current resumed activity most
653     * of the time but could be different when we're pausing one activity before we resume
654     * another activity.
655     */
656    private ActivityRecord mLastResumedActivity;
657
658    /**
659     * If non-null, we are tracking the time the user spends in the currently focused app.
660     */
661    private AppTimeTracker mCurAppTimeTracker;
662
663    /**
664     * List of intents that were used to start the most recent tasks.
665     */
666    final RecentTasks mRecentTasks;
667
668    /**
669     * For addAppTask: cached of the last activity component that was added.
670     */
671    ComponentName mLastAddedTaskComponent;
672
673    /**
674     * For addAppTask: cached of the last activity uid that was added.
675     */
676    int mLastAddedTaskUid;
677
678    /**
679     * For addAppTask: cached of the last ActivityInfo that was added.
680     */
681    ActivityInfo mLastAddedTaskActivity;
682
683    /**
684     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
685     */
686    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
687
688    /**
689     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
690     */
691    String mDeviceOwnerName;
692
693    final UserController mUserController;
694
695    final AppErrors mAppErrors;
696
697    /**
698     * Indicates the maximum time spent waiting for the network rules to get updated.
699     */
700    @VisibleForTesting
701    long mWaitForNetworkTimeoutMs;
702
703    public boolean canShowErrorDialogs() {
704        return mShowDialogs && !mSleeping && !mShuttingDown
705                && !mKeyguardController.isKeyguardShowing();
706    }
707
708    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
709            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
710
711    static void boostPriorityForLockedSection() {
712        sThreadPriorityBooster.boost();
713    }
714
715    static void resetPriorityAfterLockedSection() {
716        sThreadPriorityBooster.reset();
717    }
718
719    public class PendingAssistExtras extends Binder implements Runnable {
720        public final ActivityRecord activity;
721        public boolean isHome;
722        public final Bundle extras;
723        public final Intent intent;
724        public final String hint;
725        public final IResultReceiver receiver;
726        public final int userHandle;
727        public boolean haveResult = false;
728        public Bundle result = null;
729        public AssistStructure structure = null;
730        public AssistContent content = null;
731        public Bundle receiverExtras;
732
733        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
734                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
735            activity = _activity;
736            extras = _extras;
737            intent = _intent;
738            hint = _hint;
739            receiver = _receiver;
740            receiverExtras = _receiverExtras;
741            userHandle = _userHandle;
742        }
743
744        @Override
745        public void run() {
746            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
747            synchronized (this) {
748                haveResult = true;
749                notifyAll();
750            }
751            pendingAssistExtrasTimedOut(this);
752        }
753    }
754
755    final ArrayList<PendingAssistExtras> mPendingAssistExtras
756            = new ArrayList<PendingAssistExtras>();
757
758    /**
759     * Process management.
760     */
761    final ProcessList mProcessList = new ProcessList();
762
763    /**
764     * All of the applications we currently have running organized by name.
765     * The keys are strings of the application package name (as
766     * returned by the package manager), and the keys are ApplicationRecord
767     * objects.
768     */
769    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
770
771    /**
772     * Tracking long-term execution of processes to look for abuse and other
773     * bad app behavior.
774     */
775    final ProcessStatsService mProcessStats;
776
777    /**
778     * The currently running isolated processes.
779     */
780    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
781
782    /**
783     * Counter for assigning isolated process uids, to avoid frequently reusing the
784     * same ones.
785     */
786    int mNextIsolatedProcessUid = 0;
787
788    /**
789     * The currently running heavy-weight process, if any.
790     */
791    ProcessRecord mHeavyWeightProcess = null;
792
793    /**
794     * Non-persistent appId whitelist for background restrictions
795     */
796    int[] mBackgroundAppIdWhitelist = new int[] {
797            BLUETOOTH_UID
798    };
799
800    /**
801     * Broadcast actions that will always be deliverable to unlaunched/background apps
802     */
803    ArraySet<String> mBackgroundLaunchBroadcasts;
804
805    /**
806     * All of the processes we currently have running organized by pid.
807     * The keys are the pid running the application.
808     *
809     * <p>NOTE: This object is protected by its own lock, NOT the global
810     * activity manager lock!
811     */
812    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
813
814    /**
815     * All of the processes that have been forced to be important.  The key
816     * is the pid of the caller who requested it (we hold a death
817     * link on it).
818     */
819    abstract class ImportanceToken implements IBinder.DeathRecipient {
820        final int pid;
821        final IBinder token;
822        final String reason;
823
824        ImportanceToken(int _pid, IBinder _token, String _reason) {
825            pid = _pid;
826            token = _token;
827            reason = _reason;
828        }
829
830        @Override
831        public String toString() {
832            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
833                    + " " + reason + " " + pid + " " + token + " }";
834        }
835    }
836    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
837
838    /**
839     * List of records for processes that someone had tried to start before the
840     * system was ready.  We don't start them at that point, but ensure they
841     * are started by the time booting is complete.
842     */
843    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
844
845    /**
846     * List of persistent applications that are in the process
847     * of being started.
848     */
849    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
850
851    /**
852     * Processes that are being forcibly torn down.
853     */
854    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
855
856    /**
857     * List of running applications, sorted by recent usage.
858     * The first entry in the list is the least recently used.
859     */
860    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
861
862    /**
863     * Where in mLruProcesses that the processes hosting activities start.
864     */
865    int mLruProcessActivityStart = 0;
866
867    /**
868     * Where in mLruProcesses that the processes hosting services start.
869     * This is after (lower index) than mLruProcessesActivityStart.
870     */
871    int mLruProcessServiceStart = 0;
872
873    /**
874     * List of processes that should gc as soon as things are idle.
875     */
876    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
877
878    /**
879     * Processes we want to collect PSS data from.
880     */
881    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
882
883    private boolean mBinderTransactionTrackingEnabled = false;
884
885    /**
886     * Last time we requested PSS data of all processes.
887     */
888    long mLastFullPssTime = SystemClock.uptimeMillis();
889
890    /**
891     * If set, the next time we collect PSS data we should do a full collection
892     * with data from native processes and the kernel.
893     */
894    boolean mFullPssPending = false;
895
896    /**
897     * This is the process holding what we currently consider to be
898     * the "home" activity.
899     */
900    ProcessRecord mHomeProcess;
901
902    /**
903     * This is the process holding the activity the user last visited that
904     * is in a different process from the one they are currently in.
905     */
906    ProcessRecord mPreviousProcess;
907
908    /**
909     * The time at which the previous process was last visible.
910     */
911    long mPreviousProcessVisibleTime;
912
913    /**
914     * Track all uids that have actively running processes.
915     */
916    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
917
918    /**
919     * This is for verifying the UID report flow.
920     */
921    static final boolean VALIDATE_UID_STATES = true;
922    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
923
924    /**
925     * Packages that the user has asked to have run in screen size
926     * compatibility mode instead of filling the screen.
927     */
928    final CompatModePackages mCompatModePackages;
929
930    /**
931     * Set of IntentSenderRecord objects that are currently active.
932     */
933    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
934            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
935
936    /**
937     * Fingerprints (hashCode()) of stack traces that we've
938     * already logged DropBox entries for.  Guarded by itself.  If
939     * something (rogue user app) forces this over
940     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
941     */
942    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
943    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
944
945    /**
946     * Strict Mode background batched logging state.
947     *
948     * The string buffer is guarded by itself, and its lock is also
949     * used to determine if another batched write is already
950     * in-flight.
951     */
952    private final StringBuilder mStrictModeBuffer = new StringBuilder();
953
954    /**
955     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
956     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
957     */
958    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
959
960    /**
961     * Resolver for broadcast intents to registered receivers.
962     * Holds BroadcastFilter (subclass of IntentFilter).
963     */
964    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
965            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
966        @Override
967        protected boolean allowFilterResult(
968                BroadcastFilter filter, List<BroadcastFilter> dest) {
969            IBinder target = filter.receiverList.receiver.asBinder();
970            for (int i = dest.size() - 1; i >= 0; i--) {
971                if (dest.get(i).receiverList.receiver.asBinder() == target) {
972                    return false;
973                }
974            }
975            return true;
976        }
977
978        @Override
979        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
980            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
981                    || userId == filter.owningUserId) {
982                return super.newResult(filter, match, userId);
983            }
984            return null;
985        }
986
987        @Override
988        protected BroadcastFilter[] newArray(int size) {
989            return new BroadcastFilter[size];
990        }
991
992        @Override
993        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
994            return packageName.equals(filter.packageName);
995        }
996    };
997
998    /**
999     * State of all active sticky broadcasts per user.  Keys are the action of the
1000     * sticky Intent, values are an ArrayList of all broadcasted intents with
1001     * that action (which should usually be one).  The SparseArray is keyed
1002     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1003     * for stickies that are sent to all users.
1004     */
1005    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1006            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1007
1008    final ActiveServices mServices;
1009
1010    final static class Association {
1011        final int mSourceUid;
1012        final String mSourceProcess;
1013        final int mTargetUid;
1014        final ComponentName mTargetComponent;
1015        final String mTargetProcess;
1016
1017        int mCount;
1018        long mTime;
1019
1020        int mNesting;
1021        long mStartTime;
1022
1023        // states of the source process when the bind occurred.
1024        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1025        long mLastStateUptime;
1026        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1027                - ActivityManager.MIN_PROCESS_STATE+1];
1028
1029        Association(int sourceUid, String sourceProcess, int targetUid,
1030                ComponentName targetComponent, String targetProcess) {
1031            mSourceUid = sourceUid;
1032            mSourceProcess = sourceProcess;
1033            mTargetUid = targetUid;
1034            mTargetComponent = targetComponent;
1035            mTargetProcess = targetProcess;
1036        }
1037    }
1038
1039    /**
1040     * When service association tracking is enabled, this is all of the associations we
1041     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1042     * -> association data.
1043     */
1044    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1045            mAssociations = new SparseArray<>();
1046    boolean mTrackingAssociations;
1047
1048    /**
1049     * Backup/restore process management
1050     */
1051    String mBackupAppName = null;
1052    BackupRecord mBackupTarget = null;
1053
1054    final ProviderMap mProviderMap;
1055
1056    /**
1057     * List of content providers who have clients waiting for them.  The
1058     * application is currently being launched and the provider will be
1059     * removed from this list once it is published.
1060     */
1061    final ArrayList<ContentProviderRecord> mLaunchingProviders
1062            = new ArrayList<ContentProviderRecord>();
1063
1064    /**
1065     * File storing persisted {@link #mGrantedUriPermissions}.
1066     */
1067    private final AtomicFile mGrantFile;
1068
1069    /** XML constants used in {@link #mGrantFile} */
1070    private static final String TAG_URI_GRANTS = "uri-grants";
1071    private static final String TAG_URI_GRANT = "uri-grant";
1072    private static final String ATTR_USER_HANDLE = "userHandle";
1073    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1074    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1075    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1076    private static final String ATTR_TARGET_PKG = "targetPkg";
1077    private static final String ATTR_URI = "uri";
1078    private static final String ATTR_MODE_FLAGS = "modeFlags";
1079    private static final String ATTR_CREATED_TIME = "createdTime";
1080    private static final String ATTR_PREFIX = "prefix";
1081
1082    /**
1083     * Global set of specific {@link Uri} permissions that have been granted.
1084     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1085     * to {@link UriPermission#uri} to {@link UriPermission}.
1086     */
1087    @GuardedBy("this")
1088    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1089            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1090
1091    public static class GrantUri {
1092        public final int sourceUserId;
1093        public final Uri uri;
1094        public boolean prefix;
1095
1096        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1097            this.sourceUserId = sourceUserId;
1098            this.uri = uri;
1099            this.prefix = prefix;
1100        }
1101
1102        @Override
1103        public int hashCode() {
1104            int hashCode = 1;
1105            hashCode = 31 * hashCode + sourceUserId;
1106            hashCode = 31 * hashCode + uri.hashCode();
1107            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1108            return hashCode;
1109        }
1110
1111        @Override
1112        public boolean equals(Object o) {
1113            if (o instanceof GrantUri) {
1114                GrantUri other = (GrantUri) o;
1115                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1116                        && prefix == other.prefix;
1117            }
1118            return false;
1119        }
1120
1121        @Override
1122        public String toString() {
1123            String result = uri.toString() + " [user " + sourceUserId + "]";
1124            if (prefix) result += " [prefix]";
1125            return result;
1126        }
1127
1128        public String toSafeString() {
1129            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1130            if (prefix) result += " [prefix]";
1131            return result;
1132        }
1133
1134        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1135            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1136                    ContentProvider.getUriWithoutUserId(uri), false);
1137        }
1138    }
1139
1140    CoreSettingsObserver mCoreSettingsObserver;
1141
1142    FontScaleSettingObserver mFontScaleSettingObserver;
1143
1144    private final class FontScaleSettingObserver extends ContentObserver {
1145        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1146
1147        public FontScaleSettingObserver() {
1148            super(mHandler);
1149            ContentResolver resolver = mContext.getContentResolver();
1150            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1151        }
1152
1153        @Override
1154        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1155            if (mFontScaleUri.equals(uri)) {
1156                updateFontScaleIfNeeded(userId);
1157            }
1158        }
1159    }
1160
1161    /**
1162     * Thread-local storage used to carry caller permissions over through
1163     * indirect content-provider access.
1164     */
1165    private class Identity {
1166        public final IBinder token;
1167        public final int pid;
1168        public final int uid;
1169
1170        Identity(IBinder _token, int _pid, int _uid) {
1171            token = _token;
1172            pid = _pid;
1173            uid = _uid;
1174        }
1175    }
1176
1177    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1178
1179    /**
1180     * All information we have collected about the runtime performance of
1181     * any user id that can impact battery performance.
1182     */
1183    final BatteryStatsService mBatteryStatsService;
1184
1185    /**
1186     * Information about component usage
1187     */
1188    UsageStatsManagerInternal mUsageStatsService;
1189
1190    /**
1191     * Access to DeviceIdleController service.
1192     */
1193    DeviceIdleController.LocalService mLocalDeviceIdleController;
1194
1195    /**
1196     * Set of app ids that are whitelisted for device idle and thus background check.
1197     */
1198    int[] mDeviceIdleWhitelist = new int[0];
1199
1200    /**
1201     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1202     */
1203    int[] mDeviceIdleTempWhitelist = new int[0];
1204
1205    static final class PendingTempWhitelist {
1206        final int targetUid;
1207        final long duration;
1208        final String tag;
1209
1210        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1211            targetUid = _targetUid;
1212            duration = _duration;
1213            tag = _tag;
1214        }
1215    }
1216
1217    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1218
1219    /**
1220     * Information about and control over application operations
1221     */
1222    final AppOpsService mAppOpsService;
1223
1224    /** Current sequencing integer of the configuration, for skipping old configurations. */
1225    private int mConfigurationSeq;
1226
1227    /**
1228     * Temp object used when global and/or display override configuration is updated. It is also
1229     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1230     * anyone...
1231     */
1232    private Configuration mTempConfig = new Configuration();
1233
1234    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1235            new UpdateConfigurationResult();
1236    private static final class UpdateConfigurationResult {
1237        // Configuration changes that were updated.
1238        int changes;
1239        // If the activity was relaunched to match the new configuration.
1240        boolean activityRelaunched;
1241
1242        void reset() {
1243            changes = 0;
1244            activityRelaunched = false;
1245        }
1246    }
1247
1248    boolean mSuppressResizeConfigChanges;
1249
1250    /**
1251     * Hardware-reported OpenGLES version.
1252     */
1253    final int GL_ES_VERSION;
1254
1255    /**
1256     * List of initialization arguments to pass to all processes when binding applications to them.
1257     * For example, references to the commonly used services.
1258     */
1259    HashMap<String, IBinder> mAppBindArgs;
1260    HashMap<String, IBinder> mIsolatedAppBindArgs;
1261
1262    /**
1263     * Temporary to avoid allocations.  Protected by main lock.
1264     */
1265    final StringBuilder mStringBuilder = new StringBuilder(256);
1266
1267    /**
1268     * Used to control how we initialize the service.
1269     */
1270    ComponentName mTopComponent;
1271    String mTopAction = Intent.ACTION_MAIN;
1272    String mTopData;
1273
1274    volatile boolean mProcessesReady = false;
1275    volatile boolean mSystemReady = false;
1276    volatile boolean mOnBattery = false;
1277    volatile int mFactoryTest;
1278
1279    @GuardedBy("this") boolean mBooting = false;
1280    @GuardedBy("this") boolean mCallFinishBooting = false;
1281    @GuardedBy("this") boolean mBootAnimationComplete = false;
1282    @GuardedBy("this") boolean mLaunchWarningShown = false;
1283    @GuardedBy("this") boolean mCheckedForSetup = false;
1284
1285    final Context mContext;
1286
1287    /**
1288     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1289     * change at runtime. Use mContext for non-UI purposes.
1290     */
1291    final Context mUiContext;
1292
1293    /**
1294     * The time at which we will allow normal application switches again,
1295     * after a call to {@link #stopAppSwitches()}.
1296     */
1297    long mAppSwitchesAllowedTime;
1298
1299    /**
1300     * This is set to true after the first switch after mAppSwitchesAllowedTime
1301     * is set; any switches after that will clear the time.
1302     */
1303    boolean mDidAppSwitch;
1304
1305    /**
1306     * Last time (in realtime) at which we checked for power usage.
1307     */
1308    long mLastPowerCheckRealtime;
1309
1310    /**
1311     * Last time (in uptime) at which we checked for power usage.
1312     */
1313    long mLastPowerCheckUptime;
1314
1315    /**
1316     * Set while we are wanting to sleep, to prevent any
1317     * activities from being started/resumed.
1318     *
1319     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1320     *
1321     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1322     * while in the sleep state until there is a pending transition out of sleep, in which case
1323     * mSleeping is set to false, and remains false while awake.
1324     *
1325     * Whether mSleeping can quickly toggled between true/false without the device actually
1326     * display changing states is undefined.
1327     */
1328    private boolean mSleeping = false;
1329
1330    /**
1331     * The process state used for processes that are running the top activities.
1332     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1333     */
1334    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1335
1336    /**
1337     * Set while we are running a voice interaction.  This overrides
1338     * sleeping while it is active.
1339     */
1340    private IVoiceInteractionSession mRunningVoice;
1341
1342    /**
1343     * For some direct access we need to power manager.
1344     */
1345    PowerManagerInternal mLocalPowerManager;
1346
1347    /**
1348     * We want to hold a wake lock while running a voice interaction session, since
1349     * this may happen with the screen off and we need to keep the CPU running to
1350     * be able to continue to interact with the user.
1351     */
1352    PowerManager.WakeLock mVoiceWakeLock;
1353
1354    /**
1355     * State of external calls telling us if the device is awake or asleep.
1356     */
1357    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1358
1359    /**
1360     * A list of tokens that cause the top activity to be put to sleep.
1361     * They are used by components that may hide and block interaction with underlying
1362     * activities.
1363     */
1364    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1365
1366    /**
1367     * Set if we are shutting down the system, similar to sleeping.
1368     */
1369    boolean mShuttingDown = false;
1370
1371    /**
1372     * Current sequence id for oom_adj computation traversal.
1373     */
1374    int mAdjSeq = 0;
1375
1376    /**
1377     * Current sequence id for process LRU updating.
1378     */
1379    int mLruSeq = 0;
1380
1381    /**
1382     * Keep track of the non-cached/empty process we last found, to help
1383     * determine how to distribute cached/empty processes next time.
1384     */
1385    int mNumNonCachedProcs = 0;
1386
1387    /**
1388     * Keep track of the number of cached hidden procs, to balance oom adj
1389     * distribution between those and empty procs.
1390     */
1391    int mNumCachedHiddenProcs = 0;
1392
1393    /**
1394     * Keep track of the number of service processes we last found, to
1395     * determine on the next iteration which should be B services.
1396     */
1397    int mNumServiceProcs = 0;
1398    int mNewNumAServiceProcs = 0;
1399    int mNewNumServiceProcs = 0;
1400
1401    /**
1402     * Allow the current computed overall memory level of the system to go down?
1403     * This is set to false when we are killing processes for reasons other than
1404     * memory management, so that the now smaller process list will not be taken as
1405     * an indication that memory is tighter.
1406     */
1407    boolean mAllowLowerMemLevel = false;
1408
1409    /**
1410     * The last computed memory level, for holding when we are in a state that
1411     * processes are going away for other reasons.
1412     */
1413    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1414
1415    /**
1416     * The last total number of process we have, to determine if changes actually look
1417     * like a shrinking number of process due to lower RAM.
1418     */
1419    int mLastNumProcesses;
1420
1421    /**
1422     * The uptime of the last time we performed idle maintenance.
1423     */
1424    long mLastIdleTime = SystemClock.uptimeMillis();
1425
1426    /**
1427     * Total time spent with RAM that has been added in the past since the last idle time.
1428     */
1429    long mLowRamTimeSinceLastIdle = 0;
1430
1431    /**
1432     * If RAM is currently low, when that horrible situation started.
1433     */
1434    long mLowRamStartTime = 0;
1435
1436    /**
1437     * For reporting to battery stats the current top application.
1438     */
1439    private String mCurResumedPackage = null;
1440    private int mCurResumedUid = -1;
1441
1442    /**
1443     * For reporting to battery stats the apps currently running foreground
1444     * service.  The ProcessMap is package/uid tuples; each of these contain
1445     * an array of the currently foreground processes.
1446     */
1447    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1448            = new ProcessMap<ArrayList<ProcessRecord>>();
1449
1450    /**
1451     * This is set if we had to do a delayed dexopt of an app before launching
1452     * it, to increase the ANR timeouts in that case.
1453     */
1454    boolean mDidDexOpt;
1455
1456    /**
1457     * Set if the systemServer made a call to enterSafeMode.
1458     */
1459    boolean mSafeMode;
1460
1461    /**
1462     * If true, we are running under a test environment so will sample PSS from processes
1463     * much more rapidly to try to collect better data when the tests are rapidly
1464     * running through apps.
1465     */
1466    boolean mTestPssMode = false;
1467
1468    String mDebugApp = null;
1469    boolean mWaitForDebugger = false;
1470    boolean mDebugTransient = false;
1471    String mOrigDebugApp = null;
1472    boolean mOrigWaitForDebugger = false;
1473    boolean mAlwaysFinishActivities = false;
1474    boolean mForceResizableActivities;
1475    boolean mSupportsMultiWindow;
1476    boolean mSupportsSplitScreenMultiWindow;
1477    boolean mSupportsFreeformWindowManagement;
1478    boolean mSupportsPictureInPicture;
1479    boolean mSupportsMultiDisplay;
1480    boolean mSupportsLeanbackOnly;
1481    IActivityController mController = null;
1482    boolean mControllerIsAMonkey = false;
1483    String mProfileApp = null;
1484    ProcessRecord mProfileProc = null;
1485    String mProfileFile;
1486    ParcelFileDescriptor mProfileFd;
1487    int mSamplingInterval = 0;
1488    boolean mAutoStopProfiler = false;
1489    boolean mStreamingOutput = false;
1490    int mProfileType = 0;
1491    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1492    String mMemWatchDumpProcName;
1493    String mMemWatchDumpFile;
1494    int mMemWatchDumpPid;
1495    int mMemWatchDumpUid;
1496    String mTrackAllocationApp = null;
1497    String mNativeDebuggingApp = null;
1498
1499    final long[] mTmpLong = new long[2];
1500
1501    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1502
1503    /**
1504     * A global counter for generating sequence numbers.
1505     * This value will be used when incrementing sequence numbers in individual uidRecords.
1506     *
1507     * Having a global counter ensures that seq numbers are monotonically increasing for a
1508     * particular uid even when the uidRecord is re-created.
1509     */
1510    @GuardedBy("this")
1511    @VisibleForTesting
1512    long mProcStateSeqCounter = 0;
1513
1514    private final Injector mInjector;
1515
1516    static final class ProcessChangeItem {
1517        static final int CHANGE_ACTIVITIES = 1<<0;
1518        int changes;
1519        int uid;
1520        int pid;
1521        int processState;
1522        boolean foregroundActivities;
1523    }
1524
1525    static final class UidObserverRegistration {
1526        final int uid;
1527        final String pkg;
1528        final int which;
1529        final int cutpoint;
1530
1531        final SparseIntArray lastProcStates;
1532
1533        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1534            uid = _uid;
1535            pkg = _pkg;
1536            which = _which;
1537            cutpoint = _cutpoint;
1538            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1539                lastProcStates = new SparseIntArray();
1540            } else {
1541                lastProcStates = null;
1542            }
1543        }
1544    }
1545
1546    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1547    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1548
1549    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1550    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1551
1552    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1553    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1554
1555    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1556    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1557
1558    /**
1559     * Runtime CPU use collection thread.  This object's lock is used to
1560     * perform synchronization with the thread (notifying it to run).
1561     */
1562    final Thread mProcessCpuThread;
1563
1564    /**
1565     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1566     * Must acquire this object's lock when accessing it.
1567     * NOTE: this lock will be held while doing long operations (trawling
1568     * through all processes in /proc), so it should never be acquired by
1569     * any critical paths such as when holding the main activity manager lock.
1570     */
1571    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1572            MONITOR_THREAD_CPU_USAGE);
1573    final AtomicLong mLastCpuTime = new AtomicLong(0);
1574    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1575    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1576
1577    long mLastWriteTime = 0;
1578
1579    /**
1580     * Used to retain an update lock when the foreground activity is in
1581     * immersive mode.
1582     */
1583    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1584
1585    /**
1586     * Set to true after the system has finished booting.
1587     */
1588    boolean mBooted = false;
1589
1590    WindowManagerService mWindowManager;
1591    final ActivityThread mSystemThread;
1592
1593    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1594        final ProcessRecord mApp;
1595        final int mPid;
1596        final IApplicationThread mAppThread;
1597
1598        AppDeathRecipient(ProcessRecord app, int pid,
1599                IApplicationThread thread) {
1600            if (DEBUG_ALL) Slog.v(
1601                TAG, "New death recipient " + this
1602                + " for thread " + thread.asBinder());
1603            mApp = app;
1604            mPid = pid;
1605            mAppThread = thread;
1606        }
1607
1608        @Override
1609        public void binderDied() {
1610            if (DEBUG_ALL) Slog.v(
1611                TAG, "Death received in " + this
1612                + " for thread " + mAppThread.asBinder());
1613            synchronized(ActivityManagerService.this) {
1614                appDiedLocked(mApp, mPid, mAppThread, true);
1615            }
1616        }
1617    }
1618
1619    static final int SHOW_ERROR_UI_MSG = 1;
1620    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1621    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1622    static final int UPDATE_CONFIGURATION_MSG = 4;
1623    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1624    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1625    static final int SERVICE_TIMEOUT_MSG = 12;
1626    static final int UPDATE_TIME_ZONE = 13;
1627    static final int SHOW_UID_ERROR_UI_MSG = 14;
1628    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1629    static final int PROC_START_TIMEOUT_MSG = 20;
1630    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1631    static final int KILL_APPLICATION_MSG = 22;
1632    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1633    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1634    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1635    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1636    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1637    static final int CLEAR_DNS_CACHE_MSG = 28;
1638    static final int UPDATE_HTTP_PROXY_MSG = 29;
1639    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1640    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1641    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1642    static final int REPORT_MEM_USAGE_MSG = 33;
1643    static final int REPORT_USER_SWITCH_MSG = 34;
1644    static final int CONTINUE_USER_SWITCH_MSG = 35;
1645    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1646    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1647    static final int PERSIST_URI_GRANTS_MSG = 38;
1648    static final int REQUEST_ALL_PSS_MSG = 39;
1649    static final int START_PROFILES_MSG = 40;
1650    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1651    static final int SYSTEM_USER_START_MSG = 42;
1652    static final int SYSTEM_USER_CURRENT_MSG = 43;
1653    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1654    static final int FINISH_BOOTING_MSG = 45;
1655    static final int START_USER_SWITCH_UI_MSG = 46;
1656    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1657    static final int DISMISS_DIALOG_UI_MSG = 48;
1658    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1659    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1660    static final int DELETE_DUMPHEAP_MSG = 51;
1661    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1662    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1663    static final int REPORT_TIME_TRACKER_MSG = 54;
1664    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1665    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1666    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1667    static final int IDLE_UIDS_MSG = 58;
1668    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1669    static final int LOG_STACK_STATE = 60;
1670    static final int VR_MODE_CHANGE_MSG = 61;
1671    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1672    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1673    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1674    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1675    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1676    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1677    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1678    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1679    static final int START_USER_SWITCH_FG_MSG = 712;
1680
1681    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1682    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1683    static final int FIRST_COMPAT_MODE_MSG = 300;
1684    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1685
1686    static ServiceThread sKillThread = null;
1687    static KillHandler sKillHandler = null;
1688
1689    CompatModeDialog mCompatModeDialog;
1690    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1691    long mLastMemUsageReportTime = 0;
1692
1693    /**
1694     * Flag whether the current user is a "monkey", i.e. whether
1695     * the UI is driven by a UI automation tool.
1696     */
1697    private boolean mUserIsMonkey;
1698
1699    /** Flag whether the device has a Recents UI */
1700    boolean mHasRecents;
1701
1702    /** The dimensions of the thumbnails in the Recents UI. */
1703    int mThumbnailWidth;
1704    int mThumbnailHeight;
1705    float mFullscreenThumbnailScale;
1706
1707    final ServiceThread mHandlerThread;
1708    final MainHandler mHandler;
1709    final Handler mUiHandler;
1710
1711    final ActivityManagerConstants mConstants;
1712
1713    PackageManagerInternal mPackageManagerInt;
1714
1715    // VoiceInteraction session ID that changes for each new request except when
1716    // being called for multiwindow assist in a single session.
1717    private int mViSessionId = 1000;
1718
1719    final boolean mPermissionReviewRequired;
1720
1721    /**
1722     * Current global configuration information. Contains general settings for the entire system,
1723     * also corresponds to the merged configuration of the default display.
1724     */
1725    Configuration getGlobalConfiguration() {
1726        return mStackSupervisor.getConfiguration();
1727    }
1728
1729    final class KillHandler extends Handler {
1730        static final int KILL_PROCESS_GROUP_MSG = 4000;
1731
1732        public KillHandler(Looper looper) {
1733            super(looper, null, true);
1734        }
1735
1736        @Override
1737        public void handleMessage(Message msg) {
1738            switch (msg.what) {
1739                case KILL_PROCESS_GROUP_MSG:
1740                {
1741                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1742                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1743                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1744                }
1745                break;
1746
1747                default:
1748                    super.handleMessage(msg);
1749            }
1750        }
1751    }
1752
1753    final class UiHandler extends Handler {
1754        public UiHandler() {
1755            super(com.android.server.UiThread.get().getLooper(), null, true);
1756        }
1757
1758        @Override
1759        public void handleMessage(Message msg) {
1760            switch (msg.what) {
1761            case SHOW_ERROR_UI_MSG: {
1762                mAppErrors.handleShowAppErrorUi(msg);
1763                ensureBootCompleted();
1764            } break;
1765            case SHOW_NOT_RESPONDING_UI_MSG: {
1766                mAppErrors.handleShowAnrUi(msg);
1767                ensureBootCompleted();
1768            } break;
1769            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1770                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1771                synchronized (ActivityManagerService.this) {
1772                    ProcessRecord proc = (ProcessRecord) data.get("app");
1773                    if (proc == null) {
1774                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1775                        break;
1776                    }
1777                    if (proc.crashDialog != null) {
1778                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1779                        return;
1780                    }
1781                    AppErrorResult res = (AppErrorResult) data.get("result");
1782                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1783                        Dialog d = new StrictModeViolationDialog(mContext,
1784                                ActivityManagerService.this, res, proc);
1785                        d.show();
1786                        proc.crashDialog = d;
1787                    } else {
1788                        // The device is asleep, so just pretend that the user
1789                        // saw a crash dialog and hit "force quit".
1790                        res.set(0);
1791                    }
1792                }
1793                ensureBootCompleted();
1794            } break;
1795            case SHOW_FACTORY_ERROR_UI_MSG: {
1796                Dialog d = new FactoryErrorDialog(
1797                        mUiContext, msg.getData().getCharSequence("msg"));
1798                d.show();
1799                ensureBootCompleted();
1800            } break;
1801            case WAIT_FOR_DEBUGGER_UI_MSG: {
1802                synchronized (ActivityManagerService.this) {
1803                    ProcessRecord app = (ProcessRecord)msg.obj;
1804                    if (msg.arg1 != 0) {
1805                        if (!app.waitedForDebugger) {
1806                            Dialog d = new AppWaitingForDebuggerDialog(
1807                                    ActivityManagerService.this,
1808                                    mUiContext, app);
1809                            app.waitDialog = d;
1810                            app.waitedForDebugger = true;
1811                            d.show();
1812                        }
1813                    } else {
1814                        if (app.waitDialog != null) {
1815                            app.waitDialog.dismiss();
1816                            app.waitDialog = null;
1817                        }
1818                    }
1819                }
1820            } break;
1821            case SHOW_UID_ERROR_UI_MSG: {
1822                if (mShowDialogs) {
1823                    AlertDialog d = new BaseErrorDialog(mUiContext);
1824                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1825                    d.setCancelable(false);
1826                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1827                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1828                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1829                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1830                    d.show();
1831                }
1832            } break;
1833            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1834                if (mShowDialogs) {
1835                    AlertDialog d = new BaseErrorDialog(mUiContext);
1836                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1837                    d.setCancelable(false);
1838                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1839                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1840                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1841                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1842                    d.show();
1843                }
1844            } break;
1845            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1846                synchronized (ActivityManagerService.this) {
1847                    ActivityRecord ar = (ActivityRecord) msg.obj;
1848                    if (mCompatModeDialog != null) {
1849                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1850                                ar.info.applicationInfo.packageName)) {
1851                            return;
1852                        }
1853                        mCompatModeDialog.dismiss();
1854                        mCompatModeDialog = null;
1855                    }
1856                    if (ar != null && false) {
1857                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1858                                ar.packageName)) {
1859                            int mode = mCompatModePackages.computeCompatModeLocked(
1860                                    ar.info.applicationInfo);
1861                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1862                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1863                                mCompatModeDialog = new CompatModeDialog(
1864                                        ActivityManagerService.this, mUiContext,
1865                                        ar.info.applicationInfo);
1866                                mCompatModeDialog.show();
1867                            }
1868                        }
1869                    }
1870                }
1871                break;
1872            }
1873            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1874                synchronized (ActivityManagerService.this) {
1875                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1876                    if (mUnsupportedDisplaySizeDialog != null) {
1877                        mUnsupportedDisplaySizeDialog.dismiss();
1878                        mUnsupportedDisplaySizeDialog = null;
1879                    }
1880                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1881                            ar.packageName)) {
1882                        // TODO(multi-display): Show dialog on appropriate display.
1883                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1884                                ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1885                        mUnsupportedDisplaySizeDialog.show();
1886                    }
1887                }
1888                break;
1889            }
1890            case START_USER_SWITCH_UI_MSG: {
1891                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1892                break;
1893            }
1894            case DISMISS_DIALOG_UI_MSG: {
1895                final Dialog d = (Dialog) msg.obj;
1896                d.dismiss();
1897                break;
1898            }
1899            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1900                dispatchProcessesChanged();
1901                break;
1902            }
1903            case DISPATCH_PROCESS_DIED_UI_MSG: {
1904                final int pid = msg.arg1;
1905                final int uid = msg.arg2;
1906                dispatchProcessDied(pid, uid);
1907                break;
1908            }
1909            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1910                dispatchUidsChanged();
1911            } break;
1912            case PUSH_TEMP_WHITELIST_UI_MSG: {
1913                pushTempWhitelist();
1914            } break;
1915            }
1916        }
1917    }
1918
1919    final class MainHandler extends Handler {
1920        public MainHandler(Looper looper) {
1921            super(looper, null, true);
1922        }
1923
1924        @Override
1925        public void handleMessage(Message msg) {
1926            switch (msg.what) {
1927            case UPDATE_CONFIGURATION_MSG: {
1928                final ContentResolver resolver = mContext.getContentResolver();
1929                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1930                        msg.arg1);
1931            } break;
1932            case GC_BACKGROUND_PROCESSES_MSG: {
1933                synchronized (ActivityManagerService.this) {
1934                    performAppGcsIfAppropriateLocked();
1935                }
1936            } break;
1937            case SERVICE_TIMEOUT_MSG: {
1938                if (mDidDexOpt) {
1939                    mDidDexOpt = false;
1940                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1941                    nmsg.obj = msg.obj;
1942                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1943                    return;
1944                }
1945                mServices.serviceTimeout((ProcessRecord)msg.obj);
1946            } break;
1947            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1948                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1949            } break;
1950            case SERVICE_FOREGROUND_CRASH_MSG: {
1951                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1952            } break;
1953            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1954                RemoteCallbackList<IResultReceiver> callbacks
1955                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
1956                int N = callbacks.beginBroadcast();
1957                for (int i = 0; i < N; i++) {
1958                    try {
1959                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1960                    } catch (RemoteException e) {
1961                    }
1962                }
1963                callbacks.finishBroadcast();
1964            } break;
1965            case UPDATE_TIME_ZONE: {
1966                synchronized (ActivityManagerService.this) {
1967                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1968                        ProcessRecord r = mLruProcesses.get(i);
1969                        if (r.thread != null) {
1970                            try {
1971                                r.thread.updateTimeZone();
1972                            } catch (RemoteException ex) {
1973                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1974                            }
1975                        }
1976                    }
1977                }
1978            } break;
1979            case CLEAR_DNS_CACHE_MSG: {
1980                synchronized (ActivityManagerService.this) {
1981                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1982                        ProcessRecord r = mLruProcesses.get(i);
1983                        if (r.thread != null) {
1984                            try {
1985                                r.thread.clearDnsCache();
1986                            } catch (RemoteException ex) {
1987                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1988                            }
1989                        }
1990                    }
1991                }
1992            } break;
1993            case UPDATE_HTTP_PROXY_MSG: {
1994                ProxyInfo proxy = (ProxyInfo)msg.obj;
1995                String host = "";
1996                String port = "";
1997                String exclList = "";
1998                Uri pacFileUrl = Uri.EMPTY;
1999                if (proxy != null) {
2000                    host = proxy.getHost();
2001                    port = Integer.toString(proxy.getPort());
2002                    exclList = proxy.getExclusionListAsString();
2003                    pacFileUrl = proxy.getPacFileUrl();
2004                }
2005                synchronized (ActivityManagerService.this) {
2006                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2007                        ProcessRecord r = mLruProcesses.get(i);
2008                        if (r.thread != null) {
2009                            try {
2010                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2011                            } catch (RemoteException ex) {
2012                                Slog.w(TAG, "Failed to update http proxy for: " +
2013                                        r.info.processName);
2014                            }
2015                        }
2016                    }
2017                }
2018            } break;
2019            case PROC_START_TIMEOUT_MSG: {
2020                if (mDidDexOpt) {
2021                    mDidDexOpt = false;
2022                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2023                    nmsg.obj = msg.obj;
2024                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
2025                    return;
2026                }
2027                ProcessRecord app = (ProcessRecord)msg.obj;
2028                synchronized (ActivityManagerService.this) {
2029                    processStartTimedOutLocked(app);
2030                }
2031            } break;
2032            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2033                ProcessRecord app = (ProcessRecord)msg.obj;
2034                synchronized (ActivityManagerService.this) {
2035                    processContentProviderPublishTimedOutLocked(app);
2036                }
2037            } break;
2038            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2039                synchronized (ActivityManagerService.this) {
2040                    mActivityStarter.doPendingActivityLaunchesLocked(true);
2041                }
2042            } break;
2043            case KILL_APPLICATION_MSG: {
2044                synchronized (ActivityManagerService.this) {
2045                    final int appId = msg.arg1;
2046                    final int userId = msg.arg2;
2047                    Bundle bundle = (Bundle)msg.obj;
2048                    String pkg = bundle.getString("pkg");
2049                    String reason = bundle.getString("reason");
2050                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2051                            false, userId, reason);
2052                }
2053            } break;
2054            case FINALIZE_PENDING_INTENT_MSG: {
2055                ((PendingIntentRecord)msg.obj).completeFinalize();
2056            } break;
2057            case POST_HEAVY_NOTIFICATION_MSG: {
2058                INotificationManager inm = NotificationManager.getService();
2059                if (inm == null) {
2060                    return;
2061                }
2062
2063                ActivityRecord root = (ActivityRecord)msg.obj;
2064                ProcessRecord process = root.app;
2065                if (process == null) {
2066                    return;
2067                }
2068
2069                try {
2070                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2071                    String text = mContext.getString(R.string.heavy_weight_notification,
2072                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2073                    Notification notification =
2074                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2075                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2076                            .setWhen(0)
2077                            .setOngoing(true)
2078                            .setTicker(text)
2079                            .setColor(mContext.getColor(
2080                                    com.android.internal.R.color.system_notification_accent_color))
2081                            .setContentTitle(text)
2082                            .setContentText(
2083                                    mContext.getText(R.string.heavy_weight_notification_detail))
2084                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2085                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2086                                    new UserHandle(root.userId)))
2087                            .build();
2088                    try {
2089                        inm.enqueueNotificationWithTag("android", "android", null,
2090                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2091                                notification, root.userId);
2092                    } catch (RuntimeException e) {
2093                        Slog.w(ActivityManagerService.TAG,
2094                                "Error showing notification for heavy-weight app", e);
2095                    } catch (RemoteException e) {
2096                    }
2097                } catch (NameNotFoundException e) {
2098                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2099                }
2100            } break;
2101            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2102                INotificationManager inm = NotificationManager.getService();
2103                if (inm == null) {
2104                    return;
2105                }
2106                try {
2107                    inm.cancelNotificationWithTag("android", null,
2108                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2109                } catch (RuntimeException e) {
2110                    Slog.w(ActivityManagerService.TAG,
2111                            "Error canceling notification for service", e);
2112                } catch (RemoteException e) {
2113                }
2114            } break;
2115            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2116                synchronized (ActivityManagerService.this) {
2117                    checkExcessivePowerUsageLocked(true);
2118                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2119                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2120                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
2121                }
2122            } break;
2123            case REPORT_MEM_USAGE_MSG: {
2124                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2125                Thread thread = new Thread() {
2126                    @Override public void run() {
2127                        reportMemUsage(memInfos);
2128                    }
2129                };
2130                thread.start();
2131                break;
2132            }
2133            case START_USER_SWITCH_FG_MSG: {
2134                mUserController.startUserInForeground(msg.arg1);
2135                break;
2136            }
2137            case REPORT_USER_SWITCH_MSG: {
2138                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2139                break;
2140            }
2141            case CONTINUE_USER_SWITCH_MSG: {
2142                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2143                break;
2144            }
2145            case USER_SWITCH_TIMEOUT_MSG: {
2146                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2147                break;
2148            }
2149            case IMMERSIVE_MODE_LOCK_MSG: {
2150                final boolean nextState = (msg.arg1 != 0);
2151                if (mUpdateLock.isHeld() != nextState) {
2152                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2153                            "Applying new update lock state '" + nextState
2154                            + "' for " + (ActivityRecord)msg.obj);
2155                    if (nextState) {
2156                        mUpdateLock.acquire();
2157                    } else {
2158                        mUpdateLock.release();
2159                    }
2160                }
2161                break;
2162            }
2163            case PERSIST_URI_GRANTS_MSG: {
2164                writeGrantedUriPermissions();
2165                break;
2166            }
2167            case REQUEST_ALL_PSS_MSG: {
2168                synchronized (ActivityManagerService.this) {
2169                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2170                }
2171                break;
2172            }
2173            case START_PROFILES_MSG: {
2174                synchronized (ActivityManagerService.this) {
2175                    mUserController.startProfilesLocked();
2176                }
2177                break;
2178            }
2179            case UPDATE_TIME_PREFERENCE_MSG: {
2180                // The user's time format preference might have changed.
2181                // For convenience we re-use the Intent extra values.
2182                synchronized (ActivityManagerService.this) {
2183                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2184                        ProcessRecord r = mLruProcesses.get(i);
2185                        if (r.thread != null) {
2186                            try {
2187                                r.thread.updateTimePrefs(msg.arg1);
2188                            } catch (RemoteException ex) {
2189                                Slog.w(TAG, "Failed to update preferences for: "
2190                                        + r.info.processName);
2191                            }
2192                        }
2193                    }
2194                }
2195                break;
2196            }
2197            case SYSTEM_USER_START_MSG: {
2198                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2199                        Integer.toString(msg.arg1), msg.arg1);
2200                mSystemServiceManager.startUser(msg.arg1);
2201                break;
2202            }
2203            case SYSTEM_USER_UNLOCK_MSG: {
2204                final int userId = msg.arg1;
2205                mSystemServiceManager.unlockUser(userId);
2206                synchronized (ActivityManagerService.this) {
2207                    mRecentTasks.loadUserRecentsLocked(userId);
2208                }
2209                if (userId == UserHandle.USER_SYSTEM) {
2210                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2211                }
2212                installEncryptionUnawareProviders(userId);
2213                mUserController.finishUserUnlocked((UserState) msg.obj);
2214                break;
2215            }
2216            case SYSTEM_USER_CURRENT_MSG: {
2217                mBatteryStatsService.noteEvent(
2218                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2219                        Integer.toString(msg.arg2), msg.arg2);
2220                mBatteryStatsService.noteEvent(
2221                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2222                        Integer.toString(msg.arg1), msg.arg1);
2223                mSystemServiceManager.switchUser(msg.arg1);
2224                break;
2225            }
2226            case ENTER_ANIMATION_COMPLETE_MSG: {
2227                synchronized (ActivityManagerService.this) {
2228                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2229                    if (r != null && r.app != null && r.app.thread != null) {
2230                        try {
2231                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2232                        } catch (RemoteException e) {
2233                        }
2234                    }
2235                }
2236                break;
2237            }
2238            case FINISH_BOOTING_MSG: {
2239                if (msg.arg1 != 0) {
2240                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2241                    finishBooting();
2242                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2243                }
2244                if (msg.arg2 != 0) {
2245                    enableScreenAfterBoot();
2246                }
2247                break;
2248            }
2249            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2250                try {
2251                    Locale l = (Locale) msg.obj;
2252                    IBinder service = ServiceManager.getService("mount");
2253                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2254                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2255                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2256                } catch (RemoteException e) {
2257                    Log.e(TAG, "Error storing locale for decryption UI", e);
2258                }
2259                break;
2260            }
2261            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2262                final int uid = msg.arg1;
2263                final byte[] firstPacket = (byte[]) msg.obj;
2264
2265                synchronized (mPidsSelfLocked) {
2266                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2267                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2268                        if (p.uid == uid) {
2269                            try {
2270                                p.thread.notifyCleartextNetwork(firstPacket);
2271                            } catch (RemoteException ignored) {
2272                            }
2273                        }
2274                    }
2275                }
2276                break;
2277            }
2278            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2279                final String procName;
2280                final int uid;
2281                final long memLimit;
2282                final String reportPackage;
2283                synchronized (ActivityManagerService.this) {
2284                    procName = mMemWatchDumpProcName;
2285                    uid = mMemWatchDumpUid;
2286                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2287                    if (val == null) {
2288                        val = mMemWatchProcesses.get(procName, 0);
2289                    }
2290                    if (val != null) {
2291                        memLimit = val.first;
2292                        reportPackage = val.second;
2293                    } else {
2294                        memLimit = 0;
2295                        reportPackage = null;
2296                    }
2297                }
2298                if (procName == null) {
2299                    return;
2300                }
2301
2302                if (DEBUG_PSS) Slog.d(TAG_PSS,
2303                        "Showing dump heap notification from " + procName + "/" + uid);
2304
2305                INotificationManager inm = NotificationManager.getService();
2306                if (inm == null) {
2307                    return;
2308                }
2309
2310                String text = mContext.getString(R.string.dump_heap_notification, procName);
2311
2312
2313                Intent deleteIntent = new Intent();
2314                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2315                Intent intent = new Intent();
2316                intent.setClassName("android", DumpHeapActivity.class.getName());
2317                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2318                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2319                if (reportPackage != null) {
2320                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2321                }
2322                int userId = UserHandle.getUserId(uid);
2323                Notification notification =
2324                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2325                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2326                        .setWhen(0)
2327                        .setOngoing(true)
2328                        .setAutoCancel(true)
2329                        .setTicker(text)
2330                        .setColor(mContext.getColor(
2331                                com.android.internal.R.color.system_notification_accent_color))
2332                        .setContentTitle(text)
2333                        .setContentText(
2334                                mContext.getText(R.string.dump_heap_notification_detail))
2335                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2336                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2337                                new UserHandle(userId)))
2338                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2339                                deleteIntent, 0, UserHandle.SYSTEM))
2340                        .build();
2341
2342                try {
2343                    inm.enqueueNotificationWithTag("android", "android", null,
2344                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2345                            notification, userId);
2346                } catch (RuntimeException e) {
2347                    Slog.w(ActivityManagerService.TAG,
2348                            "Error showing notification for dump heap", e);
2349                } catch (RemoteException e) {
2350                }
2351            } break;
2352            case DELETE_DUMPHEAP_MSG: {
2353                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2354                        null, DumpHeapActivity.JAVA_URI,
2355                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2356                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2357                        UserHandle.myUserId());
2358                synchronized (ActivityManagerService.this) {
2359                    mMemWatchDumpFile = null;
2360                    mMemWatchDumpProcName = null;
2361                    mMemWatchDumpPid = -1;
2362                    mMemWatchDumpUid = -1;
2363                }
2364            } break;
2365            case FOREGROUND_PROFILE_CHANGED_MSG: {
2366                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2367            } break;
2368            case REPORT_TIME_TRACKER_MSG: {
2369                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2370                tracker.deliverResult(mContext);
2371            } break;
2372            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2373                mUserController.dispatchUserSwitchComplete(msg.arg1);
2374            } break;
2375            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2376                mUserController.dispatchLockedBootComplete(msg.arg1);
2377            } break;
2378            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2379                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2380                try {
2381                    connection.shutdown();
2382                } catch (RemoteException e) {
2383                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2384                }
2385                // Only a UiAutomation can set this flag and now that
2386                // it is finished we make sure it is reset to its default.
2387                mUserIsMonkey = false;
2388            } break;
2389            case IDLE_UIDS_MSG: {
2390                idleUids();
2391            } break;
2392            case VR_MODE_CHANGE_MSG: {
2393                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2394                    return;
2395                }
2396                synchronized (ActivityManagerService.this) {
2397                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2398                    mWindowManager.disableNonVrUi(disableNonVrUi);
2399                    if (disableNonVrUi) {
2400                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2401                        // then remove the pinned stack.
2402                        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2403                                PINNED_STACK_ID);
2404                        if (pinnedStack != null) {
2405                            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2406                        }
2407                    }
2408                }
2409            } break;
2410            case NOTIFY_VR_SLEEPING_MSG: {
2411                notifyVrManagerOfSleepState(msg.arg1 != 0);
2412            } break;
2413            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2414                synchronized (ActivityManagerService.this) {
2415                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2416                        ProcessRecord r = mLruProcesses.get(i);
2417                        if (r.thread != null) {
2418                            try {
2419                                r.thread.handleTrustStorageUpdate();
2420                            } catch (RemoteException ex) {
2421                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2422                                        r.info.processName);
2423                            }
2424                        }
2425                    }
2426                }
2427            } break;
2428            }
2429        }
2430    };
2431
2432    static final int COLLECT_PSS_BG_MSG = 1;
2433
2434    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2435        @Override
2436        public void handleMessage(Message msg) {
2437            switch (msg.what) {
2438            case COLLECT_PSS_BG_MSG: {
2439                long start = SystemClock.uptimeMillis();
2440                MemInfoReader memInfo = null;
2441                synchronized (ActivityManagerService.this) {
2442                    if (mFullPssPending) {
2443                        mFullPssPending = false;
2444                        memInfo = new MemInfoReader();
2445                    }
2446                }
2447                if (memInfo != null) {
2448                    updateCpuStatsNow();
2449                    long nativeTotalPss = 0;
2450                    final List<ProcessCpuTracker.Stats> stats;
2451                    synchronized (mProcessCpuTracker) {
2452                        stats = mProcessCpuTracker.getStats( (st)-> {
2453                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2454                        });
2455                    }
2456                    final int N = stats.size();
2457                    for (int j = 0; j < N; j++) {
2458                        synchronized (mPidsSelfLocked) {
2459                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2460                                // This is one of our own processes; skip it.
2461                                continue;
2462                            }
2463                        }
2464                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2465                    }
2466                    memInfo.readMemInfo();
2467                    synchronized (ActivityManagerService.this) {
2468                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2469                                + (SystemClock.uptimeMillis()-start) + "ms");
2470                        final long cachedKb = memInfo.getCachedSizeKb();
2471                        final long freeKb = memInfo.getFreeSizeKb();
2472                        final long zramKb = memInfo.getZramTotalSizeKb();
2473                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2474                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2475                                kernelKb*1024, nativeTotalPss*1024);
2476                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2477                                nativeTotalPss);
2478                    }
2479                }
2480
2481                int num = 0;
2482                long[] tmp = new long[2];
2483                do {
2484                    ProcessRecord proc;
2485                    int procState;
2486                    int pid;
2487                    long lastPssTime;
2488                    synchronized (ActivityManagerService.this) {
2489                        if (mPendingPssProcesses.size() <= 0) {
2490                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2491                                    "Collected PSS of " + num + " processes in "
2492                                    + (SystemClock.uptimeMillis() - start) + "ms");
2493                            mPendingPssProcesses.clear();
2494                            return;
2495                        }
2496                        proc = mPendingPssProcesses.remove(0);
2497                        procState = proc.pssProcState;
2498                        lastPssTime = proc.lastPssTime;
2499                        if (proc.thread != null && procState == proc.setProcState
2500                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2501                                        < SystemClock.uptimeMillis()) {
2502                            pid = proc.pid;
2503                        } else {
2504                            proc = null;
2505                            pid = 0;
2506                        }
2507                    }
2508                    if (proc != null) {
2509                        long pss = Debug.getPss(pid, tmp, null);
2510                        synchronized (ActivityManagerService.this) {
2511                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2512                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2513                                num++;
2514                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2515                                        SystemClock.uptimeMillis());
2516                            }
2517                        }
2518                    }
2519                } while (true);
2520            }
2521            }
2522        }
2523    };
2524
2525    public void setSystemProcess() {
2526        try {
2527            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2528            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2529            ServiceManager.addService("meminfo", new MemBinder(this));
2530            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2531            ServiceManager.addService("dbinfo", new DbBinder(this));
2532            if (MONITOR_CPU_USAGE) {
2533                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2534            }
2535            ServiceManager.addService("permission", new PermissionController(this));
2536            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2537
2538            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2539                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2540            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2541
2542            synchronized (this) {
2543                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2544                app.persistent = true;
2545                app.pid = MY_PID;
2546                app.maxAdj = ProcessList.SYSTEM_ADJ;
2547                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2548                synchronized (mPidsSelfLocked) {
2549                    mPidsSelfLocked.put(app.pid, app);
2550                }
2551                updateLruProcessLocked(app, false, null);
2552                updateOomAdjLocked();
2553            }
2554        } catch (PackageManager.NameNotFoundException e) {
2555            throw new RuntimeException(
2556                    "Unable to find android system package", e);
2557        }
2558    }
2559
2560    public void setWindowManager(WindowManagerService wm) {
2561        mWindowManager = wm;
2562        mStackSupervisor.setWindowManager(wm);
2563        mActivityStarter.setWindowManager(wm);
2564    }
2565
2566    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2567        mUsageStatsService = usageStatsManager;
2568    }
2569
2570    public void startObservingNativeCrashes() {
2571        final NativeCrashListener ncl = new NativeCrashListener(this);
2572        ncl.start();
2573    }
2574
2575    public IAppOpsService getAppOpsService() {
2576        return mAppOpsService;
2577    }
2578
2579    static class MemBinder extends Binder {
2580        ActivityManagerService mActivityManagerService;
2581        MemBinder(ActivityManagerService activityManagerService) {
2582            mActivityManagerService = activityManagerService;
2583        }
2584
2585        @Override
2586        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2587            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2588                    "meminfo", pw)) return;
2589            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2590        }
2591    }
2592
2593    static class GraphicsBinder extends Binder {
2594        ActivityManagerService mActivityManagerService;
2595        GraphicsBinder(ActivityManagerService activityManagerService) {
2596            mActivityManagerService = activityManagerService;
2597        }
2598
2599        @Override
2600        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2601            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2602                    "gfxinfo", pw)) return;
2603            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2604        }
2605    }
2606
2607    static class DbBinder extends Binder {
2608        ActivityManagerService mActivityManagerService;
2609        DbBinder(ActivityManagerService activityManagerService) {
2610            mActivityManagerService = activityManagerService;
2611        }
2612
2613        @Override
2614        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2615            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2616                    "dbinfo", pw)) return;
2617            mActivityManagerService.dumpDbInfo(fd, pw, args);
2618        }
2619    }
2620
2621    static class CpuBinder extends Binder {
2622        ActivityManagerService mActivityManagerService;
2623        CpuBinder(ActivityManagerService activityManagerService) {
2624            mActivityManagerService = activityManagerService;
2625        }
2626
2627        @Override
2628        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2629            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2630                    "cpuinfo", pw)) return;
2631            synchronized (mActivityManagerService.mProcessCpuTracker) {
2632                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2633                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2634                        SystemClock.uptimeMillis()));
2635            }
2636        }
2637    }
2638
2639    public static final class Lifecycle extends SystemService {
2640        private final ActivityManagerService mService;
2641
2642        public Lifecycle(Context context) {
2643            super(context);
2644            mService = new ActivityManagerService(context);
2645        }
2646
2647        @Override
2648        public void onStart() {
2649            mService.start();
2650        }
2651
2652        public ActivityManagerService getService() {
2653            return mService;
2654        }
2655    }
2656
2657    @VisibleForTesting
2658    public ActivityManagerService(Injector injector) {
2659        mInjector = injector;
2660        mContext = mInjector.getContext();
2661        mUiContext = null;
2662        GL_ES_VERSION = 0;
2663        mActivityStarter = null;
2664        mAppErrors = null;
2665        mAppOpsService = mInjector.getAppOpsService(null, null);
2666        mBatteryStatsService = null;
2667        mCompatModePackages = null;
2668        mConstants = null;
2669        mGrantFile = null;
2670        mHandler = null;
2671        mHandlerThread = null;
2672        mIntentFirewall = null;
2673        mKeyguardController = null;
2674        mPermissionReviewRequired = false;
2675        mProcessCpuThread = null;
2676        mProcessStats = null;
2677        mProviderMap = null;
2678        mRecentTasks = null;
2679        mServices = null;
2680        mStackSupervisor = null;
2681        mSystemThread = null;
2682        mTaskChangeNotificationController = null;
2683        mUiHandler = injector.getUiHandler(null);
2684        mUserController = null;
2685        mVrController = null;
2686    }
2687
2688    // Note: This method is invoked on the main thread but may need to attach various
2689    // handlers to other threads.  So take care to be explicit about the looper.
2690    public ActivityManagerService(Context systemContext) {
2691        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2692        mInjector = new Injector();
2693        mContext = systemContext;
2694
2695        mFactoryTest = FactoryTest.getMode();
2696        mSystemThread = ActivityThread.currentActivityThread();
2697        mUiContext = mSystemThread.getSystemUiContext();
2698
2699        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2700
2701        mPermissionReviewRequired = mContext.getResources().getBoolean(
2702                com.android.internal.R.bool.config_permissionReviewRequired);
2703
2704        mHandlerThread = new ServiceThread(TAG,
2705                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2706        mHandlerThread.start();
2707        mHandler = new MainHandler(mHandlerThread.getLooper());
2708        mUiHandler = mInjector.getUiHandler(this);
2709
2710        mConstants = new ActivityManagerConstants(this, mHandler);
2711
2712        /* static; one-time init here */
2713        if (sKillHandler == null) {
2714            sKillThread = new ServiceThread(TAG + ":kill",
2715                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2716            sKillThread.start();
2717            sKillHandler = new KillHandler(sKillThread.getLooper());
2718        }
2719
2720        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2721                "foreground", BROADCAST_FG_TIMEOUT, false);
2722        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2723                "background", BROADCAST_BG_TIMEOUT, true);
2724        mBroadcastQueues[0] = mFgBroadcastQueue;
2725        mBroadcastQueues[1] = mBgBroadcastQueue;
2726
2727        mServices = new ActiveServices(this);
2728        mProviderMap = new ProviderMap(this);
2729        mAppErrors = new AppErrors(mUiContext, this);
2730
2731        // TODO: Move creation of battery stats service outside of activity manager service.
2732        File dataDir = Environment.getDataDirectory();
2733        File systemDir = new File(dataDir, "system");
2734        systemDir.mkdirs();
2735        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2736        mBatteryStatsService.getActiveStatistics().readLocked();
2737        mBatteryStatsService.scheduleWriteToDisk();
2738        mOnBattery = DEBUG_POWER ? true
2739                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2740        mBatteryStatsService.getActiveStatistics().setCallback(this);
2741
2742        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2743
2744        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2745        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2746                new IAppOpsCallback.Stub() {
2747                    @Override public void opChanged(int op, int uid, String packageName) {
2748                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2749                            if (mAppOpsService.checkOperation(op, uid, packageName)
2750                                    != AppOpsManager.MODE_ALLOWED) {
2751                                runInBackgroundDisabled(uid);
2752                            }
2753                        }
2754                    }
2755                });
2756
2757        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2758
2759        mUserController = new UserController(this);
2760
2761        mVrController = new VrController(this);
2762
2763        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2764            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2765
2766        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2767            mUseFifoUiScheduling = true;
2768        }
2769
2770        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2771        mTempConfig.setToDefaults();
2772        mTempConfig.setLocales(LocaleList.getDefault());
2773        mConfigurationSeq = mTempConfig.seq = 1;
2774        mStackSupervisor = createStackSupervisor();
2775        mStackSupervisor.onConfigurationChanged(mTempConfig);
2776        mKeyguardController = mStackSupervisor.mKeyguardController;
2777        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2778        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2779        mTaskChangeNotificationController =
2780                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2781        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2782        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2783
2784        mProcessCpuThread = new Thread("CpuTracker") {
2785            @Override
2786            public void run() {
2787                synchronized (mProcessCpuTracker) {
2788                    mProcessCpuInitLatch.countDown();
2789                    mProcessCpuTracker.init();
2790                }
2791                while (true) {
2792                    try {
2793                        try {
2794                            synchronized(this) {
2795                                final long now = SystemClock.uptimeMillis();
2796                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2797                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2798                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2799                                //        + ", write delay=" + nextWriteDelay);
2800                                if (nextWriteDelay < nextCpuDelay) {
2801                                    nextCpuDelay = nextWriteDelay;
2802                                }
2803                                if (nextCpuDelay > 0) {
2804                                    mProcessCpuMutexFree.set(true);
2805                                    this.wait(nextCpuDelay);
2806                                }
2807                            }
2808                        } catch (InterruptedException e) {
2809                        }
2810                        updateCpuStatsNow();
2811                    } catch (Exception e) {
2812                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2813                    }
2814                }
2815            }
2816        };
2817
2818        Watchdog.getInstance().addMonitor(this);
2819        Watchdog.getInstance().addThread(mHandler);
2820    }
2821
2822    protected ActivityStackSupervisor createStackSupervisor() {
2823        return new ActivityStackSupervisor(this, mHandler.getLooper());
2824    }
2825
2826    public void setSystemServiceManager(SystemServiceManager mgr) {
2827        mSystemServiceManager = mgr;
2828    }
2829
2830    public void setInstaller(Installer installer) {
2831        mInstaller = installer;
2832    }
2833
2834    private void start() {
2835        removeAllProcessGroups();
2836        mProcessCpuThread.start();
2837
2838        mBatteryStatsService.publish(mContext);
2839        mAppOpsService.publish(mContext);
2840        Slog.d("AppOps", "AppOpsService published");
2841        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2842        // Wait for the synchronized block started in mProcessCpuThread,
2843        // so that any other acccess to mProcessCpuTracker from main thread
2844        // will be blocked during mProcessCpuTracker initialization.
2845        try {
2846            mProcessCpuInitLatch.await();
2847        } catch (InterruptedException e) {
2848            Slog.wtf(TAG, "Interrupted wait during start", e);
2849            Thread.currentThread().interrupt();
2850            throw new IllegalStateException("Interrupted wait during start");
2851        }
2852    }
2853
2854    void onUserStoppedLocked(int userId) {
2855        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2856    }
2857
2858    public void initPowerManagement() {
2859        mStackSupervisor.initPowerManagement();
2860        mBatteryStatsService.initPowerManagement();
2861        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2862        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2863        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2864        mVoiceWakeLock.setReferenceCounted(false);
2865    }
2866
2867    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2868        if (mBackgroundLaunchBroadcasts == null) {
2869            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2870        }
2871        return mBackgroundLaunchBroadcasts;
2872    }
2873
2874    @Override
2875    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2876            throws RemoteException {
2877        if (code == SYSPROPS_TRANSACTION) {
2878            // We need to tell all apps about the system property change.
2879            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2880            synchronized(this) {
2881                final int NP = mProcessNames.getMap().size();
2882                for (int ip=0; ip<NP; ip++) {
2883                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2884                    final int NA = apps.size();
2885                    for (int ia=0; ia<NA; ia++) {
2886                        ProcessRecord app = apps.valueAt(ia);
2887                        if (app.thread != null) {
2888                            procs.add(app.thread.asBinder());
2889                        }
2890                    }
2891                }
2892            }
2893
2894            int N = procs.size();
2895            for (int i=0; i<N; i++) {
2896                Parcel data2 = Parcel.obtain();
2897                try {
2898                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2899                            Binder.FLAG_ONEWAY);
2900                } catch (RemoteException e) {
2901                }
2902                data2.recycle();
2903            }
2904        }
2905        try {
2906            return super.onTransact(code, data, reply, flags);
2907        } catch (RuntimeException e) {
2908            // The activity manager only throws security exceptions, so let's
2909            // log all others.
2910            if (!(e instanceof SecurityException)) {
2911                Slog.wtf(TAG, "Activity Manager Crash", e);
2912            }
2913            throw e;
2914        }
2915    }
2916
2917    void updateCpuStats() {
2918        final long now = SystemClock.uptimeMillis();
2919        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2920            return;
2921        }
2922        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2923            synchronized (mProcessCpuThread) {
2924                mProcessCpuThread.notify();
2925            }
2926        }
2927    }
2928
2929    void updateCpuStatsNow() {
2930        synchronized (mProcessCpuTracker) {
2931            mProcessCpuMutexFree.set(false);
2932            final long now = SystemClock.uptimeMillis();
2933            boolean haveNewCpuStats = false;
2934
2935            if (MONITOR_CPU_USAGE &&
2936                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2937                mLastCpuTime.set(now);
2938                mProcessCpuTracker.update();
2939                if (mProcessCpuTracker.hasGoodLastStats()) {
2940                    haveNewCpuStats = true;
2941                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2942                    //Slog.i(TAG, "Total CPU usage: "
2943                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2944
2945                    // Slog the cpu usage if the property is set.
2946                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2947                        int user = mProcessCpuTracker.getLastUserTime();
2948                        int system = mProcessCpuTracker.getLastSystemTime();
2949                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2950                        int irq = mProcessCpuTracker.getLastIrqTime();
2951                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2952                        int idle = mProcessCpuTracker.getLastIdleTime();
2953
2954                        int total = user + system + iowait + irq + softIrq + idle;
2955                        if (total == 0) total = 1;
2956
2957                        EventLog.writeEvent(EventLogTags.CPU,
2958                                ((user+system+iowait+irq+softIrq) * 100) / total,
2959                                (user * 100) / total,
2960                                (system * 100) / total,
2961                                (iowait * 100) / total,
2962                                (irq * 100) / total,
2963                                (softIrq * 100) / total);
2964                    }
2965                }
2966            }
2967
2968            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2969            synchronized(bstats) {
2970                synchronized(mPidsSelfLocked) {
2971                    if (haveNewCpuStats) {
2972                        if (bstats.startAddingCpuLocked()) {
2973                            int totalUTime = 0;
2974                            int totalSTime = 0;
2975                            final int N = mProcessCpuTracker.countStats();
2976                            for (int i=0; i<N; i++) {
2977                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2978                                if (!st.working) {
2979                                    continue;
2980                                }
2981                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2982                                totalUTime += st.rel_utime;
2983                                totalSTime += st.rel_stime;
2984                                if (pr != null) {
2985                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2986                                    if (ps == null || !ps.isActive()) {
2987                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2988                                                pr.info.uid, pr.processName);
2989                                    }
2990                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2991                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2992                                } else {
2993                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2994                                    if (ps == null || !ps.isActive()) {
2995                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2996                                                bstats.mapUid(st.uid), st.name);
2997                                    }
2998                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2999                                }
3000                            }
3001                            final int userTime = mProcessCpuTracker.getLastUserTime();
3002                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3003                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3004                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3005                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3006                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3007                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3008                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3009                        }
3010                    }
3011                }
3012
3013                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3014                    mLastWriteTime = now;
3015                    mBatteryStatsService.scheduleWriteToDisk();
3016                }
3017            }
3018        }
3019    }
3020
3021    @Override
3022    public void batteryNeedsCpuUpdate() {
3023        updateCpuStatsNow();
3024    }
3025
3026    @Override
3027    public void batteryPowerChanged(boolean onBattery) {
3028        // When plugging in, update the CPU stats first before changing
3029        // the plug state.
3030        updateCpuStatsNow();
3031        synchronized (this) {
3032            synchronized(mPidsSelfLocked) {
3033                mOnBattery = DEBUG_POWER ? true : onBattery;
3034            }
3035        }
3036    }
3037
3038    @Override
3039    public void batterySendBroadcast(Intent intent) {
3040        synchronized (this) {
3041            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3042                    AppOpsManager.OP_NONE, null, false, false,
3043                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3044        }
3045    }
3046
3047    /**
3048     * Initialize the application bind args. These are passed to each
3049     * process when the bindApplication() IPC is sent to the process. They're
3050     * lazily setup to make sure the services are running when they're asked for.
3051     */
3052    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3053        // Isolated processes won't get this optimization, so that we don't
3054        // violate the rules about which services they have access to.
3055        if (isolated) {
3056            if (mIsolatedAppBindArgs == null) {
3057                mIsolatedAppBindArgs = new HashMap<>();
3058                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3059            }
3060            return mIsolatedAppBindArgs;
3061        }
3062
3063        if (mAppBindArgs == null) {
3064            mAppBindArgs = new HashMap<>();
3065
3066            // Setup the application init args
3067            mAppBindArgs.put("package", ServiceManager.getService("package"));
3068            mAppBindArgs.put("window", ServiceManager.getService("window"));
3069            mAppBindArgs.put(Context.ALARM_SERVICE,
3070                    ServiceManager.getService(Context.ALARM_SERVICE));
3071        }
3072        return mAppBindArgs;
3073    }
3074
3075    /**
3076     * Update AMS states when an activity is resumed. This should only be called by
3077     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3078     */
3079    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3080        final TaskRecord task = r.getTask();
3081        if (task.isApplicationTask()) {
3082            if (mCurAppTimeTracker != r.appTimeTracker) {
3083                // We are switching app tracking.  Complete the current one.
3084                if (mCurAppTimeTracker != null) {
3085                    mCurAppTimeTracker.stop();
3086                    mHandler.obtainMessage(
3087                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3088                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3089                    mCurAppTimeTracker = null;
3090                }
3091                if (r.appTimeTracker != null) {
3092                    mCurAppTimeTracker = r.appTimeTracker;
3093                    startTimeTrackingFocusedActivityLocked();
3094                }
3095            } else {
3096                startTimeTrackingFocusedActivityLocked();
3097            }
3098        } else {
3099            r.appTimeTracker = null;
3100        }
3101        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3102        // TODO: Probably not, because we don't want to resume voice on switching
3103        // back to this activity
3104        if (task.voiceInteractor != null) {
3105            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3106        } else {
3107            finishRunningVoiceLocked();
3108
3109            if (mLastResumedActivity != null) {
3110                final IVoiceInteractionSession session;
3111
3112                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3113                if (lastResumedActivityTask != null
3114                        && lastResumedActivityTask.voiceSession != null) {
3115                    session = lastResumedActivityTask.voiceSession;
3116                } else {
3117                    session = mLastResumedActivity.voiceSession;
3118                }
3119
3120                if (session != null) {
3121                    // We had been in a voice interaction session, but now focused has
3122                    // move to something different.  Just finish the session, we can't
3123                    // return to it and retain the proper state and synchronization with
3124                    // the voice interaction service.
3125                    finishVoiceTask(session);
3126                }
3127            }
3128        }
3129
3130        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3131            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3132            mHandler.obtainMessage(
3133                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3134        }
3135        mLastResumedActivity = r;
3136
3137        mWindowManager.setFocusedApp(r.appToken, true);
3138
3139        applyUpdateLockStateLocked(r);
3140        applyUpdateVrModeLocked(r);
3141
3142        EventLogTags.writeAmSetResumedActivity(
3143                r == null ? -1 : r.userId,
3144                r == null ? "NULL" : r.shortComponentName,
3145                reason);
3146    }
3147
3148    @Override
3149    public void setFocusedStack(int stackId) {
3150        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3151        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3152        final long callingId = Binder.clearCallingIdentity();
3153        try {
3154            synchronized (this) {
3155                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3156                if (stack == null) {
3157                    return;
3158                }
3159                final ActivityRecord r = stack.topRunningActivityLocked();
3160                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3161                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3162                }
3163            }
3164        } finally {
3165            Binder.restoreCallingIdentity(callingId);
3166        }
3167    }
3168
3169    @Override
3170    public void setFocusedTask(int taskId) {
3171        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3172        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3173        final long callingId = Binder.clearCallingIdentity();
3174        try {
3175            synchronized (this) {
3176                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3177                if (task == null) {
3178                    return;
3179                }
3180                final ActivityRecord r = task.topRunningActivityLocked();
3181                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3182                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3183                }
3184            }
3185        } finally {
3186            Binder.restoreCallingIdentity(callingId);
3187        }
3188    }
3189
3190    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3191    @Override
3192    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3193        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3194        mTaskChangeNotificationController.registerTaskStackListener(listener);
3195    }
3196
3197    /**
3198     * Unregister a task stack listener so that it stops receiving callbacks.
3199     */
3200    @Override
3201    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3202         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3203         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3204     }
3205
3206    @Override
3207    public void notifyActivityDrawn(IBinder token) {
3208        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3209        synchronized (this) {
3210            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3211            if (r != null) {
3212                r.getStack().notifyActivityDrawnLocked(r);
3213            }
3214        }
3215    }
3216
3217    final void applyUpdateLockStateLocked(ActivityRecord r) {
3218        // Modifications to the UpdateLock state are done on our handler, outside
3219        // the activity manager's locks.  The new state is determined based on the
3220        // state *now* of the relevant activity record.  The object is passed to
3221        // the handler solely for logging detail, not to be consulted/modified.
3222        final boolean nextState = r != null && r.immersive;
3223        mHandler.sendMessage(
3224                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3225    }
3226
3227    final void applyUpdateVrModeLocked(ActivityRecord r) {
3228        mHandler.sendMessage(
3229                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3230    }
3231
3232    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3233        mHandler.sendMessage(
3234                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3235    }
3236
3237    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3238        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3239        if (vrService == null) {
3240            return;
3241        }
3242        vrService.onSleepStateChanged(isSleeping);
3243    }
3244
3245    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3246        Message msg = Message.obtain();
3247        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3248        msg.obj = r.getTask().askedCompatMode ? null : r;
3249        mUiHandler.sendMessage(msg);
3250    }
3251
3252    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3253        final Configuration globalConfig = getGlobalConfiguration();
3254        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3255                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3256            final Message msg = Message.obtain();
3257            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3258            msg.obj = r;
3259            mUiHandler.sendMessage(msg);
3260        }
3261    }
3262
3263    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3264            String what, Object obj, ProcessRecord srcApp) {
3265        app.lastActivityTime = now;
3266
3267        if (app.activities.size() > 0) {
3268            // Don't want to touch dependent processes that are hosting activities.
3269            return index;
3270        }
3271
3272        int lrui = mLruProcesses.lastIndexOf(app);
3273        if (lrui < 0) {
3274            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3275                    + what + " " + obj + " from " + srcApp);
3276            return index;
3277        }
3278
3279        if (lrui >= index) {
3280            // Don't want to cause this to move dependent processes *back* in the
3281            // list as if they were less frequently used.
3282            return index;
3283        }
3284
3285        if (lrui >= mLruProcessActivityStart) {
3286            // Don't want to touch dependent processes that are hosting activities.
3287            return index;
3288        }
3289
3290        mLruProcesses.remove(lrui);
3291        if (index > 0) {
3292            index--;
3293        }
3294        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3295                + " in LRU list: " + app);
3296        mLruProcesses.add(index, app);
3297        return index;
3298    }
3299
3300    static void killProcessGroup(int uid, int pid) {
3301        if (sKillHandler != null) {
3302            sKillHandler.sendMessage(
3303                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3304        } else {
3305            Slog.w(TAG, "Asked to kill process group before system bringup!");
3306            Process.killProcessGroup(uid, pid);
3307        }
3308    }
3309
3310    final void removeLruProcessLocked(ProcessRecord app) {
3311        int lrui = mLruProcesses.lastIndexOf(app);
3312        if (lrui >= 0) {
3313            if (!app.killed) {
3314                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3315                killProcessQuiet(app.pid);
3316                killProcessGroup(app.uid, app.pid);
3317            }
3318            if (lrui <= mLruProcessActivityStart) {
3319                mLruProcessActivityStart--;
3320            }
3321            if (lrui <= mLruProcessServiceStart) {
3322                mLruProcessServiceStart--;
3323            }
3324            mLruProcesses.remove(lrui);
3325        }
3326    }
3327
3328    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3329            ProcessRecord client) {
3330        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3331                || app.treatLikeActivity;
3332        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3333        if (!activityChange && hasActivity) {
3334            // The process has activities, so we are only allowing activity-based adjustments
3335            // to move it.  It should be kept in the front of the list with other
3336            // processes that have activities, and we don't want those to change their
3337            // order except due to activity operations.
3338            return;
3339        }
3340
3341        mLruSeq++;
3342        final long now = SystemClock.uptimeMillis();
3343        app.lastActivityTime = now;
3344
3345        // First a quick reject: if the app is already at the position we will
3346        // put it, then there is nothing to do.
3347        if (hasActivity) {
3348            final int N = mLruProcesses.size();
3349            if (N > 0 && mLruProcesses.get(N-1) == app) {
3350                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3351                return;
3352            }
3353        } else {
3354            if (mLruProcessServiceStart > 0
3355                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3356                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3357                return;
3358            }
3359        }
3360
3361        int lrui = mLruProcesses.lastIndexOf(app);
3362
3363        if (app.persistent && lrui >= 0) {
3364            // We don't care about the position of persistent processes, as long as
3365            // they are in the list.
3366            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3367            return;
3368        }
3369
3370        /* In progress: compute new position first, so we can avoid doing work
3371           if the process is not actually going to move.  Not yet working.
3372        int addIndex;
3373        int nextIndex;
3374        boolean inActivity = false, inService = false;
3375        if (hasActivity) {
3376            // Process has activities, put it at the very tipsy-top.
3377            addIndex = mLruProcesses.size();
3378            nextIndex = mLruProcessServiceStart;
3379            inActivity = true;
3380        } else if (hasService) {
3381            // Process has services, put it at the top of the service list.
3382            addIndex = mLruProcessActivityStart;
3383            nextIndex = mLruProcessServiceStart;
3384            inActivity = true;
3385            inService = true;
3386        } else  {
3387            // Process not otherwise of interest, it goes to the top of the non-service area.
3388            addIndex = mLruProcessServiceStart;
3389            if (client != null) {
3390                int clientIndex = mLruProcesses.lastIndexOf(client);
3391                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3392                        + app);
3393                if (clientIndex >= 0 && addIndex > clientIndex) {
3394                    addIndex = clientIndex;
3395                }
3396            }
3397            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3398        }
3399
3400        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3401                + mLruProcessActivityStart + "): " + app);
3402        */
3403
3404        if (lrui >= 0) {
3405            if (lrui < mLruProcessActivityStart) {
3406                mLruProcessActivityStart--;
3407            }
3408            if (lrui < mLruProcessServiceStart) {
3409                mLruProcessServiceStart--;
3410            }
3411            /*
3412            if (addIndex > lrui) {
3413                addIndex--;
3414            }
3415            if (nextIndex > lrui) {
3416                nextIndex--;
3417            }
3418            */
3419            mLruProcesses.remove(lrui);
3420        }
3421
3422        /*
3423        mLruProcesses.add(addIndex, app);
3424        if (inActivity) {
3425            mLruProcessActivityStart++;
3426        }
3427        if (inService) {
3428            mLruProcessActivityStart++;
3429        }
3430        */
3431
3432        int nextIndex;
3433        if (hasActivity) {
3434            final int N = mLruProcesses.size();
3435            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3436                // Process doesn't have activities, but has clients with
3437                // activities...  move it up, but one below the top (the top
3438                // should always have a real activity).
3439                if (DEBUG_LRU) Slog.d(TAG_LRU,
3440                        "Adding to second-top of LRU activity list: " + app);
3441                mLruProcesses.add(N - 1, app);
3442                // To keep it from spamming the LRU list (by making a bunch of clients),
3443                // we will push down any other entries owned by the app.
3444                final int uid = app.info.uid;
3445                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3446                    ProcessRecord subProc = mLruProcesses.get(i);
3447                    if (subProc.info.uid == uid) {
3448                        // We want to push this one down the list.  If the process after
3449                        // it is for the same uid, however, don't do so, because we don't
3450                        // want them internally to be re-ordered.
3451                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3452                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3453                                    "Pushing uid " + uid + " swapping at " + i + ": "
3454                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3455                            ProcessRecord tmp = mLruProcesses.get(i);
3456                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3457                            mLruProcesses.set(i - 1, tmp);
3458                            i--;
3459                        }
3460                    } else {
3461                        // A gap, we can stop here.
3462                        break;
3463                    }
3464                }
3465            } else {
3466                // Process has activities, put it at the very tipsy-top.
3467                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3468                mLruProcesses.add(app);
3469            }
3470            nextIndex = mLruProcessServiceStart;
3471        } else if (hasService) {
3472            // Process has services, put it at the top of the service list.
3473            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3474            mLruProcesses.add(mLruProcessActivityStart, app);
3475            nextIndex = mLruProcessServiceStart;
3476            mLruProcessActivityStart++;
3477        } else  {
3478            // Process not otherwise of interest, it goes to the top of the non-service area.
3479            int index = mLruProcessServiceStart;
3480            if (client != null) {
3481                // If there is a client, don't allow the process to be moved up higher
3482                // in the list than that client.
3483                int clientIndex = mLruProcesses.lastIndexOf(client);
3484                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3485                        + " when updating " + app);
3486                if (clientIndex <= lrui) {
3487                    // Don't allow the client index restriction to push it down farther in the
3488                    // list than it already is.
3489                    clientIndex = lrui;
3490                }
3491                if (clientIndex >= 0 && index > clientIndex) {
3492                    index = clientIndex;
3493                }
3494            }
3495            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3496            mLruProcesses.add(index, app);
3497            nextIndex = index-1;
3498            mLruProcessActivityStart++;
3499            mLruProcessServiceStart++;
3500        }
3501
3502        // If the app is currently using a content provider or service,
3503        // bump those processes as well.
3504        for (int j=app.connections.size()-1; j>=0; j--) {
3505            ConnectionRecord cr = app.connections.valueAt(j);
3506            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3507                    && cr.binding.service.app != null
3508                    && cr.binding.service.app.lruSeq != mLruSeq
3509                    && !cr.binding.service.app.persistent) {
3510                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3511                        "service connection", cr, app);
3512            }
3513        }
3514        for (int j=app.conProviders.size()-1; j>=0; j--) {
3515            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3516            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3517                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3518                        "provider reference", cpr, app);
3519            }
3520        }
3521    }
3522
3523    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3524        if (uid == SYSTEM_UID) {
3525            // The system gets to run in any process.  If there are multiple
3526            // processes with the same uid, just pick the first (this
3527            // should never happen).
3528            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3529            if (procs == null) return null;
3530            final int procCount = procs.size();
3531            for (int i = 0; i < procCount; i++) {
3532                final int procUid = procs.keyAt(i);
3533                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3534                    // Don't use an app process or different user process for system component.
3535                    continue;
3536                }
3537                return procs.valueAt(i);
3538            }
3539        }
3540        ProcessRecord proc = mProcessNames.get(processName, uid);
3541        if (false && proc != null && !keepIfLarge
3542                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3543                && proc.lastCachedPss >= 4000) {
3544            // Turn this condition on to cause killing to happen regularly, for testing.
3545            if (proc.baseProcessTracker != null) {
3546                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3547            }
3548            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3549        } else if (proc != null && !keepIfLarge
3550                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3551                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3552            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3553            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3554                if (proc.baseProcessTracker != null) {
3555                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3556                }
3557                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3558            }
3559        }
3560        return proc;
3561    }
3562
3563    void notifyPackageUse(String packageName, int reason) {
3564        IPackageManager pm = AppGlobals.getPackageManager();
3565        try {
3566            pm.notifyPackageUse(packageName, reason);
3567        } catch (RemoteException e) {
3568        }
3569    }
3570
3571    boolean isNextTransitionForward() {
3572        int transit = mWindowManager.getPendingAppTransition();
3573        return transit == TRANSIT_ACTIVITY_OPEN
3574                || transit == TRANSIT_TASK_OPEN
3575                || transit == TRANSIT_TASK_TO_FRONT;
3576    }
3577
3578    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3579            String processName, String abiOverride, int uid, Runnable crashHandler) {
3580        synchronized(this) {
3581            ApplicationInfo info = new ApplicationInfo();
3582            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3583            // For isolated processes, the former contains the parent's uid and the latter the
3584            // actual uid of the isolated process.
3585            // In the special case introduced by this method (which is, starting an isolated
3586            // process directly from the SystemServer without an actual parent app process) the
3587            // closest thing to a parent's uid is SYSTEM_UID.
3588            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3589            // the |isolated| logic in the ProcessRecord constructor.
3590            info.uid = SYSTEM_UID;
3591            info.processName = processName;
3592            info.className = entryPoint;
3593            info.packageName = "android";
3594            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3595            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3596                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3597                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3598                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3599                    crashHandler);
3600            return proc != null ? proc.pid : 0;
3601        }
3602    }
3603
3604    final ProcessRecord startProcessLocked(String processName,
3605            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3606            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3607            boolean isolated, boolean keepIfLarge) {
3608        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3609                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3610                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3611                null /* crashHandler */);
3612    }
3613
3614    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3615            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3616            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3617            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3618        long startTime = SystemClock.elapsedRealtime();
3619        ProcessRecord app;
3620        if (!isolated) {
3621            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3622            checkTime(startTime, "startProcess: after getProcessRecord");
3623
3624            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3625                // If we are in the background, then check to see if this process
3626                // is bad.  If so, we will just silently fail.
3627                if (mAppErrors.isBadProcessLocked(info)) {
3628                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3629                            + "/" + info.processName);
3630                    return null;
3631                }
3632            } else {
3633                // When the user is explicitly starting a process, then clear its
3634                // crash count so that we won't make it bad until they see at
3635                // least one crash dialog again, and make the process good again
3636                // if it had been bad.
3637                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3638                        + "/" + info.processName);
3639                mAppErrors.resetProcessCrashTimeLocked(info);
3640                if (mAppErrors.isBadProcessLocked(info)) {
3641                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3642                            UserHandle.getUserId(info.uid), info.uid,
3643                            info.processName);
3644                    mAppErrors.clearBadProcessLocked(info);
3645                    if (app != null) {
3646                        app.bad = false;
3647                    }
3648                }
3649            }
3650        } else {
3651            // If this is an isolated process, it can't re-use an existing process.
3652            app = null;
3653        }
3654
3655        // We don't have to do anything more if:
3656        // (1) There is an existing application record; and
3657        // (2) The caller doesn't think it is dead, OR there is no thread
3658        //     object attached to it so we know it couldn't have crashed; and
3659        // (3) There is a pid assigned to it, so it is either starting or
3660        //     already running.
3661        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3662                + " app=" + app + " knownToBeDead=" + knownToBeDead
3663                + " thread=" + (app != null ? app.thread : null)
3664                + " pid=" + (app != null ? app.pid : -1));
3665        if (app != null && app.pid > 0) {
3666            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3667                // We already have the app running, or are waiting for it to
3668                // come up (we have a pid but not yet its thread), so keep it.
3669                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3670                // If this is a new package in the process, add the package to the list
3671                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3672                checkTime(startTime, "startProcess: done, added package to proc");
3673                return app;
3674            }
3675
3676            // An application record is attached to a previous process,
3677            // clean it up now.
3678            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3679            checkTime(startTime, "startProcess: bad proc running, killing");
3680            killProcessGroup(app.uid, app.pid);
3681            handleAppDiedLocked(app, true, true);
3682            checkTime(startTime, "startProcess: done killing old proc");
3683        }
3684
3685        String hostingNameStr = hostingName != null
3686                ? hostingName.flattenToShortString() : null;
3687
3688        if (app == null) {
3689            checkTime(startTime, "startProcess: creating new process record");
3690            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3691            if (app == null) {
3692                Slog.w(TAG, "Failed making new process record for "
3693                        + processName + "/" + info.uid + " isolated=" + isolated);
3694                return null;
3695            }
3696            app.crashHandler = crashHandler;
3697            checkTime(startTime, "startProcess: done creating new process record");
3698        } else {
3699            // If this is a new package in the process, add the package to the list
3700            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3701            checkTime(startTime, "startProcess: added package to existing proc");
3702        }
3703
3704        // If the system is not ready yet, then hold off on starting this
3705        // process until it is.
3706        if (!mProcessesReady
3707                && !isAllowedWhileBooting(info)
3708                && !allowWhileBooting) {
3709            if (!mProcessesOnHold.contains(app)) {
3710                mProcessesOnHold.add(app);
3711            }
3712            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3713                    "System not ready, putting on hold: " + app);
3714            checkTime(startTime, "startProcess: returning with proc on hold");
3715            return app;
3716        }
3717
3718        checkTime(startTime, "startProcess: stepping in to startProcess");
3719        startProcessLocked(
3720                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3721        checkTime(startTime, "startProcess: done starting proc!");
3722        return (app.pid != 0) ? app : null;
3723    }
3724
3725    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3726        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3727    }
3728
3729    private final void startProcessLocked(ProcessRecord app,
3730            String hostingType, String hostingNameStr) {
3731        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3732                null /* entryPoint */, null /* entryPointArgs */);
3733    }
3734
3735    private final void startProcessLocked(ProcessRecord app, String hostingType,
3736            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3737        long startTime = SystemClock.elapsedRealtime();
3738        if (app.pid > 0 && app.pid != MY_PID) {
3739            checkTime(startTime, "startProcess: removing from pids map");
3740            synchronized (mPidsSelfLocked) {
3741                mPidsSelfLocked.remove(app.pid);
3742                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3743            }
3744            checkTime(startTime, "startProcess: done removing from pids map");
3745            app.setPid(0);
3746        }
3747
3748        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3749                "startProcessLocked removing on hold: " + app);
3750        mProcessesOnHold.remove(app);
3751
3752        checkTime(startTime, "startProcess: starting to update cpu stats");
3753        updateCpuStats();
3754        checkTime(startTime, "startProcess: done updating cpu stats");
3755
3756        try {
3757            try {
3758                final int userId = UserHandle.getUserId(app.uid);
3759                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3760            } catch (RemoteException e) {
3761                throw e.rethrowAsRuntimeException();
3762            }
3763
3764            int uid = app.uid;
3765            int[] gids = null;
3766            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3767            if (!app.isolated) {
3768                int[] permGids = null;
3769                try {
3770                    checkTime(startTime, "startProcess: getting gids from package manager");
3771                    final IPackageManager pm = AppGlobals.getPackageManager();
3772                    permGids = pm.getPackageGids(app.info.packageName,
3773                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3774                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3775                            StorageManagerInternal.class);
3776                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3777                            app.info.packageName);
3778                } catch (RemoteException e) {
3779                    throw e.rethrowAsRuntimeException();
3780                }
3781
3782                /*
3783                 * Add shared application and profile GIDs so applications can share some
3784                 * resources like shared libraries and access user-wide resources
3785                 */
3786                if (ArrayUtils.isEmpty(permGids)) {
3787                    gids = new int[3];
3788                } else {
3789                    gids = new int[permGids.length + 3];
3790                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3791                }
3792                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3793                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3794                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3795            }
3796            checkTime(startTime, "startProcess: building args");
3797            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3798                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3799                        && mTopComponent != null
3800                        && app.processName.equals(mTopComponent.getPackageName())) {
3801                    uid = 0;
3802                }
3803                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3804                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3805                    uid = 0;
3806                }
3807            }
3808            int debugFlags = 0;
3809            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3810                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3811                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3812                // Also turn on CheckJNI for debuggable apps. It's quite
3813                // awkward to turn on otherwise.
3814                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3815            }
3816            // Run the app in safe mode if its manifest requests so or the
3817            // system is booted in safe mode.
3818            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3819                mSafeMode == true) {
3820                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3821            }
3822            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3823                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3824            }
3825            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3826            if ("true".equals(genDebugInfoProperty)) {
3827                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3828            }
3829            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3830                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3831            }
3832            if ("1".equals(SystemProperties.get("debug.assert"))) {
3833                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3834            }
3835            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3836                // Enable all debug flags required by the native debugger.
3837                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3838                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3839                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3840                mNativeDebuggingApp = null;
3841            }
3842
3843            String invokeWith = null;
3844            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3845                // Debuggable apps may include a wrapper script with their library directory.
3846                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3847                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3848                try {
3849                    if (new File(wrapperFileName).exists()) {
3850                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3851                    }
3852                } finally {
3853                    StrictMode.setThreadPolicy(oldPolicy);
3854                }
3855            }
3856
3857            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3858            if (requiredAbi == null) {
3859                requiredAbi = Build.SUPPORTED_ABIS[0];
3860            }
3861
3862            String instructionSet = null;
3863            if (app.info.primaryCpuAbi != null) {
3864                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3865            }
3866
3867            app.gids = gids;
3868            app.requiredAbi = requiredAbi;
3869            app.instructionSet = instructionSet;
3870
3871            // the per-user SELinux context must be set
3872            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3873                Slog.wtf(TAG, "SELinux tag not defined",
3874                        new IllegalStateException("SELinux tag not defined for "
3875                        + app.info.packageName + " (uid " + app.uid + ")"));
3876            }
3877            final String seInfo = app.info.seInfo
3878                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3879            // Start the process.  It will either succeed and return a result containing
3880            // the PID of the new process, or else throw a RuntimeException.
3881            boolean isActivityProcess = (entryPoint == null);
3882            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3883            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3884                    app.processName);
3885            checkTime(startTime, "startProcess: asking zygote to start proc");
3886            ProcessStartResult startResult;
3887            if (hostingType.equals("webview_service")) {
3888                startResult = startWebView(entryPoint,
3889                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3890                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3891                        app.info.dataDir, null, entryPointArgs);
3892            } else {
3893                startResult = Process.start(entryPoint,
3894                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3895                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3896                        app.info.dataDir, invokeWith, entryPointArgs);
3897            }
3898            checkTime(startTime, "startProcess: returned from zygote!");
3899            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3900
3901            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3902            checkTime(startTime, "startProcess: done updating battery stats");
3903
3904            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3905                    UserHandle.getUserId(uid), startResult.pid, uid,
3906                    app.processName, hostingType,
3907                    hostingNameStr != null ? hostingNameStr : "");
3908
3909            try {
3910                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3911                        seInfo, app.info.sourceDir, startResult.pid);
3912            } catch (RemoteException ex) {
3913                // Ignore
3914            }
3915
3916            if (app.persistent) {
3917                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3918            }
3919
3920            checkTime(startTime, "startProcess: building log message");
3921            StringBuilder buf = mStringBuilder;
3922            buf.setLength(0);
3923            buf.append("Start proc ");
3924            buf.append(startResult.pid);
3925            buf.append(':');
3926            buf.append(app.processName);
3927            buf.append('/');
3928            UserHandle.formatUid(buf, uid);
3929            if (!isActivityProcess) {
3930                buf.append(" [");
3931                buf.append(entryPoint);
3932                buf.append("]");
3933            }
3934            buf.append(" for ");
3935            buf.append(hostingType);
3936            if (hostingNameStr != null) {
3937                buf.append(" ");
3938                buf.append(hostingNameStr);
3939            }
3940            Slog.i(TAG, buf.toString());
3941            app.setPid(startResult.pid);
3942            app.usingWrapper = startResult.usingWrapper;
3943            app.removed = false;
3944            app.killed = false;
3945            app.killedByAm = false;
3946            checkTime(startTime, "startProcess: starting to update pids map");
3947            ProcessRecord oldApp;
3948            synchronized (mPidsSelfLocked) {
3949                oldApp = mPidsSelfLocked.get(startResult.pid);
3950            }
3951            // If there is already an app occupying that pid that hasn't been cleaned up
3952            if (oldApp != null && !app.isolated) {
3953                // Clean up anything relating to this pid first
3954                Slog.w(TAG, "Reusing pid " + startResult.pid
3955                        + " while app is still mapped to it");
3956                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3957                        true /*replacingPid*/);
3958            }
3959            synchronized (mPidsSelfLocked) {
3960                this.mPidsSelfLocked.put(startResult.pid, app);
3961                if (isActivityProcess) {
3962                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3963                    msg.obj = app;
3964                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3965                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3966                }
3967            }
3968            checkTime(startTime, "startProcess: done updating pids map");
3969        } catch (RuntimeException e) {
3970            Slog.e(TAG, "Failure starting process " + app.processName, e);
3971
3972            // Something went very wrong while trying to start this process; one
3973            // common case is when the package is frozen due to an active
3974            // upgrade. To recover, clean up any active bookkeeping related to
3975            // starting this process. (We already invoked this method once when
3976            // the package was initially frozen through KILL_APPLICATION_MSG, so
3977            // it doesn't hurt to use it again.)
3978            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3979                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3980        }
3981    }
3982
3983    void updateUsageStats(ActivityRecord component, boolean resumed) {
3984        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3985                "updateUsageStats: comp=" + component + "res=" + resumed);
3986        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3987        if (resumed) {
3988            if (mUsageStatsService != null) {
3989                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3990                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3991            }
3992            synchronized (stats) {
3993                stats.noteActivityResumedLocked(component.app.uid);
3994            }
3995        } else {
3996            if (mUsageStatsService != null) {
3997                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3998                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3999            }
4000            synchronized (stats) {
4001                stats.noteActivityPausedLocked(component.app.uid);
4002            }
4003        }
4004    }
4005
4006    Intent getHomeIntent() {
4007        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4008        intent.setComponent(mTopComponent);
4009        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4010        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4011            intent.addCategory(Intent.CATEGORY_HOME);
4012        }
4013        return intent;
4014    }
4015
4016    boolean startHomeActivityLocked(int userId, String reason) {
4017        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4018                && mTopAction == null) {
4019            // We are running in factory test mode, but unable to find
4020            // the factory test app, so just sit around displaying the
4021            // error message and don't try to start anything.
4022            return false;
4023        }
4024        Intent intent = getHomeIntent();
4025        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4026        if (aInfo != null) {
4027            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4028            // Don't do this if the home app is currently being
4029            // instrumented.
4030            aInfo = new ActivityInfo(aInfo);
4031            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4032            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4033                    aInfo.applicationInfo.uid, true);
4034            if (app == null || app.instr == null) {
4035                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4036                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
4037            }
4038        } else {
4039            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4040        }
4041
4042        return true;
4043    }
4044
4045    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4046        ActivityInfo ai = null;
4047        ComponentName comp = intent.getComponent();
4048        try {
4049            if (comp != null) {
4050                // Factory test.
4051                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4052            } else {
4053                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4054                        intent,
4055                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4056                        flags, userId);
4057
4058                if (info != null) {
4059                    ai = info.activityInfo;
4060                }
4061            }
4062        } catch (RemoteException e) {
4063            // ignore
4064        }
4065
4066        return ai;
4067    }
4068
4069    /**
4070     * Starts the "new version setup screen" if appropriate.
4071     */
4072    void startSetupActivityLocked() {
4073        // Only do this once per boot.
4074        if (mCheckedForSetup) {
4075            return;
4076        }
4077
4078        // We will show this screen if the current one is a different
4079        // version than the last one shown, and we are not running in
4080        // low-level factory test mode.
4081        final ContentResolver resolver = mContext.getContentResolver();
4082        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4083                Settings.Global.getInt(resolver,
4084                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4085            mCheckedForSetup = true;
4086
4087            // See if we should be showing the platform update setup UI.
4088            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4089            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4090                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4091            if (!ris.isEmpty()) {
4092                final ResolveInfo ri = ris.get(0);
4093                String vers = ri.activityInfo.metaData != null
4094                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4095                        : null;
4096                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4097                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4098                            Intent.METADATA_SETUP_VERSION);
4099                }
4100                String lastVers = Settings.Secure.getString(
4101                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4102                if (vers != null && !vers.equals(lastVers)) {
4103                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4104                    intent.setComponent(new ComponentName(
4105                            ri.activityInfo.packageName, ri.activityInfo.name));
4106                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4107                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4108                            null, 0, 0, 0, null, false, false, null, null, null);
4109                }
4110            }
4111        }
4112    }
4113
4114    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4115        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4116    }
4117
4118    void enforceNotIsolatedCaller(String caller) {
4119        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4120            throw new SecurityException("Isolated process not allowed to call " + caller);
4121        }
4122    }
4123
4124    void enforceShellRestriction(String restriction, int userHandle) {
4125        if (Binder.getCallingUid() == SHELL_UID) {
4126            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4127                throw new SecurityException("Shell does not have permission to access user "
4128                        + userHandle);
4129            }
4130        }
4131    }
4132
4133    @Override
4134    public int getFrontActivityScreenCompatMode() {
4135        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4136        synchronized (this) {
4137            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4138        }
4139    }
4140
4141    @Override
4142    public void setFrontActivityScreenCompatMode(int mode) {
4143        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4144                "setFrontActivityScreenCompatMode");
4145        synchronized (this) {
4146            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4147        }
4148    }
4149
4150    @Override
4151    public int getPackageScreenCompatMode(String packageName) {
4152        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4153        synchronized (this) {
4154            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4155        }
4156    }
4157
4158    @Override
4159    public void setPackageScreenCompatMode(String packageName, int mode) {
4160        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4161                "setPackageScreenCompatMode");
4162        synchronized (this) {
4163            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4164        }
4165    }
4166
4167    @Override
4168    public boolean getPackageAskScreenCompat(String packageName) {
4169        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4170        synchronized (this) {
4171            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4172        }
4173    }
4174
4175    @Override
4176    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4177        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4178                "setPackageAskScreenCompat");
4179        synchronized (this) {
4180            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4181        }
4182    }
4183
4184    private boolean hasUsageStatsPermission(String callingPackage) {
4185        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4186                Binder.getCallingUid(), callingPackage);
4187        if (mode == AppOpsManager.MODE_DEFAULT) {
4188            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4189                    == PackageManager.PERMISSION_GRANTED;
4190        }
4191        return mode == AppOpsManager.MODE_ALLOWED;
4192    }
4193
4194    @Override
4195    public int getPackageProcessState(String packageName, String callingPackage) {
4196        if (!hasUsageStatsPermission(callingPackage)) {
4197            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4198                    "getPackageProcessState");
4199        }
4200
4201        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4202        synchronized (this) {
4203            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4204                final ProcessRecord proc = mLruProcesses.get(i);
4205                if (procState > proc.setProcState) {
4206                    if (proc.pkgList.containsKey(packageName) ||
4207                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4208                        procState = proc.setProcState;
4209                    }
4210                }
4211            }
4212        }
4213        return procState;
4214    }
4215
4216    @Override
4217    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4218            throws RemoteException {
4219        synchronized (this) {
4220            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4221            if (app == null) {
4222                throw new IllegalArgumentException("Unknown process: " + process);
4223            }
4224            if (app.thread == null) {
4225                throw new IllegalArgumentException("Process has no app thread");
4226            }
4227            if (app.trimMemoryLevel >= level) {
4228                throw new IllegalArgumentException(
4229                        "Unable to set a higher trim level than current level");
4230            }
4231            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4232                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4233                throw new IllegalArgumentException("Unable to set a background trim level "
4234                    + "on a foreground process");
4235            }
4236            app.thread.scheduleTrimMemory(level);
4237            app.trimMemoryLevel = level;
4238            return true;
4239        }
4240    }
4241
4242    private void dispatchProcessesChanged() {
4243        int N;
4244        synchronized (this) {
4245            N = mPendingProcessChanges.size();
4246            if (mActiveProcessChanges.length < N) {
4247                mActiveProcessChanges = new ProcessChangeItem[N];
4248            }
4249            mPendingProcessChanges.toArray(mActiveProcessChanges);
4250            mPendingProcessChanges.clear();
4251            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4252                    "*** Delivering " + N + " process changes");
4253        }
4254
4255        int i = mProcessObservers.beginBroadcast();
4256        while (i > 0) {
4257            i--;
4258            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4259            if (observer != null) {
4260                try {
4261                    for (int j=0; j<N; j++) {
4262                        ProcessChangeItem item = mActiveProcessChanges[j];
4263                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4264                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4265                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4266                                    + item.uid + ": " + item.foregroundActivities);
4267                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4268                                    item.foregroundActivities);
4269                        }
4270                    }
4271                } catch (RemoteException e) {
4272                }
4273            }
4274        }
4275        mProcessObservers.finishBroadcast();
4276
4277        synchronized (this) {
4278            for (int j=0; j<N; j++) {
4279                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4280            }
4281        }
4282    }
4283
4284    private void dispatchProcessDied(int pid, int uid) {
4285        int i = mProcessObservers.beginBroadcast();
4286        while (i > 0) {
4287            i--;
4288            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4289            if (observer != null) {
4290                try {
4291                    observer.onProcessDied(pid, uid);
4292                } catch (RemoteException e) {
4293                }
4294            }
4295        }
4296        mProcessObservers.finishBroadcast();
4297    }
4298
4299    @VisibleForTesting
4300    void dispatchUidsChanged() {
4301        int N;
4302        synchronized (this) {
4303            N = mPendingUidChanges.size();
4304            if (mActiveUidChanges.length < N) {
4305                mActiveUidChanges = new UidRecord.ChangeItem[N];
4306            }
4307            for (int i=0; i<N; i++) {
4308                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4309                mActiveUidChanges[i] = change;
4310                if (change.uidRecord != null) {
4311                    change.uidRecord.pendingChange = null;
4312                    change.uidRecord = null;
4313                }
4314            }
4315            mPendingUidChanges.clear();
4316            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4317                    "*** Delivering " + N + " uid changes");
4318        }
4319
4320        int i = mUidObservers.beginBroadcast();
4321        while (i > 0) {
4322            i--;
4323            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4324                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4325        }
4326        mUidObservers.finishBroadcast();
4327
4328        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4329            for (int j = 0; j < N; ++j) {
4330                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4331                if (item.change == UidRecord.CHANGE_GONE
4332                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4333                    mValidateUids.remove(item.uid);
4334                } else {
4335                    UidRecord validateUid = mValidateUids.get(item.uid);
4336                    if (validateUid == null) {
4337                        validateUid = new UidRecord(item.uid);
4338                        mValidateUids.put(item.uid, validateUid);
4339                    }
4340                    if (item.change == UidRecord.CHANGE_IDLE) {
4341                        validateUid.idle = true;
4342                    } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4343                        validateUid.idle = false;
4344                    }
4345                    validateUid.curProcState = validateUid.setProcState = item.processState;
4346                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4347                }
4348            }
4349        }
4350
4351        synchronized (this) {
4352            for (int j = 0; j < N; j++) {
4353                mAvailUidChanges.add(mActiveUidChanges[j]);
4354            }
4355        }
4356    }
4357
4358    private void dispatchUidsChangedForObserver(IUidObserver observer,
4359            UidObserverRegistration reg, int changesSize) {
4360        if (observer == null) {
4361            return;
4362        }
4363        try {
4364            for (int j = 0; j < changesSize; j++) {
4365                UidRecord.ChangeItem item = mActiveUidChanges[j];
4366                final int change = item.change;
4367                if (change == UidRecord.CHANGE_IDLE
4368                        || change == UidRecord.CHANGE_GONE_IDLE) {
4369                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4370                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4371                                "UID idle uid=" + item.uid);
4372                        observer.onUidIdle(item.uid, item.ephemeral);
4373                    }
4374                } else if (change == UidRecord.CHANGE_ACTIVE) {
4375                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4376                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4377                                "UID active uid=" + item.uid);
4378                        observer.onUidActive(item.uid);
4379                    }
4380                }
4381                if (change == UidRecord.CHANGE_GONE
4382                        || change == UidRecord.CHANGE_GONE_IDLE) {
4383                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4384                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4385                                "UID gone uid=" + item.uid);
4386                        observer.onUidGone(item.uid, item.ephemeral);
4387                    }
4388                    if (reg.lastProcStates != null) {
4389                        reg.lastProcStates.delete(item.uid);
4390                    }
4391                } else {
4392                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4393                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4394                                "UID CHANGED uid=" + item.uid
4395                                        + ": " + item.processState);
4396                        boolean doReport = true;
4397                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4398                            final int lastState = reg.lastProcStates.get(item.uid,
4399                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4400                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4401                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4402                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4403                                doReport = lastAboveCut != newAboveCut;
4404                            } else {
4405                                doReport = item.processState
4406                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4407                            }
4408                        }
4409                        if (doReport) {
4410                            if (reg.lastProcStates != null) {
4411                                reg.lastProcStates.put(item.uid, item.processState);
4412                            }
4413                            observer.onUidStateChanged(item.uid, item.processState,
4414                                    item.procStateSeq);
4415                        }
4416                    }
4417                }
4418            }
4419        } catch (RemoteException e) {
4420        }
4421    }
4422
4423    @Override
4424    public final int startActivity(IApplicationThread caller, String callingPackage,
4425            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4426            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4427        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4428                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4429                UserHandle.getCallingUserId());
4430    }
4431
4432    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4433        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4434        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4435                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4436                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4437
4438        // TODO: Switch to user app stacks here.
4439        String mimeType = intent.getType();
4440        final Uri data = intent.getData();
4441        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4442            mimeType = getProviderMimeType(data, userId);
4443        }
4444        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4445
4446        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4447        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4448                null, 0, 0, null, null, null, null, false, userId, container, null);
4449    }
4450
4451    @Override
4452    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4453            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4454            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4455        enforceNotIsolatedCaller("startActivity");
4456        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4457                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4458        // TODO: Switch to user app stacks here.
4459        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4460                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4461                profilerInfo, null, null, bOptions, false, userId, null, null);
4462    }
4463
4464    @Override
4465    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4466            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4467            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4468            int userId) {
4469
4470        // This is very dangerous -- it allows you to perform a start activity (including
4471        // permission grants) as any app that may launch one of your own activities.  So
4472        // we will only allow this to be done from activities that are part of the core framework,
4473        // and then only when they are running as the system.
4474        final ActivityRecord sourceRecord;
4475        final int targetUid;
4476        final String targetPackage;
4477        synchronized (this) {
4478            if (resultTo == null) {
4479                throw new SecurityException("Must be called from an activity");
4480            }
4481            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4482            if (sourceRecord == null) {
4483                throw new SecurityException("Called with bad activity token: " + resultTo);
4484            }
4485            if (!sourceRecord.info.packageName.equals("android")) {
4486                throw new SecurityException(
4487                        "Must be called from an activity that is declared in the android package");
4488            }
4489            if (sourceRecord.app == null) {
4490                throw new SecurityException("Called without a process attached to activity");
4491            }
4492            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4493                // This is still okay, as long as this activity is running under the
4494                // uid of the original calling activity.
4495                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4496                    throw new SecurityException(
4497                            "Calling activity in uid " + sourceRecord.app.uid
4498                                    + " must be system uid or original calling uid "
4499                                    + sourceRecord.launchedFromUid);
4500                }
4501            }
4502            if (ignoreTargetSecurity) {
4503                if (intent.getComponent() == null) {
4504                    throw new SecurityException(
4505                            "Component must be specified with ignoreTargetSecurity");
4506                }
4507                if (intent.getSelector() != null) {
4508                    throw new SecurityException(
4509                            "Selector not allowed with ignoreTargetSecurity");
4510                }
4511            }
4512            targetUid = sourceRecord.launchedFromUid;
4513            targetPackage = sourceRecord.launchedFromPackage;
4514        }
4515
4516        if (userId == UserHandle.USER_NULL) {
4517            userId = UserHandle.getUserId(sourceRecord.app.uid);
4518        }
4519
4520        // TODO: Switch to user app stacks here.
4521        try {
4522            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4523                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4524                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4525            return ret;
4526        } catch (SecurityException e) {
4527            // XXX need to figure out how to propagate to original app.
4528            // A SecurityException here is generally actually a fault of the original
4529            // calling activity (such as a fairly granting permissions), so propagate it
4530            // back to them.
4531            /*
4532            StringBuilder msg = new StringBuilder();
4533            msg.append("While launching");
4534            msg.append(intent.toString());
4535            msg.append(": ");
4536            msg.append(e.getMessage());
4537            */
4538            throw e;
4539        }
4540    }
4541
4542    @Override
4543    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4544            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4545            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4546        enforceNotIsolatedCaller("startActivityAndWait");
4547        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4548                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4549        WaitResult res = new WaitResult();
4550        // TODO: Switch to user app stacks here.
4551        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4552                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4553                bOptions, false, userId, null, null);
4554        return res;
4555    }
4556
4557    @Override
4558    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4559            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4560            int startFlags, Configuration config, Bundle bOptions, int userId) {
4561        enforceNotIsolatedCaller("startActivityWithConfig");
4562        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4563                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4564        // TODO: Switch to user app stacks here.
4565        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4566                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4567                null, null, config, bOptions, false, userId, null, null);
4568        return ret;
4569    }
4570
4571    @Override
4572    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4573            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4574            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4575            throws TransactionTooLargeException {
4576        enforceNotIsolatedCaller("startActivityIntentSender");
4577        // Refuse possible leaked file descriptors
4578        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4579            throw new IllegalArgumentException("File descriptors passed in Intent");
4580        }
4581
4582        IIntentSender sender = intent.getTarget();
4583        if (!(sender instanceof PendingIntentRecord)) {
4584            throw new IllegalArgumentException("Bad PendingIntent object");
4585        }
4586
4587        PendingIntentRecord pir = (PendingIntentRecord)sender;
4588
4589        synchronized (this) {
4590            // If this is coming from the currently resumed activity, it is
4591            // effectively saying that app switches are allowed at this point.
4592            final ActivityStack stack = getFocusedStack();
4593            if (stack.mResumedActivity != null &&
4594                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4595                mAppSwitchesAllowedTime = 0;
4596            }
4597        }
4598        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4599                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4600        return ret;
4601    }
4602
4603    @Override
4604    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4605            Intent intent, String resolvedType, IVoiceInteractionSession session,
4606            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4607            Bundle bOptions, int userId) {
4608        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4609                != PackageManager.PERMISSION_GRANTED) {
4610            String msg = "Permission Denial: startVoiceActivity() from pid="
4611                    + Binder.getCallingPid()
4612                    + ", uid=" + Binder.getCallingUid()
4613                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4614            Slog.w(TAG, msg);
4615            throw new SecurityException(msg);
4616        }
4617        if (session == null || interactor == null) {
4618            throw new NullPointerException("null session or interactor");
4619        }
4620        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4621                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4622        // TODO: Switch to user app stacks here.
4623        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4624                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4625                null, bOptions, false, userId, null, null);
4626    }
4627
4628    @Override
4629    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4630            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4631        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4632                != PackageManager.PERMISSION_GRANTED) {
4633            final String msg = "Permission Denial: startAssistantActivity() from pid="
4634                    + Binder.getCallingPid()
4635                    + ", uid=" + Binder.getCallingUid()
4636                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4637            Slog.w(TAG, msg);
4638            throw new SecurityException(msg);
4639        }
4640        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4641                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4642        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4643                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4644                userId, null, null);
4645    }
4646
4647    @Override
4648    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4649            throws RemoteException {
4650        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4651        synchronized (this) {
4652            ActivityRecord activity = getFocusedStack().topActivity();
4653            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4654                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4655            }
4656            if (mRunningVoice != null || activity.getTask().voiceSession != null
4657                    || activity.voiceSession != null) {
4658                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4659                return;
4660            }
4661            if (activity.pendingVoiceInteractionStart) {
4662                Slog.w(TAG, "Pending start of voice interaction already.");
4663                return;
4664            }
4665            activity.pendingVoiceInteractionStart = true;
4666        }
4667        LocalServices.getService(VoiceInteractionManagerInternal.class)
4668                .startLocalVoiceInteraction(callingActivity, options);
4669    }
4670
4671    @Override
4672    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4673        LocalServices.getService(VoiceInteractionManagerInternal.class)
4674                .stopLocalVoiceInteraction(callingActivity);
4675    }
4676
4677    @Override
4678    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4679        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4680                .supportsLocalVoiceInteraction();
4681    }
4682
4683    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4684            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4685        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4686        if (activityToCallback == null) return;
4687        activityToCallback.setVoiceSessionLocked(voiceSession);
4688
4689        // Inform the activity
4690        try {
4691            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4692                    voiceInteractor);
4693            long token = Binder.clearCallingIdentity();
4694            try {
4695                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4696            } finally {
4697                Binder.restoreCallingIdentity(token);
4698            }
4699            // TODO: VI Should we cache the activity so that it's easier to find later
4700            // rather than scan through all the stacks and activities?
4701        } catch (RemoteException re) {
4702            activityToCallback.clearVoiceSessionLocked();
4703            // TODO: VI Should this terminate the voice session?
4704        }
4705    }
4706
4707    @Override
4708    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4709        synchronized (this) {
4710            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4711                if (keepAwake) {
4712                    mVoiceWakeLock.acquire();
4713                } else {
4714                    mVoiceWakeLock.release();
4715                }
4716            }
4717        }
4718    }
4719
4720    @Override
4721    public boolean startNextMatchingActivity(IBinder callingActivity,
4722            Intent intent, Bundle bOptions) {
4723        // Refuse possible leaked file descriptors
4724        if (intent != null && intent.hasFileDescriptors() == true) {
4725            throw new IllegalArgumentException("File descriptors passed in Intent");
4726        }
4727        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4728
4729        synchronized (this) {
4730            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4731            if (r == null) {
4732                ActivityOptions.abort(options);
4733                return false;
4734            }
4735            if (r.app == null || r.app.thread == null) {
4736                // The caller is not running...  d'oh!
4737                ActivityOptions.abort(options);
4738                return false;
4739            }
4740            intent = new Intent(intent);
4741            // The caller is not allowed to change the data.
4742            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4743            // And we are resetting to find the next component...
4744            intent.setComponent(null);
4745
4746            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4747
4748            ActivityInfo aInfo = null;
4749            try {
4750                List<ResolveInfo> resolves =
4751                    AppGlobals.getPackageManager().queryIntentActivities(
4752                            intent, r.resolvedType,
4753                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4754                            UserHandle.getCallingUserId()).getList();
4755
4756                // Look for the original activity in the list...
4757                final int N = resolves != null ? resolves.size() : 0;
4758                for (int i=0; i<N; i++) {
4759                    ResolveInfo rInfo = resolves.get(i);
4760                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4761                            && rInfo.activityInfo.name.equals(r.info.name)) {
4762                        // We found the current one...  the next matching is
4763                        // after it.
4764                        i++;
4765                        if (i<N) {
4766                            aInfo = resolves.get(i).activityInfo;
4767                        }
4768                        if (debug) {
4769                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4770                                    + "/" + r.info.name);
4771                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4772                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4773                        }
4774                        break;
4775                    }
4776                }
4777            } catch (RemoteException e) {
4778            }
4779
4780            if (aInfo == null) {
4781                // Nobody who is next!
4782                ActivityOptions.abort(options);
4783                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4784                return false;
4785            }
4786
4787            intent.setComponent(new ComponentName(
4788                    aInfo.applicationInfo.packageName, aInfo.name));
4789            intent.setFlags(intent.getFlags()&~(
4790                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4791                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4792                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4793                    Intent.FLAG_ACTIVITY_NEW_TASK));
4794
4795            // Okay now we need to start the new activity, replacing the
4796            // currently running activity.  This is a little tricky because
4797            // we want to start the new one as if the current one is finished,
4798            // but not finish the current one first so that there is no flicker.
4799            // And thus...
4800            final boolean wasFinishing = r.finishing;
4801            r.finishing = true;
4802
4803            // Propagate reply information over to the new activity.
4804            final ActivityRecord resultTo = r.resultTo;
4805            final String resultWho = r.resultWho;
4806            final int requestCode = r.requestCode;
4807            r.resultTo = null;
4808            if (resultTo != null) {
4809                resultTo.removeResultsLocked(r, resultWho, requestCode);
4810            }
4811
4812            final long origId = Binder.clearCallingIdentity();
4813            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4814                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4815                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4816                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4817                    false, false, null, null, null);
4818            Binder.restoreCallingIdentity(origId);
4819
4820            r.finishing = wasFinishing;
4821            if (res != ActivityManager.START_SUCCESS) {
4822                return false;
4823            }
4824            return true;
4825        }
4826    }
4827
4828    @Override
4829    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4830        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4831            String msg = "Permission Denial: startActivityFromRecents called without " +
4832                    START_TASKS_FROM_RECENTS;
4833            Slog.w(TAG, msg);
4834            throw new SecurityException(msg);
4835        }
4836        final long origId = Binder.clearCallingIdentity();
4837        try {
4838            synchronized (this) {
4839                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4840            }
4841        } finally {
4842            Binder.restoreCallingIdentity(origId);
4843        }
4844    }
4845
4846    final int startActivityInPackage(int uid, String callingPackage,
4847            Intent intent, String resolvedType, IBinder resultTo,
4848            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4849            IActivityContainer container, TaskRecord inTask) {
4850
4851        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4852                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4853
4854        // TODO: Switch to user app stacks here.
4855        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4856                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4857                null, null, null, bOptions, false, userId, container, inTask);
4858        return ret;
4859    }
4860
4861    @Override
4862    public final int startActivities(IApplicationThread caller, String callingPackage,
4863            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4864            int userId) {
4865        enforceNotIsolatedCaller("startActivities");
4866        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4867                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4868        // TODO: Switch to user app stacks here.
4869        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4870                resolvedTypes, resultTo, bOptions, userId);
4871        return ret;
4872    }
4873
4874    final int startActivitiesInPackage(int uid, String callingPackage,
4875            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4876            Bundle bOptions, int userId) {
4877
4878        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4879                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4880        // TODO: Switch to user app stacks here.
4881        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4882                resultTo, bOptions, userId);
4883        return ret;
4884    }
4885
4886    @Override
4887    public void reportActivityFullyDrawn(IBinder token) {
4888        synchronized (this) {
4889            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4890            if (r == null) {
4891                return;
4892            }
4893            r.reportFullyDrawnLocked();
4894        }
4895    }
4896
4897    @Override
4898    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4899        synchronized (this) {
4900            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4901            if (r == null) {
4902                return;
4903            }
4904            final long origId = Binder.clearCallingIdentity();
4905            try {
4906                r.setRequestedOrientation(requestedOrientation);
4907            } finally {
4908                Binder.restoreCallingIdentity(origId);
4909            }
4910        }
4911    }
4912
4913    @Override
4914    public int getRequestedOrientation(IBinder token) {
4915        synchronized (this) {
4916            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4917            if (r == null) {
4918                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4919            }
4920            return r.getRequestedOrientation();
4921        }
4922    }
4923
4924    @Override
4925    public final void requestActivityRelaunch(IBinder token) {
4926        synchronized(this) {
4927            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4928            if (r == null) {
4929                return;
4930            }
4931            final long origId = Binder.clearCallingIdentity();
4932            try {
4933                r.forceNewConfig = true;
4934                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4935                        true /* preserveWindow */);
4936            } finally {
4937                Binder.restoreCallingIdentity(origId);
4938            }
4939        }
4940    }
4941
4942    /**
4943     * This is the internal entry point for handling Activity.finish().
4944     *
4945     * @param token The Binder token referencing the Activity we want to finish.
4946     * @param resultCode Result code, if any, from this Activity.
4947     * @param resultData Result data (Intent), if any, from this Activity.
4948     * @param finishTask Whether to finish the task associated with this Activity.
4949     *
4950     * @return Returns true if the activity successfully finished, or false if it is still running.
4951     */
4952    @Override
4953    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4954            int finishTask) {
4955        // Refuse possible leaked file descriptors
4956        if (resultData != null && resultData.hasFileDescriptors() == true) {
4957            throw new IllegalArgumentException("File descriptors passed in Intent");
4958        }
4959
4960        synchronized(this) {
4961            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4962            if (r == null) {
4963                return true;
4964            }
4965            // Keep track of the root activity of the task before we finish it
4966            TaskRecord tr = r.getTask();
4967            ActivityRecord rootR = tr.getRootActivity();
4968            if (rootR == null) {
4969                Slog.w(TAG, "Finishing task with all activities already finished");
4970            }
4971            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4972            // finish.
4973            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4974                    mStackSupervisor.isLastLockedTask(tr)) {
4975                Slog.i(TAG, "Not finishing task in lock task mode");
4976                mStackSupervisor.showLockTaskToast();
4977                return false;
4978            }
4979            if (mController != null) {
4980                // Find the first activity that is not finishing.
4981                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
4982                if (next != null) {
4983                    // ask watcher if this is allowed
4984                    boolean resumeOK = true;
4985                    try {
4986                        resumeOK = mController.activityResuming(next.packageName);
4987                    } catch (RemoteException e) {
4988                        mController = null;
4989                        Watchdog.getInstance().setActivityController(null);
4990                    }
4991
4992                    if (!resumeOK) {
4993                        Slog.i(TAG, "Not finishing activity because controller resumed");
4994                        return false;
4995                    }
4996                }
4997            }
4998            final long origId = Binder.clearCallingIdentity();
4999            try {
5000                boolean res;
5001                final boolean finishWithRootActivity =
5002                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5003                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5004                        || (finishWithRootActivity && r == rootR)) {
5005                    // If requested, remove the task that is associated to this activity only if it
5006                    // was the root activity in the task. The result code and data is ignored
5007                    // because we don't support returning them across task boundaries. Also, to
5008                    // keep backwards compatibility we remove the task from recents when finishing
5009                    // task with root activity.
5010                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5011                    if (!res) {
5012                        Slog.i(TAG, "Removing task failed to finish activity");
5013                    }
5014                } else {
5015                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5016                            resultData, "app-request", true);
5017                    if (!res) {
5018                        Slog.i(TAG, "Failed to finish by app-request");
5019                    }
5020                }
5021                return res;
5022            } finally {
5023                Binder.restoreCallingIdentity(origId);
5024            }
5025        }
5026    }
5027
5028    @Override
5029    public final void finishHeavyWeightApp() {
5030        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5031                != PackageManager.PERMISSION_GRANTED) {
5032            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5033                    + Binder.getCallingPid()
5034                    + ", uid=" + Binder.getCallingUid()
5035                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5036            Slog.w(TAG, msg);
5037            throw new SecurityException(msg);
5038        }
5039
5040        synchronized(this) {
5041            if (mHeavyWeightProcess == null) {
5042                return;
5043            }
5044
5045            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5046            for (int i = 0; i < activities.size(); i++) {
5047                ActivityRecord r = activities.get(i);
5048                if (!r.finishing && r.isInStackLocked()) {
5049                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5050                            null, "finish-heavy", true);
5051                }
5052            }
5053
5054            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5055                    mHeavyWeightProcess.userId, 0));
5056            mHeavyWeightProcess = null;
5057        }
5058    }
5059
5060    @Override
5061    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5062            String message) {
5063        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5064                != PackageManager.PERMISSION_GRANTED) {
5065            String msg = "Permission Denial: crashApplication() from pid="
5066                    + Binder.getCallingPid()
5067                    + ", uid=" + Binder.getCallingUid()
5068                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5069            Slog.w(TAG, msg);
5070            throw new SecurityException(msg);
5071        }
5072
5073        synchronized(this) {
5074            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5075        }
5076    }
5077
5078    @Override
5079    public final void finishSubActivity(IBinder token, String resultWho,
5080            int requestCode) {
5081        synchronized(this) {
5082            final long origId = Binder.clearCallingIdentity();
5083            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5084            if (r != null) {
5085                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5086            }
5087            Binder.restoreCallingIdentity(origId);
5088        }
5089    }
5090
5091    @Override
5092    public boolean finishActivityAffinity(IBinder token) {
5093        synchronized(this) {
5094            final long origId = Binder.clearCallingIdentity();
5095            try {
5096                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5097                if (r == null) {
5098                    return false;
5099                }
5100
5101                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5102                // can finish.
5103                final TaskRecord task = r.getTask();
5104                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5105                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5106                    mStackSupervisor.showLockTaskToast();
5107                    return false;
5108                }
5109                return task.getStack().finishActivityAffinityLocked(r);
5110            } finally {
5111                Binder.restoreCallingIdentity(origId);
5112            }
5113        }
5114    }
5115
5116    @Override
5117    public void finishVoiceTask(IVoiceInteractionSession session) {
5118        synchronized (this) {
5119            final long origId = Binder.clearCallingIdentity();
5120            try {
5121                // TODO: VI Consider treating local voice interactions and voice tasks
5122                // differently here
5123                mStackSupervisor.finishVoiceTask(session);
5124            } finally {
5125                Binder.restoreCallingIdentity(origId);
5126            }
5127        }
5128
5129    }
5130
5131    @Override
5132    public boolean releaseActivityInstance(IBinder token) {
5133        synchronized(this) {
5134            final long origId = Binder.clearCallingIdentity();
5135            try {
5136                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5137                if (r == null) {
5138                    return false;
5139                }
5140                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5141            } finally {
5142                Binder.restoreCallingIdentity(origId);
5143            }
5144        }
5145    }
5146
5147    @Override
5148    public void releaseSomeActivities(IApplicationThread appInt) {
5149        synchronized(this) {
5150            final long origId = Binder.clearCallingIdentity();
5151            try {
5152                ProcessRecord app = getRecordForAppLocked(appInt);
5153                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5154            } finally {
5155                Binder.restoreCallingIdentity(origId);
5156            }
5157        }
5158    }
5159
5160    @Override
5161    public boolean willActivityBeVisible(IBinder token) {
5162        synchronized(this) {
5163            ActivityStack stack = ActivityRecord.getStackLocked(token);
5164            if (stack != null) {
5165                return stack.willActivityBeVisibleLocked(token);
5166            }
5167            return false;
5168        }
5169    }
5170
5171    @Override
5172    public void overridePendingTransition(IBinder token, String packageName,
5173            int enterAnim, int exitAnim) {
5174        synchronized(this) {
5175            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5176            if (self == null) {
5177                return;
5178            }
5179
5180            final long origId = Binder.clearCallingIdentity();
5181
5182            if (self.state == ActivityState.RESUMED
5183                    || self.state == ActivityState.PAUSING) {
5184                mWindowManager.overridePendingAppTransition(packageName,
5185                        enterAnim, exitAnim, null);
5186            }
5187
5188            Binder.restoreCallingIdentity(origId);
5189        }
5190    }
5191
5192    /**
5193     * Main function for removing an existing process from the activity manager
5194     * as a result of that process going away.  Clears out all connections
5195     * to the process.
5196     */
5197    private final void handleAppDiedLocked(ProcessRecord app,
5198            boolean restarting, boolean allowRestart) {
5199        int pid = app.pid;
5200        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5201                false /*replacingPid*/);
5202        if (!kept && !restarting) {
5203            removeLruProcessLocked(app);
5204            if (pid > 0) {
5205                ProcessList.remove(pid);
5206            }
5207        }
5208
5209        if (mProfileProc == app) {
5210            clearProfilerLocked();
5211        }
5212
5213        // Remove this application's activities from active lists.
5214        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5215
5216        app.activities.clear();
5217
5218        if (app.instr != null) {
5219            Slog.w(TAG, "Crash of app " + app.processName
5220                  + " running instrumentation " + app.instr.mClass);
5221            Bundle info = new Bundle();
5222            info.putString("shortMsg", "Process crashed.");
5223            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5224        }
5225
5226        mWindowManager.deferSurfaceLayout();
5227        try {
5228            if (!restarting && hasVisibleActivities
5229                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5230                // If there was nothing to resume, and we are not already restarting this process, but
5231                // there is a visible activity that is hosted by the process...  then make sure all
5232                // visible activities are running, taking care of restarting this process.
5233                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5234            }
5235        } finally {
5236            mWindowManager.continueSurfaceLayout();
5237        }
5238    }
5239
5240    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5241        final IBinder threadBinder = thread.asBinder();
5242        // Find the application record.
5243        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5244            final ProcessRecord rec = mLruProcesses.get(i);
5245            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5246                return i;
5247            }
5248        }
5249        return -1;
5250    }
5251
5252    final ProcessRecord getRecordForAppLocked(
5253            IApplicationThread thread) {
5254        if (thread == null) {
5255            return null;
5256        }
5257
5258        int appIndex = getLRURecordIndexForAppLocked(thread);
5259        if (appIndex >= 0) {
5260            return mLruProcesses.get(appIndex);
5261        }
5262
5263        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5264        // double-check that.
5265        final IBinder threadBinder = thread.asBinder();
5266        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5267        for (int i = pmap.size()-1; i >= 0; i--) {
5268            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5269            for (int j = procs.size()-1; j >= 0; j--) {
5270                final ProcessRecord proc = procs.valueAt(j);
5271                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5272                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5273                            + proc);
5274                    return proc;
5275                }
5276            }
5277        }
5278
5279        return null;
5280    }
5281
5282    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5283        // If there are no longer any background processes running,
5284        // and the app that died was not running instrumentation,
5285        // then tell everyone we are now low on memory.
5286        boolean haveBg = false;
5287        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5288            ProcessRecord rec = mLruProcesses.get(i);
5289            if (rec.thread != null
5290                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5291                haveBg = true;
5292                break;
5293            }
5294        }
5295
5296        if (!haveBg) {
5297            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5298            if (doReport) {
5299                long now = SystemClock.uptimeMillis();
5300                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5301                    doReport = false;
5302                } else {
5303                    mLastMemUsageReportTime = now;
5304                }
5305            }
5306            final ArrayList<ProcessMemInfo> memInfos
5307                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5308            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5309            long now = SystemClock.uptimeMillis();
5310            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5311                ProcessRecord rec = mLruProcesses.get(i);
5312                if (rec == dyingProc || rec.thread == null) {
5313                    continue;
5314                }
5315                if (doReport) {
5316                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5317                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5318                }
5319                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5320                    // The low memory report is overriding any current
5321                    // state for a GC request.  Make sure to do
5322                    // heavy/important/visible/foreground processes first.
5323                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5324                        rec.lastRequestedGc = 0;
5325                    } else {
5326                        rec.lastRequestedGc = rec.lastLowMemory;
5327                    }
5328                    rec.reportLowMemory = true;
5329                    rec.lastLowMemory = now;
5330                    mProcessesToGc.remove(rec);
5331                    addProcessToGcListLocked(rec);
5332                }
5333            }
5334            if (doReport) {
5335                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5336                mHandler.sendMessage(msg);
5337            }
5338            scheduleAppGcsLocked();
5339        }
5340    }
5341
5342    final void appDiedLocked(ProcessRecord app) {
5343       appDiedLocked(app, app.pid, app.thread, false);
5344    }
5345
5346    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5347            boolean fromBinderDied) {
5348        // First check if this ProcessRecord is actually active for the pid.
5349        synchronized (mPidsSelfLocked) {
5350            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5351            if (curProc != app) {
5352                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5353                return;
5354            }
5355        }
5356
5357        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5358        synchronized (stats) {
5359            stats.noteProcessDiedLocked(app.info.uid, pid);
5360        }
5361
5362        if (!app.killed) {
5363            if (!fromBinderDied) {
5364                killProcessQuiet(pid);
5365            }
5366            killProcessGroup(app.uid, pid);
5367            app.killed = true;
5368        }
5369
5370        // Clean up already done if the process has been re-started.
5371        if (app.pid == pid && app.thread != null &&
5372                app.thread.asBinder() == thread.asBinder()) {
5373            boolean doLowMem = app.instr == null;
5374            boolean doOomAdj = doLowMem;
5375            if (!app.killedByAm) {
5376                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5377                        + ") has died");
5378                mAllowLowerMemLevel = true;
5379            } else {
5380                // Note that we always want to do oom adj to update our state with the
5381                // new number of procs.
5382                mAllowLowerMemLevel = false;
5383                doLowMem = false;
5384            }
5385            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5386            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5387                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5388            handleAppDiedLocked(app, false, true);
5389
5390            if (doOomAdj) {
5391                updateOomAdjLocked();
5392            }
5393            if (doLowMem) {
5394                doLowMemReportIfNeededLocked(app);
5395            }
5396        } else if (app.pid != pid) {
5397            // A new process has already been started.
5398            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5399                    + ") has died and restarted (pid " + app.pid + ").");
5400            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5401        } else if (DEBUG_PROCESSES) {
5402            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5403                    + thread.asBinder());
5404        }
5405    }
5406
5407    /**
5408     * If a stack trace dump file is configured, dump process stack traces.
5409     * @param clearTraces causes the dump file to be erased prior to the new
5410     *    traces being written, if true; when false, the new traces will be
5411     *    appended to any existing file content.
5412     * @param firstPids of dalvik VM processes to dump stack traces for first
5413     * @param lastPids of dalvik VM processes to dump stack traces for last
5414     * @param nativePids optional list of native pids to dump stack crawls
5415     * @return file containing stack traces, or null if no dump file is configured
5416     */
5417    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5418            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5419            ArrayList<Integer> nativePids) {
5420        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5421        if (tracesPath == null || tracesPath.length() == 0) {
5422            return null;
5423        }
5424
5425        File tracesFile = new File(tracesPath);
5426        try {
5427            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5428            tracesFile.createNewFile();
5429            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5430        } catch (IOException e) {
5431            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5432            return null;
5433        }
5434
5435        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativePids);
5436        return tracesFile;
5437    }
5438
5439    public static class DumpStackFileObserver extends FileObserver {
5440        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5441        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5442        static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
5443
5444        private final String mTracesPath;
5445        private boolean mClosed;
5446
5447        public DumpStackFileObserver(String tracesPath) {
5448            super(tracesPath, FileObserver.CLOSE_WRITE);
5449            mTracesPath = tracesPath;
5450        }
5451
5452        @Override
5453        public synchronized void onEvent(int event, String path) {
5454            mClosed = true;
5455            notify();
5456        }
5457
5458        public long dumpWithTimeout(int pid, long timeout) {
5459            sendSignal(pid, SIGNAL_QUIT);
5460            final long start = SystemClock.elapsedRealtime();
5461
5462            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5463            synchronized (this) {
5464                try {
5465                    wait(waitTime); // Wait for traces file to be closed.
5466                } catch (InterruptedException e) {
5467                    Slog.wtf(TAG, e);
5468                }
5469            }
5470
5471            // This avoids a corner case of passing a negative time to the native
5472            // trace in case we've already hit the overall timeout.
5473            final long timeWaited = SystemClock.elapsedRealtime() - start;
5474            if (timeWaited >= timeout) {
5475                return timeWaited;
5476            }
5477
5478            if (!mClosed) {
5479                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5480                       ". Attempting native stack collection.");
5481
5482                final long nativeDumpTimeoutMs = Math.min(
5483                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5484
5485                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5486                        (int) (nativeDumpTimeoutMs / 1000));
5487            }
5488
5489            final long end = SystemClock.elapsedRealtime();
5490            mClosed = false;
5491
5492            return (end - start);
5493        }
5494    }
5495
5496    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5497            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5498            ArrayList<Integer> nativePids) {
5499        // Use a FileObserver to detect when traces finish writing.
5500        // The order of traces is considered important to maintain for legibility.
5501        DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
5502
5503        // We must complete all stack dumps within 20 seconds.
5504        long remainingTime = 20 * 1000;
5505        try {
5506            observer.startWatching();
5507
5508            // First collect all of the stacks of the most important pids.
5509            if (firstPids != null) {
5510                int num = firstPids.size();
5511                for (int i = 0; i < num; i++) {
5512                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5513                            + firstPids.get(i));
5514                    final long timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5515
5516                    remainingTime -= timeTaken;
5517                    if (remainingTime <= 0) {
5518                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5519                            "); deadline exceeded.");
5520                        return;
5521                    }
5522
5523                    if (DEBUG_ANR) {
5524                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5525                    }
5526                }
5527            }
5528
5529            // Next collect the stacks of the native pids
5530            if (nativePids != null) {
5531                for (int pid : nativePids) {
5532                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5533                    final long nativeDumpTimeoutMs = Math.min(
5534                            DumpStackFileObserver.NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5535
5536                    final long start = SystemClock.elapsedRealtime();
5537                    Debug.dumpNativeBacktraceToFileTimeout(
5538                            pid, tracesPath, (int) (nativeDumpTimeoutMs / 1000));
5539                    final long timeTaken = SystemClock.elapsedRealtime() - start;
5540
5541                    remainingTime -= timeTaken;
5542                    if (remainingTime <= 0) {
5543                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5544                            "); deadline exceeded.");
5545                        return;
5546                    }
5547
5548                    if (DEBUG_ANR) {
5549                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5550                    }
5551                }
5552            }
5553
5554            // Lastly, measure CPU usage.
5555            if (processCpuTracker != null) {
5556                processCpuTracker.init();
5557                System.gc();
5558                processCpuTracker.update();
5559                try {
5560                    synchronized (processCpuTracker) {
5561                        processCpuTracker.wait(500); // measure over 1/2 second.
5562                    }
5563                } catch (InterruptedException e) {
5564                }
5565                processCpuTracker.update();
5566
5567                // We'll take the stack crawls of just the top apps using CPU.
5568                final int N = processCpuTracker.countWorkingStats();
5569                int numProcs = 0;
5570                for (int i=0; i<N && numProcs<5; i++) {
5571                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5572                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5573                        numProcs++;
5574
5575                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5576
5577                        final long timeTaken = observer.dumpWithTimeout(stats.pid, remainingTime);
5578                        remainingTime -= timeTaken;
5579                        if (remainingTime <= 0) {
5580                            Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + stats.pid +
5581                                "); deadline exceeded.");
5582                            return;
5583                        }
5584
5585                        if (DEBUG_ANR) {
5586                            Slog.d(TAG, "Done with extra pid " + stats.pid + " in " + timeTaken + "ms");
5587                        }
5588                    } else if (DEBUG_ANR) {
5589                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5590                                + stats.pid);
5591                    }
5592                }
5593            }
5594        } finally {
5595            observer.stopWatching();
5596        }
5597    }
5598
5599    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5600        if (true || IS_USER_BUILD) {
5601            return;
5602        }
5603        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5604        if (tracesPath == null || tracesPath.length() == 0) {
5605            return;
5606        }
5607
5608        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5609        StrictMode.allowThreadDiskWrites();
5610        try {
5611            final File tracesFile = new File(tracesPath);
5612            final File tracesDir = tracesFile.getParentFile();
5613            final File tracesTmp = new File(tracesDir, "__tmp__");
5614            try {
5615                if (tracesFile.exists()) {
5616                    tracesTmp.delete();
5617                    tracesFile.renameTo(tracesTmp);
5618                }
5619                StringBuilder sb = new StringBuilder();
5620                Time tobj = new Time();
5621                tobj.set(System.currentTimeMillis());
5622                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5623                sb.append(": ");
5624                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5625                sb.append(" since ");
5626                sb.append(msg);
5627                FileOutputStream fos = new FileOutputStream(tracesFile);
5628                fos.write(sb.toString().getBytes());
5629                if (app == null) {
5630                    fos.write("\n*** No application process!".getBytes());
5631                }
5632                fos.close();
5633                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5634            } catch (IOException e) {
5635                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5636                return;
5637            }
5638
5639            if (app != null) {
5640                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5641                firstPids.add(app.pid);
5642                dumpStackTraces(tracesPath, firstPids, null, null, null);
5643            }
5644
5645            File lastTracesFile = null;
5646            File curTracesFile = null;
5647            for (int i=9; i>=0; i--) {
5648                String name = String.format(Locale.US, "slow%02d.txt", i);
5649                curTracesFile = new File(tracesDir, name);
5650                if (curTracesFile.exists()) {
5651                    if (lastTracesFile != null) {
5652                        curTracesFile.renameTo(lastTracesFile);
5653                    } else {
5654                        curTracesFile.delete();
5655                    }
5656                }
5657                lastTracesFile = curTracesFile;
5658            }
5659            tracesFile.renameTo(curTracesFile);
5660            if (tracesTmp.exists()) {
5661                tracesTmp.renameTo(tracesFile);
5662            }
5663        } finally {
5664            StrictMode.setThreadPolicy(oldPolicy);
5665        }
5666    }
5667
5668    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5669        if (!mLaunchWarningShown) {
5670            mLaunchWarningShown = true;
5671            mUiHandler.post(new Runnable() {
5672                @Override
5673                public void run() {
5674                    synchronized (ActivityManagerService.this) {
5675                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5676                        d.show();
5677                        mUiHandler.postDelayed(new Runnable() {
5678                            @Override
5679                            public void run() {
5680                                synchronized (ActivityManagerService.this) {
5681                                    d.dismiss();
5682                                    mLaunchWarningShown = false;
5683                                }
5684                            }
5685                        }, 4000);
5686                    }
5687                }
5688            });
5689        }
5690    }
5691
5692    @Override
5693    public boolean clearApplicationUserData(final String packageName,
5694            final IPackageDataObserver observer, int userId) {
5695        enforceNotIsolatedCaller("clearApplicationUserData");
5696        int uid = Binder.getCallingUid();
5697        int pid = Binder.getCallingPid();
5698        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5699                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5700
5701
5702        long callingId = Binder.clearCallingIdentity();
5703        try {
5704            IPackageManager pm = AppGlobals.getPackageManager();
5705            int pkgUid = -1;
5706            synchronized(this) {
5707                if (getPackageManagerInternalLocked().isPackageDataProtected(
5708                        userId, packageName)) {
5709                    throw new SecurityException(
5710                            "Cannot clear data for a protected package: " + packageName);
5711                }
5712
5713                try {
5714                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5715                } catch (RemoteException e) {
5716                }
5717                if (pkgUid == -1) {
5718                    Slog.w(TAG, "Invalid packageName: " + packageName);
5719                    if (observer != null) {
5720                        try {
5721                            observer.onRemoveCompleted(packageName, false);
5722                        } catch (RemoteException e) {
5723                            Slog.i(TAG, "Observer no longer exists.");
5724                        }
5725                    }
5726                    return false;
5727                }
5728                if (uid == pkgUid || checkComponentPermission(
5729                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5730                        pid, uid, -1, true)
5731                        == PackageManager.PERMISSION_GRANTED) {
5732                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5733                } else {
5734                    throw new SecurityException("PID " + pid + " does not have permission "
5735                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5736                                    + " of package " + packageName);
5737                }
5738
5739                // Remove all tasks match the cleared application package and user
5740                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5741                    final TaskRecord tr = mRecentTasks.get(i);
5742                    final String taskPackageName =
5743                            tr.getBaseIntent().getComponent().getPackageName();
5744                    if (tr.userId != userId) continue;
5745                    if (!taskPackageName.equals(packageName)) continue;
5746                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5747                }
5748            }
5749
5750            final int pkgUidF = pkgUid;
5751            final int userIdF = userId;
5752            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5753                @Override
5754                public void onRemoveCompleted(String packageName, boolean succeeded)
5755                        throws RemoteException {
5756                    synchronized (ActivityManagerService.this) {
5757                        finishForceStopPackageLocked(packageName, pkgUidF);
5758                    }
5759
5760                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5761                            Uri.fromParts("package", packageName, null));
5762                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5763                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5764                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5765                    broadcastIntentInPackage("android", SYSTEM_UID, intent,
5766                            null, null, 0, null, null, null, null, false, false, userIdF);
5767
5768                    if (observer != null) {
5769                        observer.onRemoveCompleted(packageName, succeeded);
5770                    }
5771                }
5772            };
5773
5774            try {
5775                // Clear application user data
5776                pm.clearApplicationUserData(packageName, localObserver, userId);
5777
5778                synchronized(this) {
5779                    // Remove all permissions granted from/to this package
5780                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5781                }
5782
5783                // Reset notification settings.
5784                INotificationManager inm = NotificationManager.getService();
5785                inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5786            } catch (RemoteException e) {
5787            }
5788        } finally {
5789            Binder.restoreCallingIdentity(callingId);
5790        }
5791        return true;
5792    }
5793
5794    @Override
5795    public void killBackgroundProcesses(final String packageName, int userId) {
5796        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5797                != PackageManager.PERMISSION_GRANTED &&
5798                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5799                        != PackageManager.PERMISSION_GRANTED) {
5800            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5801                    + Binder.getCallingPid()
5802                    + ", uid=" + Binder.getCallingUid()
5803                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5804            Slog.w(TAG, msg);
5805            throw new SecurityException(msg);
5806        }
5807
5808        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5809                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5810        long callingId = Binder.clearCallingIdentity();
5811        try {
5812            IPackageManager pm = AppGlobals.getPackageManager();
5813            synchronized(this) {
5814                int appId = -1;
5815                try {
5816                    appId = UserHandle.getAppId(
5817                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5818                } catch (RemoteException e) {
5819                }
5820                if (appId == -1) {
5821                    Slog.w(TAG, "Invalid packageName: " + packageName);
5822                    return;
5823                }
5824                killPackageProcessesLocked(packageName, appId, userId,
5825                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5826            }
5827        } finally {
5828            Binder.restoreCallingIdentity(callingId);
5829        }
5830    }
5831
5832    @Override
5833    public void killAllBackgroundProcesses() {
5834        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5835                != PackageManager.PERMISSION_GRANTED) {
5836            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5837                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5838                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5839            Slog.w(TAG, msg);
5840            throw new SecurityException(msg);
5841        }
5842
5843        final long callingId = Binder.clearCallingIdentity();
5844        try {
5845            synchronized (this) {
5846                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5847                final int NP = mProcessNames.getMap().size();
5848                for (int ip = 0; ip < NP; ip++) {
5849                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5850                    final int NA = apps.size();
5851                    for (int ia = 0; ia < NA; ia++) {
5852                        final ProcessRecord app = apps.valueAt(ia);
5853                        if (app.persistent) {
5854                            // We don't kill persistent processes.
5855                            continue;
5856                        }
5857                        if (app.removed) {
5858                            procs.add(app);
5859                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5860                            app.removed = true;
5861                            procs.add(app);
5862                        }
5863                    }
5864                }
5865
5866                final int N = procs.size();
5867                for (int i = 0; i < N; i++) {
5868                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5869                }
5870
5871                mAllowLowerMemLevel = true;
5872
5873                updateOomAdjLocked();
5874                doLowMemReportIfNeededLocked(null);
5875            }
5876        } finally {
5877            Binder.restoreCallingIdentity(callingId);
5878        }
5879    }
5880
5881    /**
5882     * Kills all background processes, except those matching any of the
5883     * specified properties.
5884     *
5885     * @param minTargetSdk the target SDK version at or above which to preserve
5886     *                     processes, or {@code -1} to ignore the target SDK
5887     * @param maxProcState the process state at or below which to preserve
5888     *                     processes, or {@code -1} to ignore the process state
5889     */
5890    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5891        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5892                != PackageManager.PERMISSION_GRANTED) {
5893            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5894                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5895                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5896            Slog.w(TAG, msg);
5897            throw new SecurityException(msg);
5898        }
5899
5900        final long callingId = Binder.clearCallingIdentity();
5901        try {
5902            synchronized (this) {
5903                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5904                final int NP = mProcessNames.getMap().size();
5905                for (int ip = 0; ip < NP; ip++) {
5906                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5907                    final int NA = apps.size();
5908                    for (int ia = 0; ia < NA; ia++) {
5909                        final ProcessRecord app = apps.valueAt(ia);
5910                        if (app.removed) {
5911                            procs.add(app);
5912                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5913                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5914                            app.removed = true;
5915                            procs.add(app);
5916                        }
5917                    }
5918                }
5919
5920                final int N = procs.size();
5921                for (int i = 0; i < N; i++) {
5922                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5923                }
5924            }
5925        } finally {
5926            Binder.restoreCallingIdentity(callingId);
5927        }
5928    }
5929
5930    @Override
5931    public void forceStopPackage(final String packageName, int userId) {
5932        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5933                != PackageManager.PERMISSION_GRANTED) {
5934            String msg = "Permission Denial: forceStopPackage() from pid="
5935                    + Binder.getCallingPid()
5936                    + ", uid=" + Binder.getCallingUid()
5937                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5938            Slog.w(TAG, msg);
5939            throw new SecurityException(msg);
5940        }
5941        final int callingPid = Binder.getCallingPid();
5942        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5943                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5944        long callingId = Binder.clearCallingIdentity();
5945        try {
5946            IPackageManager pm = AppGlobals.getPackageManager();
5947            synchronized(this) {
5948                int[] users = userId == UserHandle.USER_ALL
5949                        ? mUserController.getUsers() : new int[] { userId };
5950                for (int user : users) {
5951                    int pkgUid = -1;
5952                    try {
5953                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5954                                user);
5955                    } catch (RemoteException e) {
5956                    }
5957                    if (pkgUid == -1) {
5958                        Slog.w(TAG, "Invalid packageName: " + packageName);
5959                        continue;
5960                    }
5961                    try {
5962                        pm.setPackageStoppedState(packageName, true, user);
5963                    } catch (RemoteException e) {
5964                    } catch (IllegalArgumentException e) {
5965                        Slog.w(TAG, "Failed trying to unstop package "
5966                                + packageName + ": " + e);
5967                    }
5968                    if (mUserController.isUserRunningLocked(user, 0)) {
5969                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5970                        finishForceStopPackageLocked(packageName, pkgUid);
5971                    }
5972                }
5973            }
5974        } finally {
5975            Binder.restoreCallingIdentity(callingId);
5976        }
5977    }
5978
5979    @Override
5980    public void addPackageDependency(String packageName) {
5981        synchronized (this) {
5982            int callingPid = Binder.getCallingPid();
5983            if (callingPid == myPid()) {
5984                //  Yeah, um, no.
5985                return;
5986            }
5987            ProcessRecord proc;
5988            synchronized (mPidsSelfLocked) {
5989                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5990            }
5991            if (proc != null) {
5992                if (proc.pkgDeps == null) {
5993                    proc.pkgDeps = new ArraySet<String>(1);
5994                }
5995                proc.pkgDeps.add(packageName);
5996            }
5997        }
5998    }
5999
6000    /*
6001     * The pkg name and app id have to be specified.
6002     */
6003    @Override
6004    public void killApplication(String pkg, int appId, int userId, String reason) {
6005        if (pkg == null) {
6006            return;
6007        }
6008        // Make sure the uid is valid.
6009        if (appId < 0) {
6010            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6011            return;
6012        }
6013        int callerUid = Binder.getCallingUid();
6014        // Only the system server can kill an application
6015        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6016            // Post an aysnc message to kill the application
6017            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6018            msg.arg1 = appId;
6019            msg.arg2 = userId;
6020            Bundle bundle = new Bundle();
6021            bundle.putString("pkg", pkg);
6022            bundle.putString("reason", reason);
6023            msg.obj = bundle;
6024            mHandler.sendMessage(msg);
6025        } else {
6026            throw new SecurityException(callerUid + " cannot kill pkg: " +
6027                    pkg);
6028        }
6029    }
6030
6031    @Override
6032    public void closeSystemDialogs(String reason) {
6033        enforceNotIsolatedCaller("closeSystemDialogs");
6034
6035        final int pid = Binder.getCallingPid();
6036        final int uid = Binder.getCallingUid();
6037        final long origId = Binder.clearCallingIdentity();
6038        try {
6039            synchronized (this) {
6040                // Only allow this from foreground processes, so that background
6041                // applications can't abuse it to prevent system UI from being shown.
6042                if (uid >= FIRST_APPLICATION_UID) {
6043                    ProcessRecord proc;
6044                    synchronized (mPidsSelfLocked) {
6045                        proc = mPidsSelfLocked.get(pid);
6046                    }
6047                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6048                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6049                                + " from background process " + proc);
6050                        return;
6051                    }
6052                }
6053                closeSystemDialogsLocked(reason);
6054            }
6055        } finally {
6056            Binder.restoreCallingIdentity(origId);
6057        }
6058    }
6059
6060    void closeSystemDialogsLocked(String reason) {
6061        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6062        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6063                | Intent.FLAG_RECEIVER_FOREGROUND);
6064        if (reason != null) {
6065            intent.putExtra("reason", reason);
6066        }
6067        mWindowManager.closeSystemDialogs(reason);
6068
6069        mStackSupervisor.closeSystemDialogsLocked();
6070
6071        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6072                AppOpsManager.OP_NONE, null, false, false,
6073                -1, SYSTEM_UID, UserHandle.USER_ALL);
6074    }
6075
6076    @Override
6077    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6078        enforceNotIsolatedCaller("getProcessMemoryInfo");
6079        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6080        for (int i=pids.length-1; i>=0; i--) {
6081            ProcessRecord proc;
6082            int oomAdj;
6083            synchronized (this) {
6084                synchronized (mPidsSelfLocked) {
6085                    proc = mPidsSelfLocked.get(pids[i]);
6086                    oomAdj = proc != null ? proc.setAdj : 0;
6087                }
6088            }
6089            infos[i] = new Debug.MemoryInfo();
6090            Debug.getMemoryInfo(pids[i], infos[i]);
6091            if (proc != null) {
6092                synchronized (this) {
6093                    if (proc.thread != null && proc.setAdj == oomAdj) {
6094                        // Record this for posterity if the process has been stable.
6095                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6096                                infos[i].getTotalUss(), false, proc.pkgList);
6097                    }
6098                }
6099            }
6100        }
6101        return infos;
6102    }
6103
6104    @Override
6105    public long[] getProcessPss(int[] pids) {
6106        enforceNotIsolatedCaller("getProcessPss");
6107        long[] pss = new long[pids.length];
6108        for (int i=pids.length-1; i>=0; i--) {
6109            ProcessRecord proc;
6110            int oomAdj;
6111            synchronized (this) {
6112                synchronized (mPidsSelfLocked) {
6113                    proc = mPidsSelfLocked.get(pids[i]);
6114                    oomAdj = proc != null ? proc.setAdj : 0;
6115                }
6116            }
6117            long[] tmpUss = new long[1];
6118            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6119            if (proc != null) {
6120                synchronized (this) {
6121                    if (proc.thread != null && proc.setAdj == oomAdj) {
6122                        // Record this for posterity if the process has been stable.
6123                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6124                    }
6125                }
6126            }
6127        }
6128        return pss;
6129    }
6130
6131    @Override
6132    public void killApplicationProcess(String processName, int uid) {
6133        if (processName == null) {
6134            return;
6135        }
6136
6137        int callerUid = Binder.getCallingUid();
6138        // Only the system server can kill an application
6139        if (callerUid == SYSTEM_UID) {
6140            synchronized (this) {
6141                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6142                if (app != null && app.thread != null) {
6143                    try {
6144                        app.thread.scheduleSuicide();
6145                    } catch (RemoteException e) {
6146                        // If the other end already died, then our work here is done.
6147                    }
6148                } else {
6149                    Slog.w(TAG, "Process/uid not found attempting kill of "
6150                            + processName + " / " + uid);
6151                }
6152            }
6153        } else {
6154            throw new SecurityException(callerUid + " cannot kill app process: " +
6155                    processName);
6156        }
6157    }
6158
6159    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6160        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6161                false, true, false, false, UserHandle.getUserId(uid), reason);
6162    }
6163
6164    private void finishForceStopPackageLocked(final String packageName, int uid) {
6165        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6166                Uri.fromParts("package", packageName, null));
6167        if (!mProcessesReady) {
6168            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6169                    | Intent.FLAG_RECEIVER_FOREGROUND);
6170        }
6171        intent.putExtra(Intent.EXTRA_UID, uid);
6172        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6173        broadcastIntentLocked(null, null, intent,
6174                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6175                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6176    }
6177
6178
6179    private final boolean killPackageProcessesLocked(String packageName, int appId,
6180            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6181            boolean doit, boolean evenPersistent, String reason) {
6182        ArrayList<ProcessRecord> procs = new ArrayList<>();
6183
6184        // Remove all processes this package may have touched: all with the
6185        // same UID (except for the system or root user), and all whose name
6186        // matches the package name.
6187        final int NP = mProcessNames.getMap().size();
6188        for (int ip=0; ip<NP; ip++) {
6189            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6190            final int NA = apps.size();
6191            for (int ia=0; ia<NA; ia++) {
6192                ProcessRecord app = apps.valueAt(ia);
6193                if (app.persistent && !evenPersistent) {
6194                    // we don't kill persistent processes
6195                    continue;
6196                }
6197                if (app.removed) {
6198                    if (doit) {
6199                        procs.add(app);
6200                    }
6201                    continue;
6202                }
6203
6204                // Skip process if it doesn't meet our oom adj requirement.
6205                if (app.setAdj < minOomAdj) {
6206                    continue;
6207                }
6208
6209                // If no package is specified, we call all processes under the
6210                // give user id.
6211                if (packageName == null) {
6212                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6213                        continue;
6214                    }
6215                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6216                        continue;
6217                    }
6218                // Package has been specified, we want to hit all processes
6219                // that match it.  We need to qualify this by the processes
6220                // that are running under the specified app and user ID.
6221                } else {
6222                    final boolean isDep = app.pkgDeps != null
6223                            && app.pkgDeps.contains(packageName);
6224                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6225                        continue;
6226                    }
6227                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6228                        continue;
6229                    }
6230                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6231                        continue;
6232                    }
6233                }
6234
6235                // Process has passed all conditions, kill it!
6236                if (!doit) {
6237                    return true;
6238                }
6239                app.removed = true;
6240                procs.add(app);
6241            }
6242        }
6243
6244        int N = procs.size();
6245        for (int i=0; i<N; i++) {
6246            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6247        }
6248        updateOomAdjLocked();
6249        return N > 0;
6250    }
6251
6252    private void cleanupDisabledPackageComponentsLocked(
6253            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6254
6255        Set<String> disabledClasses = null;
6256        boolean packageDisabled = false;
6257        IPackageManager pm = AppGlobals.getPackageManager();
6258
6259        if (changedClasses == null) {
6260            // Nothing changed...
6261            return;
6262        }
6263
6264        // Determine enable/disable state of the package and its components.
6265        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6266        for (int i = changedClasses.length - 1; i >= 0; i--) {
6267            final String changedClass = changedClasses[i];
6268
6269            if (changedClass.equals(packageName)) {
6270                try {
6271                    // Entire package setting changed
6272                    enabled = pm.getApplicationEnabledSetting(packageName,
6273                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6274                } catch (Exception e) {
6275                    // No such package/component; probably racing with uninstall.  In any
6276                    // event it means we have nothing further to do here.
6277                    return;
6278                }
6279                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6280                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6281                if (packageDisabled) {
6282                    // Entire package is disabled.
6283                    // No need to continue to check component states.
6284                    disabledClasses = null;
6285                    break;
6286                }
6287            } else {
6288                try {
6289                    enabled = pm.getComponentEnabledSetting(
6290                            new ComponentName(packageName, changedClass),
6291                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6292                } catch (Exception e) {
6293                    // As above, probably racing with uninstall.
6294                    return;
6295                }
6296                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6297                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6298                    if (disabledClasses == null) {
6299                        disabledClasses = new ArraySet<>(changedClasses.length);
6300                    }
6301                    disabledClasses.add(changedClass);
6302                }
6303            }
6304        }
6305
6306        if (!packageDisabled && disabledClasses == null) {
6307            // Nothing to do here...
6308            return;
6309        }
6310
6311        // Clean-up disabled activities.
6312        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6313                packageName, disabledClasses, true, false, userId) && mBooted) {
6314            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6315            mStackSupervisor.scheduleIdleLocked();
6316        }
6317
6318        // Clean-up disabled tasks
6319        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6320
6321        // Clean-up disabled services.
6322        mServices.bringDownDisabledPackageServicesLocked(
6323                packageName, disabledClasses, userId, false, killProcess, true);
6324
6325        // Clean-up disabled providers.
6326        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6327        mProviderMap.collectPackageProvidersLocked(
6328                packageName, disabledClasses, true, false, userId, providers);
6329        for (int i = providers.size() - 1; i >= 0; i--) {
6330            removeDyingProviderLocked(null, providers.get(i), true);
6331        }
6332
6333        // Clean-up disabled broadcast receivers.
6334        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6335            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6336                    packageName, disabledClasses, userId, true);
6337        }
6338
6339    }
6340
6341    final boolean clearBroadcastQueueForUserLocked(int userId) {
6342        boolean didSomething = false;
6343        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6344            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6345                    null, null, userId, true);
6346        }
6347        return didSomething;
6348    }
6349
6350    final boolean forceStopPackageLocked(String packageName, int appId,
6351            boolean callerWillRestart, boolean purgeCache, boolean doit,
6352            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6353        int i;
6354
6355        if (userId == UserHandle.USER_ALL && packageName == null) {
6356            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6357        }
6358
6359        if (appId < 0 && packageName != null) {
6360            try {
6361                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6362                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6363            } catch (RemoteException e) {
6364            }
6365        }
6366
6367        if (doit) {
6368            if (packageName != null) {
6369                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6370                        + " user=" + userId + ": " + reason);
6371            } else {
6372                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6373            }
6374
6375            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6376        }
6377
6378        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6379                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6380                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6381
6382        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6383
6384        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6385                packageName, null, doit, evenPersistent, userId)) {
6386            if (!doit) {
6387                return true;
6388            }
6389            didSomething = true;
6390        }
6391
6392        if (mServices.bringDownDisabledPackageServicesLocked(
6393                packageName, null, userId, evenPersistent, true, doit)) {
6394            if (!doit) {
6395                return true;
6396            }
6397            didSomething = true;
6398        }
6399
6400        if (packageName == null) {
6401            // Remove all sticky broadcasts from this user.
6402            mStickyBroadcasts.remove(userId);
6403        }
6404
6405        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6406        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6407                userId, providers)) {
6408            if (!doit) {
6409                return true;
6410            }
6411            didSomething = true;
6412        }
6413        for (i = providers.size() - 1; i >= 0; i--) {
6414            removeDyingProviderLocked(null, providers.get(i), true);
6415        }
6416
6417        // Remove transient permissions granted from/to this package/user
6418        removeUriPermissionsForPackageLocked(packageName, userId, false);
6419
6420        if (doit) {
6421            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6422                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6423                        packageName, null, userId, doit);
6424            }
6425        }
6426
6427        if (packageName == null || uninstalling) {
6428            // Remove pending intents.  For now we only do this when force
6429            // stopping users, because we have some problems when doing this
6430            // for packages -- app widgets are not currently cleaned up for
6431            // such packages, so they can be left with bad pending intents.
6432            if (mIntentSenderRecords.size() > 0) {
6433                Iterator<WeakReference<PendingIntentRecord>> it
6434                        = mIntentSenderRecords.values().iterator();
6435                while (it.hasNext()) {
6436                    WeakReference<PendingIntentRecord> wpir = it.next();
6437                    if (wpir == null) {
6438                        it.remove();
6439                        continue;
6440                    }
6441                    PendingIntentRecord pir = wpir.get();
6442                    if (pir == null) {
6443                        it.remove();
6444                        continue;
6445                    }
6446                    if (packageName == null) {
6447                        // Stopping user, remove all objects for the user.
6448                        if (pir.key.userId != userId) {
6449                            // Not the same user, skip it.
6450                            continue;
6451                        }
6452                    } else {
6453                        if (UserHandle.getAppId(pir.uid) != appId) {
6454                            // Different app id, skip it.
6455                            continue;
6456                        }
6457                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6458                            // Different user, skip it.
6459                            continue;
6460                        }
6461                        if (!pir.key.packageName.equals(packageName)) {
6462                            // Different package, skip it.
6463                            continue;
6464                        }
6465                    }
6466                    if (!doit) {
6467                        return true;
6468                    }
6469                    didSomething = true;
6470                    it.remove();
6471                    makeIntentSenderCanceledLocked(pir);
6472                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6473                        pir.key.activity.pendingResults.remove(pir.ref);
6474                    }
6475                }
6476            }
6477        }
6478
6479        if (doit) {
6480            if (purgeCache && packageName != null) {
6481                AttributeCache ac = AttributeCache.instance();
6482                if (ac != null) {
6483                    ac.removePackage(packageName);
6484                }
6485            }
6486            if (mBooted) {
6487                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6488                mStackSupervisor.scheduleIdleLocked();
6489            }
6490        }
6491
6492        return didSomething;
6493    }
6494
6495    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6496        return removeProcessNameLocked(name, uid, null);
6497    }
6498
6499    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6500            final ProcessRecord expecting) {
6501        ProcessRecord old = mProcessNames.get(name, uid);
6502        // Only actually remove when the currently recorded value matches the
6503        // record that we expected; if it doesn't match then we raced with a
6504        // newly created process and we don't want to destroy the new one.
6505        if ((expecting == null) || (old == expecting)) {
6506            mProcessNames.remove(name, uid);
6507        }
6508        if (old != null && old.uidRecord != null) {
6509            old.uidRecord.numProcs--;
6510            if (old.uidRecord.numProcs == 0) {
6511                // No more processes using this uid, tell clients it is gone.
6512                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6513                        "No more processes in " + old.uidRecord);
6514                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6515                EventLogTags.writeAmUidStopped(uid);
6516                mActiveUids.remove(uid);
6517                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6518            }
6519            old.uidRecord = null;
6520        }
6521        mIsolatedProcesses.remove(uid);
6522        return old;
6523    }
6524
6525    private final void addProcessNameLocked(ProcessRecord proc) {
6526        // We shouldn't already have a process under this name, but just in case we
6527        // need to clean up whatever may be there now.
6528        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6529        if (old == proc && proc.persistent) {
6530            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6531            Slog.w(TAG, "Re-adding persistent process " + proc);
6532        } else if (old != null) {
6533            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6534        }
6535        UidRecord uidRec = mActiveUids.get(proc.uid);
6536        if (uidRec == null) {
6537            uidRec = new UidRecord(proc.uid);
6538            // This is the first appearance of the uid, report it now!
6539            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6540                    "Creating new process uid: " + uidRec);
6541            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6542                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6543                uidRec.setWhitelist = uidRec.curWhitelist = true;
6544            }
6545            uidRec.updateHasInternetPermission();
6546            mActiveUids.put(proc.uid, uidRec);
6547            EventLogTags.writeAmUidRunning(uidRec.uid);
6548            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6549            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6550        }
6551        proc.uidRecord = uidRec;
6552
6553        // Reset render thread tid if it was already set, so new process can set it again.
6554        proc.renderThreadTid = 0;
6555        uidRec.numProcs++;
6556        mProcessNames.put(proc.processName, proc.uid, proc);
6557        if (proc.isolated) {
6558            mIsolatedProcesses.put(proc.uid, proc);
6559        }
6560    }
6561
6562    boolean removeProcessLocked(ProcessRecord app,
6563            boolean callerWillRestart, boolean allowRestart, String reason) {
6564        final String name = app.processName;
6565        final int uid = app.uid;
6566        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6567            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6568
6569        ProcessRecord old = mProcessNames.get(name, uid);
6570        if (old != app) {
6571            // This process is no longer active, so nothing to do.
6572            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6573            return false;
6574        }
6575        removeProcessNameLocked(name, uid);
6576        if (mHeavyWeightProcess == app) {
6577            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6578                    mHeavyWeightProcess.userId, 0));
6579            mHeavyWeightProcess = null;
6580        }
6581        boolean needRestart = false;
6582        if (app.pid > 0 && app.pid != MY_PID) {
6583            int pid = app.pid;
6584            synchronized (mPidsSelfLocked) {
6585                mPidsSelfLocked.remove(pid);
6586                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6587            }
6588            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6589            if (app.isolated) {
6590                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6591                getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6592            }
6593            boolean willRestart = false;
6594            if (app.persistent && !app.isolated) {
6595                if (!callerWillRestart) {
6596                    willRestart = true;
6597                } else {
6598                    needRestart = true;
6599                }
6600            }
6601            app.kill(reason, true);
6602            handleAppDiedLocked(app, willRestart, allowRestart);
6603            if (willRestart) {
6604                removeLruProcessLocked(app);
6605                addAppLocked(app.info, null, false, null /* ABI override */);
6606            }
6607        } else {
6608            mRemovedProcesses.add(app);
6609        }
6610
6611        return needRestart;
6612    }
6613
6614    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6615        cleanupAppInLaunchingProvidersLocked(app, true);
6616        removeProcessLocked(app, false, true, "timeout publishing content providers");
6617    }
6618
6619    private final void processStartTimedOutLocked(ProcessRecord app) {
6620        final int pid = app.pid;
6621        boolean gone = false;
6622        synchronized (mPidsSelfLocked) {
6623            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6624            if (knownApp != null && knownApp.thread == null) {
6625                mPidsSelfLocked.remove(pid);
6626                gone = true;
6627            }
6628        }
6629
6630        if (gone) {
6631            Slog.w(TAG, "Process " + app + " failed to attach");
6632            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6633                    pid, app.uid, app.processName);
6634            removeProcessNameLocked(app.processName, app.uid);
6635            if (mHeavyWeightProcess == app) {
6636                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6637                        mHeavyWeightProcess.userId, 0));
6638                mHeavyWeightProcess = null;
6639            }
6640            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6641            if (app.isolated) {
6642                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6643            }
6644            // Take care of any launching providers waiting for this process.
6645            cleanupAppInLaunchingProvidersLocked(app, true);
6646            // Take care of any services that are waiting for the process.
6647            mServices.processStartTimedOutLocked(app);
6648            app.kill("start timeout", true);
6649            removeLruProcessLocked(app);
6650            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6651                Slog.w(TAG, "Unattached app died before backup, skipping");
6652                mHandler.post(new Runnable() {
6653                @Override
6654                    public void run(){
6655                        try {
6656                            IBackupManager bm = IBackupManager.Stub.asInterface(
6657                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6658                            bm.agentDisconnected(app.info.packageName);
6659                        } catch (RemoteException e) {
6660                            // Can't happen; the backup manager is local
6661                        }
6662                    }
6663                });
6664            }
6665            if (isPendingBroadcastProcessLocked(pid)) {
6666                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6667                skipPendingBroadcastLocked(pid);
6668            }
6669        } else {
6670            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6671        }
6672    }
6673
6674    private final boolean attachApplicationLocked(IApplicationThread thread,
6675            int pid) {
6676
6677        // Find the application record that is being attached...  either via
6678        // the pid if we are running in multiple processes, or just pull the
6679        // next app record if we are emulating process with anonymous threads.
6680        ProcessRecord app;
6681        long startTime = SystemClock.uptimeMillis();
6682        if (pid != MY_PID && pid >= 0) {
6683            synchronized (mPidsSelfLocked) {
6684                app = mPidsSelfLocked.get(pid);
6685            }
6686        } else {
6687            app = null;
6688        }
6689
6690        if (app == null) {
6691            Slog.w(TAG, "No pending application record for pid " + pid
6692                    + " (IApplicationThread " + thread + "); dropping process");
6693            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6694            if (pid > 0 && pid != MY_PID) {
6695                killProcessQuiet(pid);
6696                //TODO: killProcessGroup(app.info.uid, pid);
6697            } else {
6698                try {
6699                    thread.scheduleExit();
6700                } catch (Exception e) {
6701                    // Ignore exceptions.
6702                }
6703            }
6704            return false;
6705        }
6706
6707        // If this application record is still attached to a previous
6708        // process, clean it up now.
6709        if (app.thread != null) {
6710            handleAppDiedLocked(app, true, true);
6711        }
6712
6713        // Tell the process all about itself.
6714
6715        if (DEBUG_ALL) Slog.v(
6716                TAG, "Binding process pid " + pid + " to record " + app);
6717
6718        final String processName = app.processName;
6719        try {
6720            AppDeathRecipient adr = new AppDeathRecipient(
6721                    app, pid, thread);
6722            thread.asBinder().linkToDeath(adr, 0);
6723            app.deathRecipient = adr;
6724        } catch (RemoteException e) {
6725            app.resetPackageList(mProcessStats);
6726            startProcessLocked(app, "link fail", processName);
6727            return false;
6728        }
6729
6730        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6731
6732        app.makeActive(thread, mProcessStats);
6733        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6734        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6735        app.forcingToImportant = null;
6736        updateProcessForegroundLocked(app, false, false);
6737        app.hasShownUi = false;
6738        app.debugging = false;
6739        app.cached = false;
6740        app.killedByAm = false;
6741        app.killed = false;
6742
6743
6744        // We carefully use the same state that PackageManager uses for
6745        // filtering, since we use this flag to decide if we need to install
6746        // providers when user is unlocked later
6747        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6748
6749        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6750
6751        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6752        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6753
6754        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6755            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6756            msg.obj = app;
6757            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6758        }
6759
6760        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6761
6762        if (!normalMode) {
6763            Slog.i(TAG, "Launching preboot mode app: " + app);
6764        }
6765
6766        if (DEBUG_ALL) Slog.v(
6767            TAG, "New app record " + app
6768            + " thread=" + thread.asBinder() + " pid=" + pid);
6769        try {
6770            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6771            if (mDebugApp != null && mDebugApp.equals(processName)) {
6772                testMode = mWaitForDebugger
6773                    ? ApplicationThreadConstants.DEBUG_WAIT
6774                    : ApplicationThreadConstants.DEBUG_ON;
6775                app.debugging = true;
6776                if (mDebugTransient) {
6777                    mDebugApp = mOrigDebugApp;
6778                    mWaitForDebugger = mOrigWaitForDebugger;
6779                }
6780            }
6781            String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6782            ParcelFileDescriptor profileFd = null;
6783            int samplingInterval = 0;
6784            boolean profileAutoStop = false;
6785            boolean profileStreamingOutput = false;
6786            if (mProfileApp != null && mProfileApp.equals(processName)) {
6787                mProfileProc = app;
6788                profileFile = mProfileFile;
6789                profileFd = mProfileFd;
6790                samplingInterval = mSamplingInterval;
6791                profileAutoStop = mAutoStopProfiler;
6792                profileStreamingOutput = mStreamingOutput;
6793            }
6794            boolean enableTrackAllocation = false;
6795            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6796                enableTrackAllocation = true;
6797                mTrackAllocationApp = null;
6798            }
6799
6800            // If the app is being launched for restore or full backup, set it up specially
6801            boolean isRestrictedBackupMode = false;
6802            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6803                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6804                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6805                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6806                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6807            }
6808
6809            if (app.instr != null) {
6810                notifyPackageUse(app.instr.mClass.getPackageName(),
6811                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6812            }
6813            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6814                    + processName + " with config " + getGlobalConfiguration());
6815            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6816            app.compat = compatibilityInfoForPackageLocked(appInfo);
6817            if (profileFd != null) {
6818                profileFd = profileFd.dup();
6819            }
6820            ProfilerInfo profilerInfo = profileFile == null ? null
6821                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6822                                       profileStreamingOutput);
6823
6824            // We deprecated Build.SERIAL and it is not accessible to
6825            // apps that target the v2 security sandbox. Since access to
6826            // the serial is now behind a permission we push down the value.
6827            String buildSerial = Build.UNKNOWN;
6828            if (appInfo.targetSandboxVersion != 2) {
6829                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6830                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6831                        .getSerial();
6832            }
6833
6834            // Check if this is a secondary process that should be incorporated into some
6835            // currently active instrumentation.  (Note we do this AFTER all of the profiling
6836            // stuff above because profiling can currently happen only in the primary
6837            // instrumentation process.)
6838            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6839                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6840                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6841                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6842                        if (aInstr.mTargetProcesses.length == 0) {
6843                            // This is the wildcard mode, where every process brought up for
6844                            // the target instrumentation should be included.
6845                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6846                                app.instr = aInstr;
6847                                aInstr.mRunningProcesses.add(app);
6848                            }
6849                        } else {
6850                            for (String proc : aInstr.mTargetProcesses) {
6851                                if (proc.equals(app.processName)) {
6852                                    app.instr = aInstr;
6853                                    aInstr.mRunningProcesses.add(app);
6854                                    break;
6855                                }
6856                            }
6857                        }
6858                    }
6859                }
6860            }
6861
6862            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6863            mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
6864            if (app.instr != null) {
6865                thread.bindApplication(processName, appInfo, providers,
6866                        app.instr.mClass,
6867                        profilerInfo, app.instr.mArguments,
6868                        app.instr.mWatcher,
6869                        app.instr.mUiAutomationConnection, testMode,
6870                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6871                        isRestrictedBackupMode || !normalMode, app.persistent,
6872                        new Configuration(getGlobalConfiguration()), app.compat,
6873                        getCommonServicesLocked(app.isolated),
6874                        mCoreSettingsObserver.getCoreSettingsLocked(),
6875                        buildSerial);
6876            } else {
6877                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6878                        null, null, null, testMode,
6879                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6880                        isRestrictedBackupMode || !normalMode, app.persistent,
6881                        new Configuration(getGlobalConfiguration()), app.compat,
6882                        getCommonServicesLocked(app.isolated),
6883                        mCoreSettingsObserver.getCoreSettingsLocked(),
6884                        buildSerial);
6885            }
6886
6887            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6888            updateLruProcessLocked(app, false, null);
6889            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6890            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6891        } catch (Exception e) {
6892            // todo: Yikes!  What should we do?  For now we will try to
6893            // start another process, but that could easily get us in
6894            // an infinite loop of restarting processes...
6895            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6896
6897            app.resetPackageList(mProcessStats);
6898            app.unlinkDeathRecipient();
6899            startProcessLocked(app, "bind fail", processName);
6900            return false;
6901        }
6902
6903        // Remove this record from the list of starting applications.
6904        mPersistentStartingProcesses.remove(app);
6905        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6906                "Attach application locked removing on hold: " + app);
6907        mProcessesOnHold.remove(app);
6908
6909        boolean badApp = false;
6910        boolean didSomething = false;
6911
6912        // See if the top visible activity is waiting to run in this process...
6913        if (normalMode) {
6914            try {
6915                if (mStackSupervisor.attachApplicationLocked(app)) {
6916                    didSomething = true;
6917                }
6918            } catch (Exception e) {
6919                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6920                badApp = true;
6921            }
6922        }
6923
6924        // Find any services that should be running in this process...
6925        if (!badApp) {
6926            try {
6927                didSomething |= mServices.attachApplicationLocked(app, processName);
6928                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6929            } catch (Exception e) {
6930                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6931                badApp = true;
6932            }
6933        }
6934
6935        // Check if a next-broadcast receiver is in this process...
6936        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6937            try {
6938                didSomething |= sendPendingBroadcastsLocked(app);
6939                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6940            } catch (Exception e) {
6941                // If the app died trying to launch the receiver we declare it 'bad'
6942                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6943                badApp = true;
6944            }
6945        }
6946
6947        // Check whether the next backup agent is in this process...
6948        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
6949            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6950                    "New app is backup target, launching agent for " + app);
6951            notifyPackageUse(mBackupTarget.appInfo.packageName,
6952                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6953            try {
6954                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6955                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6956                        mBackupTarget.backupMode);
6957            } catch (Exception e) {
6958                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6959                badApp = true;
6960            }
6961        }
6962
6963        if (badApp) {
6964            app.kill("error during init", true);
6965            handleAppDiedLocked(app, false, true);
6966            return false;
6967        }
6968
6969        if (!didSomething) {
6970            updateOomAdjLocked();
6971            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6972        }
6973
6974        return true;
6975    }
6976
6977    @Override
6978    public final void attachApplication(IApplicationThread thread) {
6979        synchronized (this) {
6980            int callingPid = Binder.getCallingPid();
6981            final long origId = Binder.clearCallingIdentity();
6982            attachApplicationLocked(thread, callingPid);
6983            Binder.restoreCallingIdentity(origId);
6984        }
6985    }
6986
6987    @Override
6988    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6989        final long origId = Binder.clearCallingIdentity();
6990        synchronized (this) {
6991            ActivityStack stack = ActivityRecord.getStackLocked(token);
6992            if (stack != null) {
6993                ActivityRecord r =
6994                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
6995                                false /* processPausingActivities */, config);
6996                if (stopProfiling) {
6997                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6998                        try {
6999                            mProfileFd.close();
7000                        } catch (IOException e) {
7001                        }
7002                        clearProfilerLocked();
7003                    }
7004                }
7005            }
7006        }
7007        Binder.restoreCallingIdentity(origId);
7008    }
7009
7010    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7011        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7012                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7013    }
7014
7015    void enableScreenAfterBoot() {
7016        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7017                SystemClock.uptimeMillis());
7018        mWindowManager.enableScreenAfterBoot();
7019
7020        synchronized (this) {
7021            updateEventDispatchingLocked();
7022        }
7023    }
7024
7025    @Override
7026    public void showBootMessage(final CharSequence msg, final boolean always) {
7027        if (Binder.getCallingUid() != myUid()) {
7028            throw new SecurityException();
7029        }
7030        mWindowManager.showBootMessage(msg, always);
7031    }
7032
7033    @Override
7034    public void keyguardGoingAway(int flags) {
7035        enforceNotIsolatedCaller("keyguardGoingAway");
7036        final long token = Binder.clearCallingIdentity();
7037        try {
7038            synchronized (this) {
7039                mKeyguardController.keyguardGoingAway(flags);
7040            }
7041        } finally {
7042            Binder.restoreCallingIdentity(token);
7043        }
7044    }
7045
7046    /**
7047     * @return whther the keyguard is currently locked.
7048     */
7049    boolean isKeyguardLocked() {
7050        return mKeyguardController.isKeyguardLocked();
7051    }
7052
7053    final void finishBooting() {
7054        synchronized (this) {
7055            if (!mBootAnimationComplete) {
7056                mCallFinishBooting = true;
7057                return;
7058            }
7059            mCallFinishBooting = false;
7060        }
7061
7062        ArraySet<String> completedIsas = new ArraySet<String>();
7063        for (String abi : Build.SUPPORTED_ABIS) {
7064            zygoteProcess.establishZygoteConnectionForAbi(abi);
7065            final String instructionSet = VMRuntime.getInstructionSet(abi);
7066            if (!completedIsas.contains(instructionSet)) {
7067                try {
7068                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7069                } catch (InstallerException e) {
7070                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7071                            e.getMessage() +")");
7072                }
7073                completedIsas.add(instructionSet);
7074            }
7075        }
7076
7077        IntentFilter pkgFilter = new IntentFilter();
7078        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7079        pkgFilter.addDataScheme("package");
7080        mContext.registerReceiver(new BroadcastReceiver() {
7081            @Override
7082            public void onReceive(Context context, Intent intent) {
7083                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7084                if (pkgs != null) {
7085                    for (String pkg : pkgs) {
7086                        synchronized (ActivityManagerService.this) {
7087                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7088                                    0, "query restart")) {
7089                                setResultCode(Activity.RESULT_OK);
7090                                return;
7091                            }
7092                        }
7093                    }
7094                }
7095            }
7096        }, pkgFilter);
7097
7098        IntentFilter dumpheapFilter = new IntentFilter();
7099        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7100        mContext.registerReceiver(new BroadcastReceiver() {
7101            @Override
7102            public void onReceive(Context context, Intent intent) {
7103                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7104                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7105                } else {
7106                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7107                }
7108            }
7109        }, dumpheapFilter);
7110
7111        // Let system services know.
7112        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7113
7114        synchronized (this) {
7115            // Ensure that any processes we had put on hold are now started
7116            // up.
7117            final int NP = mProcessesOnHold.size();
7118            if (NP > 0) {
7119                ArrayList<ProcessRecord> procs =
7120                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7121                for (int ip=0; ip<NP; ip++) {
7122                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7123                            + procs.get(ip));
7124                    startProcessLocked(procs.get(ip), "on-hold", null);
7125                }
7126            }
7127
7128            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7129                // Start looking for apps that are abusing wake locks.
7130                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7131                mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
7132                // Tell anyone interested that we are done booting!
7133                SystemProperties.set("sys.boot_completed", "1");
7134
7135                // And trigger dev.bootcomplete if we are not showing encryption progress
7136                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7137                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7138                    SystemProperties.set("dev.bootcomplete", "1");
7139                }
7140                mUserController.sendBootCompletedLocked(
7141                        new IIntentReceiver.Stub() {
7142                            @Override
7143                            public void performReceive(Intent intent, int resultCode,
7144                                    String data, Bundle extras, boolean ordered,
7145                                    boolean sticky, int sendingUser) {
7146                                synchronized (ActivityManagerService.this) {
7147                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7148                                            true, false);
7149                                }
7150                            }
7151                        });
7152                scheduleStartProfilesLocked();
7153            }
7154        }
7155    }
7156
7157    @Override
7158    public void bootAnimationComplete() {
7159        final boolean callFinishBooting;
7160        synchronized (this) {
7161            callFinishBooting = mCallFinishBooting;
7162            mBootAnimationComplete = true;
7163        }
7164        if (callFinishBooting) {
7165            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7166            finishBooting();
7167            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7168        }
7169    }
7170
7171    final void ensureBootCompleted() {
7172        boolean booting;
7173        boolean enableScreen;
7174        synchronized (this) {
7175            booting = mBooting;
7176            mBooting = false;
7177            enableScreen = !mBooted;
7178            mBooted = true;
7179        }
7180
7181        if (booting) {
7182            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7183            finishBooting();
7184            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7185        }
7186
7187        if (enableScreen) {
7188            enableScreenAfterBoot();
7189        }
7190    }
7191
7192    @Override
7193    public final void activityResumed(IBinder token) {
7194        final long origId = Binder.clearCallingIdentity();
7195        synchronized(this) {
7196            ActivityRecord.activityResumedLocked(token);
7197            mWindowManager.notifyAppResumedFinished(token);
7198        }
7199        Binder.restoreCallingIdentity(origId);
7200    }
7201
7202    @Override
7203    public final void activityPaused(IBinder token) {
7204        final long origId = Binder.clearCallingIdentity();
7205        synchronized(this) {
7206            ActivityStack stack = ActivityRecord.getStackLocked(token);
7207            if (stack != null) {
7208                stack.activityPausedLocked(token, false);
7209            }
7210        }
7211        Binder.restoreCallingIdentity(origId);
7212    }
7213
7214    @Override
7215    public final void activityStopped(IBinder token, Bundle icicle,
7216            PersistableBundle persistentState, CharSequence description) {
7217        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7218
7219        // Refuse possible leaked file descriptors
7220        if (icicle != null && icicle.hasFileDescriptors()) {
7221            throw new IllegalArgumentException("File descriptors passed in Bundle");
7222        }
7223
7224        final long origId = Binder.clearCallingIdentity();
7225
7226        synchronized (this) {
7227            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7228            if (r != null) {
7229                r.activityStoppedLocked(icicle, persistentState, description);
7230            }
7231        }
7232
7233        trimApplications();
7234
7235        Binder.restoreCallingIdentity(origId);
7236    }
7237
7238    @Override
7239    public final void activityDestroyed(IBinder token) {
7240        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7241        synchronized (this) {
7242            ActivityStack stack = ActivityRecord.getStackLocked(token);
7243            if (stack != null) {
7244                stack.activityDestroyedLocked(token, "activityDestroyed");
7245            }
7246        }
7247    }
7248
7249    @Override
7250    public final void activityRelaunched(IBinder token) {
7251        final long origId = Binder.clearCallingIdentity();
7252        synchronized (this) {
7253            mStackSupervisor.activityRelaunchedLocked(token);
7254        }
7255        Binder.restoreCallingIdentity(origId);
7256    }
7257
7258    @Override
7259    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7260            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7261        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7262                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7263        synchronized (this) {
7264            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7265            if (record == null) {
7266                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7267                        + "found for: " + token);
7268            }
7269            record.setSizeConfigurations(horizontalSizeConfiguration,
7270                    verticalSizeConfigurations, smallestSizeConfigurations);
7271        }
7272    }
7273
7274    @Override
7275    public final void backgroundResourcesReleased(IBinder token) {
7276        final long origId = Binder.clearCallingIdentity();
7277        try {
7278            synchronized (this) {
7279                ActivityStack stack = ActivityRecord.getStackLocked(token);
7280                if (stack != null) {
7281                    stack.backgroundResourcesReleased();
7282                }
7283            }
7284        } finally {
7285            Binder.restoreCallingIdentity(origId);
7286        }
7287    }
7288
7289    @Override
7290    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7291        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7292    }
7293
7294    @Override
7295    public final void notifyEnterAnimationComplete(IBinder token) {
7296        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7297    }
7298
7299    @Override
7300    public String getCallingPackage(IBinder token) {
7301        synchronized (this) {
7302            ActivityRecord r = getCallingRecordLocked(token);
7303            return r != null ? r.info.packageName : null;
7304        }
7305    }
7306
7307    @Override
7308    public ComponentName getCallingActivity(IBinder token) {
7309        synchronized (this) {
7310            ActivityRecord r = getCallingRecordLocked(token);
7311            return r != null ? r.intent.getComponent() : null;
7312        }
7313    }
7314
7315    private ActivityRecord getCallingRecordLocked(IBinder token) {
7316        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7317        if (r == null) {
7318            return null;
7319        }
7320        return r.resultTo;
7321    }
7322
7323    @Override
7324    public ComponentName getActivityClassForToken(IBinder token) {
7325        synchronized(this) {
7326            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7327            if (r == null) {
7328                return null;
7329            }
7330            return r.intent.getComponent();
7331        }
7332    }
7333
7334    @Override
7335    public String getPackageForToken(IBinder token) {
7336        synchronized(this) {
7337            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7338            if (r == null) {
7339                return null;
7340            }
7341            return r.packageName;
7342        }
7343    }
7344
7345    @Override
7346    public boolean isRootVoiceInteraction(IBinder token) {
7347        synchronized(this) {
7348            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7349            if (r == null) {
7350                return false;
7351            }
7352            return r.rootVoiceInteraction;
7353        }
7354    }
7355
7356    @Override
7357    public IIntentSender getIntentSender(int type,
7358            String packageName, IBinder token, String resultWho,
7359            int requestCode, Intent[] intents, String[] resolvedTypes,
7360            int flags, Bundle bOptions, int userId) {
7361        enforceNotIsolatedCaller("getIntentSender");
7362        // Refuse possible leaked file descriptors
7363        if (intents != null) {
7364            if (intents.length < 1) {
7365                throw new IllegalArgumentException("Intents array length must be >= 1");
7366            }
7367            for (int i=0; i<intents.length; i++) {
7368                Intent intent = intents[i];
7369                if (intent != null) {
7370                    if (intent.hasFileDescriptors()) {
7371                        throw new IllegalArgumentException("File descriptors passed in Intent");
7372                    }
7373                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7374                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7375                        throw new IllegalArgumentException(
7376                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7377                    }
7378                    intents[i] = new Intent(intent);
7379                }
7380            }
7381            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7382                throw new IllegalArgumentException(
7383                        "Intent array length does not match resolvedTypes length");
7384            }
7385        }
7386        if (bOptions != null) {
7387            if (bOptions.hasFileDescriptors()) {
7388                throw new IllegalArgumentException("File descriptors passed in options");
7389            }
7390        }
7391
7392        synchronized(this) {
7393            int callingUid = Binder.getCallingUid();
7394            int origUserId = userId;
7395            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7396                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7397                    ALLOW_NON_FULL, "getIntentSender", null);
7398            if (origUserId == UserHandle.USER_CURRENT) {
7399                // We don't want to evaluate this until the pending intent is
7400                // actually executed.  However, we do want to always do the
7401                // security checking for it above.
7402                userId = UserHandle.USER_CURRENT;
7403            }
7404            try {
7405                if (callingUid != 0 && callingUid != SYSTEM_UID) {
7406                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7407                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7408                    if (!UserHandle.isSameApp(callingUid, uid)) {
7409                        String msg = "Permission Denial: getIntentSender() from pid="
7410                            + Binder.getCallingPid()
7411                            + ", uid=" + Binder.getCallingUid()
7412                            + ", (need uid=" + uid + ")"
7413                            + " is not allowed to send as package " + packageName;
7414                        Slog.w(TAG, msg);
7415                        throw new SecurityException(msg);
7416                    }
7417                }
7418
7419                return getIntentSenderLocked(type, packageName, callingUid, userId,
7420                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7421
7422            } catch (RemoteException e) {
7423                throw new SecurityException(e);
7424            }
7425        }
7426    }
7427
7428    IIntentSender getIntentSenderLocked(int type, String packageName,
7429            int callingUid, int userId, IBinder token, String resultWho,
7430            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7431            Bundle bOptions) {
7432        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7433        ActivityRecord activity = null;
7434        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7435            activity = ActivityRecord.isInStackLocked(token);
7436            if (activity == null) {
7437                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7438                return null;
7439            }
7440            if (activity.finishing) {
7441                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7442                return null;
7443            }
7444        }
7445
7446        // We're going to be splicing together extras before sending, so we're
7447        // okay poking into any contained extras.
7448        if (intents != null) {
7449            for (int i = 0; i < intents.length; i++) {
7450                intents[i].setDefusable(true);
7451            }
7452        }
7453        Bundle.setDefusable(bOptions, true);
7454
7455        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7456        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7457        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7458        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7459                |PendingIntent.FLAG_UPDATE_CURRENT);
7460
7461        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7462                type, packageName, activity, resultWho,
7463                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7464        WeakReference<PendingIntentRecord> ref;
7465        ref = mIntentSenderRecords.get(key);
7466        PendingIntentRecord rec = ref != null ? ref.get() : null;
7467        if (rec != null) {
7468            if (!cancelCurrent) {
7469                if (updateCurrent) {
7470                    if (rec.key.requestIntent != null) {
7471                        rec.key.requestIntent.replaceExtras(intents != null ?
7472                                intents[intents.length - 1] : null);
7473                    }
7474                    if (intents != null) {
7475                        intents[intents.length-1] = rec.key.requestIntent;
7476                        rec.key.allIntents = intents;
7477                        rec.key.allResolvedTypes = resolvedTypes;
7478                    } else {
7479                        rec.key.allIntents = null;
7480                        rec.key.allResolvedTypes = null;
7481                    }
7482                }
7483                return rec;
7484            }
7485            makeIntentSenderCanceledLocked(rec);
7486            mIntentSenderRecords.remove(key);
7487        }
7488        if (noCreate) {
7489            return rec;
7490        }
7491        rec = new PendingIntentRecord(this, key, callingUid);
7492        mIntentSenderRecords.put(key, rec.ref);
7493        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7494            if (activity.pendingResults == null) {
7495                activity.pendingResults
7496                        = new HashSet<WeakReference<PendingIntentRecord>>();
7497            }
7498            activity.pendingResults.add(rec.ref);
7499        }
7500        return rec;
7501    }
7502
7503    @Override
7504    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7505            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7506        if (target instanceof PendingIntentRecord) {
7507            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7508                    finishedReceiver, requiredPermission, options);
7509        } else {
7510            if (intent == null) {
7511                // Weird case: someone has given us their own custom IIntentSender, and now
7512                // they have someone else trying to send to it but of course this isn't
7513                // really a PendingIntent, so there is no base Intent, and the caller isn't
7514                // supplying an Intent... but we never want to dispatch a null Intent to
7515                // a receiver, so um...  let's make something up.
7516                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7517                intent = new Intent(Intent.ACTION_MAIN);
7518            }
7519            try {
7520                target.send(code, intent, resolvedType, null, requiredPermission, options);
7521            } catch (RemoteException e) {
7522            }
7523            // Platform code can rely on getting a result back when the send is done, but if
7524            // this intent sender is from outside of the system we can't rely on it doing that.
7525            // So instead we don't give it the result receiver, and instead just directly
7526            // report the finish immediately.
7527            if (finishedReceiver != null) {
7528                try {
7529                    finishedReceiver.performReceive(intent, 0,
7530                            null, null, false, false, UserHandle.getCallingUserId());
7531                } catch (RemoteException e) {
7532                }
7533            }
7534            return 0;
7535        }
7536    }
7537
7538    @Override
7539    public void cancelIntentSender(IIntentSender sender) {
7540        if (!(sender instanceof PendingIntentRecord)) {
7541            return;
7542        }
7543        synchronized(this) {
7544            PendingIntentRecord rec = (PendingIntentRecord)sender;
7545            try {
7546                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7547                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7548                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7549                    String msg = "Permission Denial: cancelIntentSender() from pid="
7550                        + Binder.getCallingPid()
7551                        + ", uid=" + Binder.getCallingUid()
7552                        + " is not allowed to cancel package "
7553                        + rec.key.packageName;
7554                    Slog.w(TAG, msg);
7555                    throw new SecurityException(msg);
7556                }
7557            } catch (RemoteException e) {
7558                throw new SecurityException(e);
7559            }
7560            cancelIntentSenderLocked(rec, true);
7561        }
7562    }
7563
7564    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7565        makeIntentSenderCanceledLocked(rec);
7566        mIntentSenderRecords.remove(rec.key);
7567        if (cleanActivity && rec.key.activity != null) {
7568            rec.key.activity.pendingResults.remove(rec.ref);
7569        }
7570    }
7571
7572    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7573        rec.canceled = true;
7574        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7575        if (callbacks != null) {
7576            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7577        }
7578    }
7579
7580    @Override
7581    public String getPackageForIntentSender(IIntentSender pendingResult) {
7582        if (!(pendingResult instanceof PendingIntentRecord)) {
7583            return null;
7584        }
7585        try {
7586            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7587            return res.key.packageName;
7588        } catch (ClassCastException e) {
7589        }
7590        return null;
7591    }
7592
7593    @Override
7594    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7595        if (!(sender instanceof PendingIntentRecord)) {
7596            return;
7597        }
7598        synchronized(this) {
7599            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7600        }
7601    }
7602
7603    @Override
7604    public void unregisterIntentSenderCancelListener(IIntentSender sender,
7605            IResultReceiver receiver) {
7606        if (!(sender instanceof PendingIntentRecord)) {
7607            return;
7608        }
7609        synchronized(this) {
7610            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7611        }
7612    }
7613
7614    @Override
7615    public int getUidForIntentSender(IIntentSender sender) {
7616        if (sender instanceof PendingIntentRecord) {
7617            try {
7618                PendingIntentRecord res = (PendingIntentRecord)sender;
7619                return res.uid;
7620            } catch (ClassCastException e) {
7621            }
7622        }
7623        return -1;
7624    }
7625
7626    @Override
7627    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7628        if (!(pendingResult instanceof PendingIntentRecord)) {
7629            return false;
7630        }
7631        try {
7632            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7633            if (res.key.allIntents == null) {
7634                return false;
7635            }
7636            for (int i=0; i<res.key.allIntents.length; i++) {
7637                Intent intent = res.key.allIntents[i];
7638                if (intent.getPackage() != null && intent.getComponent() != null) {
7639                    return false;
7640                }
7641            }
7642            return true;
7643        } catch (ClassCastException e) {
7644        }
7645        return false;
7646    }
7647
7648    @Override
7649    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7650        if (!(pendingResult instanceof PendingIntentRecord)) {
7651            return false;
7652        }
7653        try {
7654            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7655            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7656                return true;
7657            }
7658            return false;
7659        } catch (ClassCastException e) {
7660        }
7661        return false;
7662    }
7663
7664    @Override
7665    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7666        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7667                "getIntentForIntentSender()");
7668        if (!(pendingResult instanceof PendingIntentRecord)) {
7669            return null;
7670        }
7671        try {
7672            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7673            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7674        } catch (ClassCastException e) {
7675        }
7676        return null;
7677    }
7678
7679    @Override
7680    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7681        if (!(pendingResult instanceof PendingIntentRecord)) {
7682            return null;
7683        }
7684        try {
7685            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7686            synchronized (this) {
7687                return getTagForIntentSenderLocked(res, prefix);
7688            }
7689        } catch (ClassCastException e) {
7690        }
7691        return null;
7692    }
7693
7694    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7695        final Intent intent = res.key.requestIntent;
7696        if (intent != null) {
7697            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7698                    || res.lastTagPrefix.equals(prefix))) {
7699                return res.lastTag;
7700            }
7701            res.lastTagPrefix = prefix;
7702            final StringBuilder sb = new StringBuilder(128);
7703            if (prefix != null) {
7704                sb.append(prefix);
7705            }
7706            if (intent.getAction() != null) {
7707                sb.append(intent.getAction());
7708            } else if (intent.getComponent() != null) {
7709                intent.getComponent().appendShortString(sb);
7710            } else {
7711                sb.append("?");
7712            }
7713            return res.lastTag = sb.toString();
7714        }
7715        return null;
7716    }
7717
7718    @Override
7719    public void setProcessLimit(int max) {
7720        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7721                "setProcessLimit()");
7722        synchronized (this) {
7723            mConstants.setOverrideMaxCachedProcesses(max);
7724        }
7725        trimApplications();
7726    }
7727
7728    @Override
7729    public int getProcessLimit() {
7730        synchronized (this) {
7731            return mConstants.getOverrideMaxCachedProcesses();
7732        }
7733    }
7734
7735    void importanceTokenDied(ImportanceToken token) {
7736        synchronized (ActivityManagerService.this) {
7737            synchronized (mPidsSelfLocked) {
7738                ImportanceToken cur
7739                    = mImportantProcesses.get(token.pid);
7740                if (cur != token) {
7741                    return;
7742                }
7743                mImportantProcesses.remove(token.pid);
7744                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7745                if (pr == null) {
7746                    return;
7747                }
7748                pr.forcingToImportant = null;
7749                updateProcessForegroundLocked(pr, false, false);
7750            }
7751            updateOomAdjLocked();
7752        }
7753    }
7754
7755    @Override
7756    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7757        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7758                "setProcessImportant()");
7759        synchronized(this) {
7760            boolean changed = false;
7761
7762            synchronized (mPidsSelfLocked) {
7763                ProcessRecord pr = mPidsSelfLocked.get(pid);
7764                if (pr == null && isForeground) {
7765                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7766                    return;
7767                }
7768                ImportanceToken oldToken = mImportantProcesses.get(pid);
7769                if (oldToken != null) {
7770                    oldToken.token.unlinkToDeath(oldToken, 0);
7771                    mImportantProcesses.remove(pid);
7772                    if (pr != null) {
7773                        pr.forcingToImportant = null;
7774                    }
7775                    changed = true;
7776                }
7777                if (isForeground && token != null) {
7778                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7779                        @Override
7780                        public void binderDied() {
7781                            importanceTokenDied(this);
7782                        }
7783                    };
7784                    try {
7785                        token.linkToDeath(newToken, 0);
7786                        mImportantProcesses.put(pid, newToken);
7787                        pr.forcingToImportant = newToken;
7788                        changed = true;
7789                    } catch (RemoteException e) {
7790                        // If the process died while doing this, we will later
7791                        // do the cleanup with the process death link.
7792                    }
7793                }
7794            }
7795
7796            if (changed) {
7797                updateOomAdjLocked();
7798            }
7799        }
7800    }
7801
7802    @Override
7803    public boolean isAppForeground(int uid) throws RemoteException {
7804        synchronized (this) {
7805            UidRecord uidRec = mActiveUids.get(uid);
7806            if (uidRec == null || uidRec.idle) {
7807                return false;
7808            }
7809            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7810        }
7811    }
7812
7813    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7814    // be guarded by permission checking.
7815    int getUidState(int uid) {
7816        synchronized (this) {
7817            UidRecord uidRec = mActiveUids.get(uid);
7818            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7819        }
7820    }
7821
7822    @Override
7823    public boolean isInMultiWindowMode(IBinder token) {
7824        final long origId = Binder.clearCallingIdentity();
7825        try {
7826            synchronized(this) {
7827                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7828                if (r == null) {
7829                    return false;
7830                }
7831                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7832                return !r.getTask().mFullscreen;
7833            }
7834        } finally {
7835            Binder.restoreCallingIdentity(origId);
7836        }
7837    }
7838
7839    @Override
7840    public boolean isInPictureInPictureMode(IBinder token) {
7841        final long origId = Binder.clearCallingIdentity();
7842        try {
7843            synchronized(this) {
7844                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
7845            }
7846        } finally {
7847            Binder.restoreCallingIdentity(origId);
7848        }
7849    }
7850
7851    private boolean isInPictureInPictureMode(ActivityRecord r) {
7852        if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
7853                r.getStack().isInStackLocked(r) == null) {
7854            return false;
7855        }
7856
7857        // If we are animating to fullscreen then we have already dispatched the PIP mode
7858        // changed, so we should reflect that check here as well.
7859        final PinnedActivityStack stack = r.getStack();
7860        final PinnedStackWindowController windowController = stack.getWindowContainerController();
7861        return !windowController.isAnimatingBoundsToFullscreen();
7862    }
7863
7864    @Override
7865    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
7866        final long origId = Binder.clearCallingIdentity();
7867        try {
7868            synchronized(this) {
7869                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
7870                        "enterPictureInPictureMode", token, params);
7871
7872                // If the activity is already in picture in picture mode, then just return early
7873                if (isInPictureInPictureMode(r)) {
7874                    return true;
7875                }
7876
7877                // Activity supports picture-in-picture, now check that we can enter PiP at this
7878                // point, if it is
7879                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7880                        false /* noThrow */, false /* beforeStopping */)) {
7881                    return false;
7882                }
7883
7884                final Runnable enterPipRunnable = () -> {
7885                    // Only update the saved args from the args that are set
7886                    r.pictureInPictureArgs.copyOnlySet(params);
7887                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
7888                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
7889                    // Adjust the source bounds by the insets for the transition down
7890                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
7891                    final Rect insets = r.pictureInPictureArgs.getSourceRectHintInsets();
7892                    if (insets != null) {
7893                        sourceBounds.offsetTo(Math.max(0, sourceBounds.left - insets.left),
7894                                Math.max(0, sourceBounds.top - insets.top));
7895                    }
7896
7897                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
7898                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
7899                    final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
7900                    stack.setPictureInPictureAspectRatio(aspectRatio);
7901                    stack.setPictureInPictureActions(actions);
7902
7903                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
7904                            r.supportsPictureInPictureWhilePausing);
7905                    logPictureInPictureArgs(params);
7906                };
7907
7908                if (isKeyguardLocked()) {
7909                    // If the keyguard is showing or occluded, then try and dismiss it before
7910                    // entering picture-in-picture (this will prompt the user to authenticate if the
7911                    // device is currently locked).
7912                    try {
7913                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7914                            @Override
7915                            public void onDismissError() throws RemoteException {
7916                                // Do nothing
7917                            }
7918
7919                            @Override
7920                            public void onDismissSucceeded() throws RemoteException {
7921                                mHandler.post(enterPipRunnable);
7922                            }
7923
7924                            @Override
7925                            public void onDismissCancelled() throws RemoteException {
7926                                // Do nothing
7927                            }
7928                        });
7929                    } catch (RemoteException e) {
7930                        // Local call
7931                    }
7932                } else {
7933                    // Enter picture in picture immediately otherwise
7934                    enterPipRunnable.run();
7935                }
7936                return true;
7937            }
7938        } finally {
7939            Binder.restoreCallingIdentity(origId);
7940        }
7941    }
7942
7943    @Override
7944    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
7945        final long origId = Binder.clearCallingIdentity();
7946        try {
7947            synchronized(this) {
7948                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
7949                        "setPictureInPictureParams", token, params);
7950
7951                // Only update the saved args from the args that are set
7952                r.pictureInPictureArgs.copyOnlySet(params);
7953                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7954                    // If the activity is already in picture-in-picture, update the pinned stack now
7955                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
7956                    // be used the next time the activity enters PiP
7957                    final PinnedActivityStack stack = r.getStack();
7958                    if (!stack.isAnimatingBoundsToFullscreen()) {
7959                        stack.setPictureInPictureAspectRatio(
7960                                r.pictureInPictureArgs.getAspectRatio());
7961                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
7962                    }
7963                }
7964                logPictureInPictureArgs(params);
7965            }
7966        } finally {
7967            Binder.restoreCallingIdentity(origId);
7968        }
7969    }
7970
7971    @Override
7972    public int getMaxNumPictureInPictureActions(IBinder token) {
7973        // Currently, this is a static constant, but later, we may change this to be dependent on
7974        // the context of the activity
7975        return 3;
7976    }
7977
7978    private void logPictureInPictureArgs(PictureInPictureParams params) {
7979        if (params.hasSetActions()) {
7980            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
7981                    params.getActions().size());
7982        }
7983        if (params.hasSetAspectRatio()) {
7984            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
7985            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
7986            MetricsLogger.action(lm);
7987        }
7988    }
7989
7990    /**
7991     * Checks the state of the system and the activity associated with the given {@param token} to
7992     * verify that picture-in-picture is supported for that activity.
7993     *
7994     * @return the activity record for the given {@param token} if all the checks pass.
7995     */
7996    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
7997            IBinder token, PictureInPictureParams params) {
7998        if (!mSupportsPictureInPicture) {
7999            throw new IllegalStateException(caller
8000                    + ": Device doesn't support picture-in-picture mode.");
8001        }
8002
8003        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8004        if (r == null) {
8005            throw new IllegalStateException(caller
8006                    + ": Can't find activity for token=" + token);
8007        }
8008
8009        if (!r.supportsPictureInPicture()) {
8010            throw new IllegalStateException(caller
8011                    + ": Current activity does not support picture-in-picture.");
8012        }
8013
8014        if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8015            throw new IllegalStateException(caller
8016                    + ": Activities on the home, assistant, or recents stack not supported");
8017        }
8018
8019        if (params.hasSetAspectRatio()
8020                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8021                        params.getAspectRatio())) {
8022            final float minAspectRatio = mContext.getResources().getFloat(
8023                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8024            final float maxAspectRatio = mContext.getResources().getFloat(
8025                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8026            throw new IllegalArgumentException(String.format(caller
8027                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8028                            minAspectRatio, maxAspectRatio));
8029        }
8030
8031        // Truncate the number of actions if necessary
8032        params.truncateActions(getMaxNumPictureInPictureActions(token));
8033
8034        return r;
8035    }
8036
8037    // =========================================================
8038    // PROCESS INFO
8039    // =========================================================
8040
8041    static class ProcessInfoService extends IProcessInfoService.Stub {
8042        final ActivityManagerService mActivityManagerService;
8043        ProcessInfoService(ActivityManagerService activityManagerService) {
8044            mActivityManagerService = activityManagerService;
8045        }
8046
8047        @Override
8048        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8049            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8050                    /*in*/ pids, /*out*/ states, null);
8051        }
8052
8053        @Override
8054        public void getProcessStatesAndOomScoresFromPids(
8055                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8056            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8057                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8058        }
8059    }
8060
8061    /**
8062     * For each PID in the given input array, write the current process state
8063     * for that process into the states array, or -1 to indicate that no
8064     * process with the given PID exists. If scores array is provided, write
8065     * the oom score for the process into the scores array, with INVALID_ADJ
8066     * indicating the PID doesn't exist.
8067     */
8068    public void getProcessStatesAndOomScoresForPIDs(
8069            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8070        if (scores != null) {
8071            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8072                    "getProcessStatesAndOomScoresForPIDs()");
8073        }
8074
8075        if (pids == null) {
8076            throw new NullPointerException("pids");
8077        } else if (states == null) {
8078            throw new NullPointerException("states");
8079        } else if (pids.length != states.length) {
8080            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8081        } else if (scores != null && pids.length != scores.length) {
8082            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8083        }
8084
8085        synchronized (mPidsSelfLocked) {
8086            for (int i = 0; i < pids.length; i++) {
8087                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8088                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8089                        pr.curProcState;
8090                if (scores != null) {
8091                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8092                }
8093            }
8094        }
8095    }
8096
8097    // =========================================================
8098    // PERMISSIONS
8099    // =========================================================
8100
8101    static class PermissionController extends IPermissionController.Stub {
8102        ActivityManagerService mActivityManagerService;
8103        PermissionController(ActivityManagerService activityManagerService) {
8104            mActivityManagerService = activityManagerService;
8105        }
8106
8107        @Override
8108        public boolean checkPermission(String permission, int pid, int uid) {
8109            return mActivityManagerService.checkPermission(permission, pid,
8110                    uid) == PackageManager.PERMISSION_GRANTED;
8111        }
8112
8113        @Override
8114        public String[] getPackagesForUid(int uid) {
8115            return mActivityManagerService.mContext.getPackageManager()
8116                    .getPackagesForUid(uid);
8117        }
8118
8119        @Override
8120        public boolean isRuntimePermission(String permission) {
8121            try {
8122                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8123                        .getPermissionInfo(permission, 0);
8124                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8125                        == PermissionInfo.PROTECTION_DANGEROUS;
8126            } catch (NameNotFoundException nnfe) {
8127                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8128            }
8129            return false;
8130        }
8131    }
8132
8133    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8134        @Override
8135        public int checkComponentPermission(String permission, int pid, int uid,
8136                int owningUid, boolean exported) {
8137            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8138                    owningUid, exported);
8139        }
8140
8141        @Override
8142        public Object getAMSLock() {
8143            return ActivityManagerService.this;
8144        }
8145    }
8146
8147    /**
8148     * This can be called with or without the global lock held.
8149     */
8150    int checkComponentPermission(String permission, int pid, int uid,
8151            int owningUid, boolean exported) {
8152        if (pid == MY_PID) {
8153            return PackageManager.PERMISSION_GRANTED;
8154        }
8155        return ActivityManager.checkComponentPermission(permission, uid,
8156                owningUid, exported);
8157    }
8158
8159    /**
8160     * As the only public entry point for permissions checking, this method
8161     * can enforce the semantic that requesting a check on a null global
8162     * permission is automatically denied.  (Internally a null permission
8163     * string is used when calling {@link #checkComponentPermission} in cases
8164     * when only uid-based security is needed.)
8165     *
8166     * This can be called with or without the global lock held.
8167     */
8168    @Override
8169    public int checkPermission(String permission, int pid, int uid) {
8170        if (permission == null) {
8171            return PackageManager.PERMISSION_DENIED;
8172        }
8173        return checkComponentPermission(permission, pid, uid, -1, true);
8174    }
8175
8176    @Override
8177    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8178        if (permission == null) {
8179            return PackageManager.PERMISSION_DENIED;
8180        }
8181
8182        // We might be performing an operation on behalf of an indirect binder
8183        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8184        // client identity accordingly before proceeding.
8185        Identity tlsIdentity = sCallerIdentity.get();
8186        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8187            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8188                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8189            uid = tlsIdentity.uid;
8190            pid = tlsIdentity.pid;
8191        }
8192
8193        return checkComponentPermission(permission, pid, uid, -1, true);
8194    }
8195
8196    /**
8197     * Binder IPC calls go through the public entry point.
8198     * This can be called with or without the global lock held.
8199     */
8200    int checkCallingPermission(String permission) {
8201        return checkPermission(permission,
8202                Binder.getCallingPid(),
8203                UserHandle.getAppId(Binder.getCallingUid()));
8204    }
8205
8206    /**
8207     * This can be called with or without the global lock held.
8208     */
8209    void enforceCallingPermission(String permission, String func) {
8210        if (checkCallingPermission(permission)
8211                == PackageManager.PERMISSION_GRANTED) {
8212            return;
8213        }
8214
8215        String msg = "Permission Denial: " + func + " from pid="
8216                + Binder.getCallingPid()
8217                + ", uid=" + Binder.getCallingUid()
8218                + " requires " + permission;
8219        Slog.w(TAG, msg);
8220        throw new SecurityException(msg);
8221    }
8222
8223    /**
8224     * Determine if UID is holding permissions required to access {@link Uri} in
8225     * the given {@link ProviderInfo}. Final permission checking is always done
8226     * in {@link ContentProvider}.
8227     */
8228    private final boolean checkHoldingPermissionsLocked(
8229            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8230        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8231                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8232        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8233            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8234                    != PERMISSION_GRANTED) {
8235                return false;
8236            }
8237        }
8238        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8239    }
8240
8241    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8242            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8243        if (pi.applicationInfo.uid == uid) {
8244            return true;
8245        } else if (!pi.exported) {
8246            return false;
8247        }
8248
8249        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8250        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8251        try {
8252            // check if target holds top-level <provider> permissions
8253            if (!readMet && pi.readPermission != null && considerUidPermissions
8254                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8255                readMet = true;
8256            }
8257            if (!writeMet && pi.writePermission != null && considerUidPermissions
8258                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8259                writeMet = true;
8260            }
8261
8262            // track if unprotected read/write is allowed; any denied
8263            // <path-permission> below removes this ability
8264            boolean allowDefaultRead = pi.readPermission == null;
8265            boolean allowDefaultWrite = pi.writePermission == null;
8266
8267            // check if target holds any <path-permission> that match uri
8268            final PathPermission[] pps = pi.pathPermissions;
8269            if (pps != null) {
8270                final String path = grantUri.uri.getPath();
8271                int i = pps.length;
8272                while (i > 0 && (!readMet || !writeMet)) {
8273                    i--;
8274                    PathPermission pp = pps[i];
8275                    if (pp.match(path)) {
8276                        if (!readMet) {
8277                            final String pprperm = pp.getReadPermission();
8278                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8279                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8280                                    + ": match=" + pp.match(path)
8281                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8282                            if (pprperm != null) {
8283                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8284                                        == PERMISSION_GRANTED) {
8285                                    readMet = true;
8286                                } else {
8287                                    allowDefaultRead = false;
8288                                }
8289                            }
8290                        }
8291                        if (!writeMet) {
8292                            final String ppwperm = pp.getWritePermission();
8293                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8294                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8295                                    + ": match=" + pp.match(path)
8296                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8297                            if (ppwperm != null) {
8298                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8299                                        == PERMISSION_GRANTED) {
8300                                    writeMet = true;
8301                                } else {
8302                                    allowDefaultWrite = false;
8303                                }
8304                            }
8305                        }
8306                    }
8307                }
8308            }
8309
8310            // grant unprotected <provider> read/write, if not blocked by
8311            // <path-permission> above
8312            if (allowDefaultRead) readMet = true;
8313            if (allowDefaultWrite) writeMet = true;
8314
8315        } catch (RemoteException e) {
8316            return false;
8317        }
8318
8319        return readMet && writeMet;
8320    }
8321
8322    public boolean isAppStartModeDisabled(int uid, String packageName) {
8323        synchronized (this) {
8324            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8325                    == ActivityManager.APP_START_MODE_DISABLED;
8326        }
8327    }
8328
8329    // Unified app-op and target sdk check
8330    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8331        // Apps that target O+ are always subject to background check
8332        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8333            if (DEBUG_BACKGROUND_CHECK) {
8334                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8335            }
8336            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8337        }
8338        // ...and legacy apps get an AppOp check
8339        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8340                uid, packageName);
8341        if (DEBUG_BACKGROUND_CHECK) {
8342            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8343        }
8344        switch (appop) {
8345            case AppOpsManager.MODE_ALLOWED:
8346                return ActivityManager.APP_START_MODE_NORMAL;
8347            case AppOpsManager.MODE_IGNORED:
8348                return ActivityManager.APP_START_MODE_DELAYED;
8349            default:
8350                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8351        }
8352    }
8353
8354    // Service launch is available to apps with run-in-background exemptions but
8355    // some other background operations are not.  If we're doing a check
8356    // of service-launch policy, allow those callers to proceed unrestricted.
8357    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8358        // Persistent app?
8359        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8360            if (DEBUG_BACKGROUND_CHECK) {
8361                Slog.i(TAG, "App " + uid + "/" + packageName
8362                        + " is persistent; not restricted in background");
8363            }
8364            return ActivityManager.APP_START_MODE_NORMAL;
8365        }
8366
8367        // Non-persistent but background whitelisted?
8368        if (uidOnBackgroundWhitelist(uid)) {
8369            if (DEBUG_BACKGROUND_CHECK) {
8370                Slog.i(TAG, "App " + uid + "/" + packageName
8371                        + " on background whitelist; not restricted in background");
8372            }
8373            return ActivityManager.APP_START_MODE_NORMAL;
8374        }
8375
8376        // Is this app on the battery whitelist?
8377        if (isOnDeviceIdleWhitelistLocked(uid)) {
8378            if (DEBUG_BACKGROUND_CHECK) {
8379                Slog.i(TAG, "App " + uid + "/" + packageName
8380                        + " on idle whitelist; not restricted in background");
8381            }
8382            return ActivityManager.APP_START_MODE_NORMAL;
8383        }
8384
8385        // None of the service-policy criteria apply, so we apply the common criteria
8386        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8387    }
8388
8389    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8390            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8391        UidRecord uidRec = mActiveUids.get(uid);
8392        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8393                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8394                + (uidRec != null ? uidRec.idle : false));
8395        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8396            boolean ephemeral;
8397            if (uidRec == null) {
8398                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8399                        UserHandle.getUserId(uid), packageName);
8400            } else {
8401                ephemeral = uidRec.ephemeral;
8402            }
8403
8404            if (ephemeral) {
8405                // We are hard-core about ephemeral apps not running in the background.
8406                return ActivityManager.APP_START_MODE_DISABLED;
8407            } else {
8408                if (disabledOnly) {
8409                    // The caller is only interested in whether app starts are completely
8410                    // disabled for the given package (that is, it is an instant app).  So
8411                    // we don't need to go further, which is all just seeing if we should
8412                    // apply a "delayed" mode for a regular app.
8413                    return ActivityManager.APP_START_MODE_NORMAL;
8414                }
8415                final int startMode = (alwaysRestrict)
8416                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8417                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8418                                packageTargetSdk);
8419                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8420                        + " pkg=" + packageName + " startMode=" + startMode
8421                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8422                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8423                    // This is an old app that has been forced into a "compatible as possible"
8424                    // mode of background check.  To increase compatibility, we will allow other
8425                    // foreground apps to cause its services to start.
8426                    if (callingPid >= 0) {
8427                        ProcessRecord proc;
8428                        synchronized (mPidsSelfLocked) {
8429                            proc = mPidsSelfLocked.get(callingPid);
8430                        }
8431                        if (proc != null && proc.curProcState
8432                                < ActivityManager.PROCESS_STATE_RECEIVER) {
8433                            // Whoever is instigating this is in the foreground, so we will allow it
8434                            // to go through.
8435                            return ActivityManager.APP_START_MODE_NORMAL;
8436                        }
8437                    }
8438                }
8439                return startMode;
8440            }
8441        }
8442        return ActivityManager.APP_START_MODE_NORMAL;
8443    }
8444
8445    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8446        final int appId = UserHandle.getAppId(uid);
8447        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8448                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8449                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8450    }
8451
8452    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8453        ProviderInfo pi = null;
8454        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8455        if (cpr != null) {
8456            pi = cpr.info;
8457        } else {
8458            try {
8459                pi = AppGlobals.getPackageManager().resolveContentProvider(
8460                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8461                        userHandle);
8462            } catch (RemoteException ex) {
8463            }
8464        }
8465        return pi;
8466    }
8467
8468    void grantEphemeralAccessLocked(int userId, Intent intent,
8469            int targetAppId, int ephemeralAppId) {
8470        getPackageManagerInternalLocked().
8471                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8472    }
8473
8474    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8475        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8476        if (targetUris != null) {
8477            return targetUris.get(grantUri);
8478        }
8479        return null;
8480    }
8481
8482    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8483            String targetPkg, int targetUid, GrantUri grantUri) {
8484        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8485        if (targetUris == null) {
8486            targetUris = Maps.newArrayMap();
8487            mGrantedUriPermissions.put(targetUid, targetUris);
8488        }
8489
8490        UriPermission perm = targetUris.get(grantUri);
8491        if (perm == null) {
8492            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8493            targetUris.put(grantUri, perm);
8494        }
8495
8496        return perm;
8497    }
8498
8499    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8500            final int modeFlags) {
8501        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8502        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8503                : UriPermission.STRENGTH_OWNED;
8504
8505        // Root gets to do everything.
8506        if (uid == 0) {
8507            return true;
8508        }
8509
8510        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8511        if (perms == null) return false;
8512
8513        // First look for exact match
8514        final UriPermission exactPerm = perms.get(grantUri);
8515        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8516            return true;
8517        }
8518
8519        // No exact match, look for prefixes
8520        final int N = perms.size();
8521        for (int i = 0; i < N; i++) {
8522            final UriPermission perm = perms.valueAt(i);
8523            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8524                    && perm.getStrength(modeFlags) >= minStrength) {
8525                return true;
8526            }
8527        }
8528
8529        return false;
8530    }
8531
8532    /**
8533     * @param uri This uri must NOT contain an embedded userId.
8534     * @param userId The userId in which the uri is to be resolved.
8535     */
8536    @Override
8537    public int checkUriPermission(Uri uri, int pid, int uid,
8538            final int modeFlags, int userId, IBinder callerToken) {
8539        enforceNotIsolatedCaller("checkUriPermission");
8540
8541        // Another redirected-binder-call permissions check as in
8542        // {@link checkPermissionWithToken}.
8543        Identity tlsIdentity = sCallerIdentity.get();
8544        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8545            uid = tlsIdentity.uid;
8546            pid = tlsIdentity.pid;
8547        }
8548
8549        // Our own process gets to do everything.
8550        if (pid == MY_PID) {
8551            return PackageManager.PERMISSION_GRANTED;
8552        }
8553        synchronized (this) {
8554            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8555                    ? PackageManager.PERMISSION_GRANTED
8556                    : PackageManager.PERMISSION_DENIED;
8557        }
8558    }
8559
8560    /**
8561     * Check if the targetPkg can be granted permission to access uri by
8562     * the callingUid using the given modeFlags.  Throws a security exception
8563     * if callingUid is not allowed to do this.  Returns the uid of the target
8564     * if the URI permission grant should be performed; returns -1 if it is not
8565     * needed (for example targetPkg already has permission to access the URI).
8566     * If you already know the uid of the target, you can supply it in
8567     * lastTargetUid else set that to -1.
8568     */
8569    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8570            final int modeFlags, int lastTargetUid) {
8571        if (!Intent.isAccessUriMode(modeFlags)) {
8572            return -1;
8573        }
8574
8575        if (targetPkg != null) {
8576            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8577                    "Checking grant " + targetPkg + " permission to " + grantUri);
8578        }
8579
8580        final IPackageManager pm = AppGlobals.getPackageManager();
8581
8582        // If this is not a content: uri, we can't do anything with it.
8583        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8584            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8585                    "Can't grant URI permission for non-content URI: " + grantUri);
8586            return -1;
8587        }
8588
8589        final String authority = grantUri.uri.getAuthority();
8590        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8591                MATCH_DEBUG_TRIAGED_MISSING);
8592        if (pi == null) {
8593            Slog.w(TAG, "No content provider found for permission check: " +
8594                    grantUri.uri.toSafeString());
8595            return -1;
8596        }
8597
8598        int targetUid = lastTargetUid;
8599        if (targetUid < 0 && targetPkg != null) {
8600            try {
8601                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8602                        UserHandle.getUserId(callingUid));
8603                if (targetUid < 0) {
8604                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8605                            "Can't grant URI permission no uid for: " + targetPkg);
8606                    return -1;
8607                }
8608            } catch (RemoteException ex) {
8609                return -1;
8610            }
8611        }
8612
8613        // If we're extending a persistable grant, then we always need to create
8614        // the grant data structure so that take/release APIs work
8615        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8616            return targetUid;
8617        }
8618
8619        if (targetUid >= 0) {
8620            // First...  does the target actually need this permission?
8621            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8622                // No need to grant the target this permission.
8623                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8624                        "Target " + targetPkg + " already has full permission to " + grantUri);
8625                return -1;
8626            }
8627        } else {
8628            // First...  there is no target package, so can anyone access it?
8629            boolean allowed = pi.exported;
8630            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8631                if (pi.readPermission != null) {
8632                    allowed = false;
8633                }
8634            }
8635            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8636                if (pi.writePermission != null) {
8637                    allowed = false;
8638                }
8639            }
8640            if (allowed) {
8641                return -1;
8642            }
8643        }
8644
8645        /* There is a special cross user grant if:
8646         * - The target is on another user.
8647         * - Apps on the current user can access the uri without any uid permissions.
8648         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8649         * grant uri permissions.
8650         */
8651        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8652                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8653                modeFlags, false /*without considering the uid permissions*/);
8654
8655        // Second...  is the provider allowing granting of URI permissions?
8656        if (!specialCrossUserGrant) {
8657            if (!pi.grantUriPermissions) {
8658                throw new SecurityException("Provider " + pi.packageName
8659                        + "/" + pi.name
8660                        + " does not allow granting of Uri permissions (uri "
8661                        + grantUri + ")");
8662            }
8663            if (pi.uriPermissionPatterns != null) {
8664                final int N = pi.uriPermissionPatterns.length;
8665                boolean allowed = false;
8666                for (int i=0; i<N; i++) {
8667                    if (pi.uriPermissionPatterns[i] != null
8668                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8669                        allowed = true;
8670                        break;
8671                    }
8672                }
8673                if (!allowed) {
8674                    throw new SecurityException("Provider " + pi.packageName
8675                            + "/" + pi.name
8676                            + " does not allow granting of permission to path of Uri "
8677                            + grantUri);
8678                }
8679            }
8680        }
8681
8682        // Third...  does the caller itself have permission to access
8683        // this uri?
8684        final int callingAppId = UserHandle.getAppId(callingUid);
8685        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8686            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8687                // Exempted authority for cropping user photos in Settings app
8688            } else {
8689                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8690                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8691                return -1;
8692            }
8693        }
8694        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8695            // Require they hold a strong enough Uri permission
8696            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8697                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8698                    throw new SecurityException(
8699                            "UID " + callingUid + " does not have permission to " + grantUri
8700                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8701                                    + "or related APIs");
8702                } else {
8703                    throw new SecurityException(
8704                            "UID " + callingUid + " does not have permission to " + grantUri);
8705                }
8706            }
8707        }
8708        return targetUid;
8709    }
8710
8711    /**
8712     * @param uri This uri must NOT contain an embedded userId.
8713     * @param userId The userId in which the uri is to be resolved.
8714     */
8715    @Override
8716    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8717            final int modeFlags, int userId) {
8718        enforceNotIsolatedCaller("checkGrantUriPermission");
8719        synchronized(this) {
8720            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8721                    new GrantUri(userId, uri, false), modeFlags, -1);
8722        }
8723    }
8724
8725    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8726            final int modeFlags, UriPermissionOwner owner) {
8727        if (!Intent.isAccessUriMode(modeFlags)) {
8728            return;
8729        }
8730
8731        // So here we are: the caller has the assumed permission
8732        // to the uri, and the target doesn't.  Let's now give this to
8733        // the target.
8734
8735        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8736                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8737
8738        final String authority = grantUri.uri.getAuthority();
8739        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8740                MATCH_DEBUG_TRIAGED_MISSING);
8741        if (pi == null) {
8742            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8743            return;
8744        }
8745
8746        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8747            grantUri.prefix = true;
8748        }
8749        final UriPermission perm = findOrCreateUriPermissionLocked(
8750                pi.packageName, targetPkg, targetUid, grantUri);
8751        perm.grantModes(modeFlags, owner);
8752    }
8753
8754    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8755            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8756        if (targetPkg == null) {
8757            throw new NullPointerException("targetPkg");
8758        }
8759        int targetUid;
8760        final IPackageManager pm = AppGlobals.getPackageManager();
8761        try {
8762            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8763        } catch (RemoteException ex) {
8764            return;
8765        }
8766
8767        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8768                targetUid);
8769        if (targetUid < 0) {
8770            return;
8771        }
8772
8773        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8774                owner);
8775    }
8776
8777    static class NeededUriGrants extends ArrayList<GrantUri> {
8778        final String targetPkg;
8779        final int targetUid;
8780        final int flags;
8781
8782        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8783            this.targetPkg = targetPkg;
8784            this.targetUid = targetUid;
8785            this.flags = flags;
8786        }
8787    }
8788
8789    /**
8790     * Like checkGrantUriPermissionLocked, but takes an Intent.
8791     */
8792    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8793            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8794        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8795                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8796                + " clip=" + (intent != null ? intent.getClipData() : null)
8797                + " from " + intent + "; flags=0x"
8798                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8799
8800        if (targetPkg == null) {
8801            throw new NullPointerException("targetPkg");
8802        }
8803
8804        if (intent == null) {
8805            return null;
8806        }
8807        Uri data = intent.getData();
8808        ClipData clip = intent.getClipData();
8809        if (data == null && clip == null) {
8810            return null;
8811        }
8812        // Default userId for uris in the intent (if they don't specify it themselves)
8813        int contentUserHint = intent.getContentUserHint();
8814        if (contentUserHint == UserHandle.USER_CURRENT) {
8815            contentUserHint = UserHandle.getUserId(callingUid);
8816        }
8817        final IPackageManager pm = AppGlobals.getPackageManager();
8818        int targetUid;
8819        if (needed != null) {
8820            targetUid = needed.targetUid;
8821        } else {
8822            try {
8823                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8824                        targetUserId);
8825            } catch (RemoteException ex) {
8826                return null;
8827            }
8828            if (targetUid < 0) {
8829                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8830                        "Can't grant URI permission no uid for: " + targetPkg
8831                        + " on user " + targetUserId);
8832                return null;
8833            }
8834        }
8835        if (data != null) {
8836            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8837            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8838                    targetUid);
8839            if (targetUid > 0) {
8840                if (needed == null) {
8841                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8842                }
8843                needed.add(grantUri);
8844            }
8845        }
8846        if (clip != null) {
8847            for (int i=0; i<clip.getItemCount(); i++) {
8848                Uri uri = clip.getItemAt(i).getUri();
8849                if (uri != null) {
8850                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8851                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8852                            targetUid);
8853                    if (targetUid > 0) {
8854                        if (needed == null) {
8855                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8856                        }
8857                        needed.add(grantUri);
8858                    }
8859                } else {
8860                    Intent clipIntent = clip.getItemAt(i).getIntent();
8861                    if (clipIntent != null) {
8862                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8863                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8864                        if (newNeeded != null) {
8865                            needed = newNeeded;
8866                        }
8867                    }
8868                }
8869            }
8870        }
8871
8872        return needed;
8873    }
8874
8875    /**
8876     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8877     */
8878    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8879            UriPermissionOwner owner) {
8880        if (needed != null) {
8881            for (int i=0; i<needed.size(); i++) {
8882                GrantUri grantUri = needed.get(i);
8883                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8884                        grantUri, needed.flags, owner);
8885            }
8886        }
8887    }
8888
8889    void grantUriPermissionFromIntentLocked(int callingUid,
8890            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8891        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8892                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8893        if (needed == null) {
8894            return;
8895        }
8896
8897        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8898    }
8899
8900    /**
8901     * @param uri This uri must NOT contain an embedded userId.
8902     * @param userId The userId in which the uri is to be resolved.
8903     */
8904    @Override
8905    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8906            final int modeFlags, int userId) {
8907        enforceNotIsolatedCaller("grantUriPermission");
8908        GrantUri grantUri = new GrantUri(userId, uri, false);
8909        synchronized(this) {
8910            final ProcessRecord r = getRecordForAppLocked(caller);
8911            if (r == null) {
8912                throw new SecurityException("Unable to find app for caller "
8913                        + caller
8914                        + " when granting permission to uri " + grantUri);
8915            }
8916            if (targetPkg == null) {
8917                throw new IllegalArgumentException("null target");
8918            }
8919            if (grantUri == null) {
8920                throw new IllegalArgumentException("null uri");
8921            }
8922
8923            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8924                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8925                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8926                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8927
8928            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8929                    UserHandle.getUserId(r.uid));
8930        }
8931    }
8932
8933    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8934        if (perm.modeFlags == 0) {
8935            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8936                    perm.targetUid);
8937            if (perms != null) {
8938                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8939                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8940
8941                perms.remove(perm.uri);
8942                if (perms.isEmpty()) {
8943                    mGrantedUriPermissions.remove(perm.targetUid);
8944                }
8945            }
8946        }
8947    }
8948
8949    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
8950            final int modeFlags) {
8951        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8952                "Revoking all granted permissions to " + grantUri);
8953
8954        final IPackageManager pm = AppGlobals.getPackageManager();
8955        final String authority = grantUri.uri.getAuthority();
8956        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8957                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8958        if (pi == null) {
8959            Slog.w(TAG, "No content provider found for permission revoke: "
8960                    + grantUri.toSafeString());
8961            return;
8962        }
8963
8964        // Does the caller have this permission on the URI?
8965        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8966            // If they don't have direct access to the URI, then revoke any
8967            // ownerless URI permissions that have been granted to them.
8968            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8969            if (perms != null) {
8970                boolean persistChanged = false;
8971                for (int i = perms.size()-1; i >= 0; i--) {
8972                    final UriPermission perm = perms.valueAt(i);
8973                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
8974                        continue;
8975                    }
8976                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8977                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8978                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8979                                "Revoking non-owned " + perm.targetUid
8980                                + " permission to " + perm.uri);
8981                        persistChanged |= perm.revokeModes(
8982                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8983                        if (perm.modeFlags == 0) {
8984                            perms.removeAt(i);
8985                        }
8986                    }
8987                }
8988                if (perms.isEmpty()) {
8989                    mGrantedUriPermissions.remove(callingUid);
8990                }
8991                if (persistChanged) {
8992                    schedulePersistUriGrants();
8993                }
8994            }
8995            return;
8996        }
8997
8998        boolean persistChanged = false;
8999
9000        // Go through all of the permissions and remove any that match.
9001        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9002            final int targetUid = mGrantedUriPermissions.keyAt(i);
9003            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9004
9005            for (int j = perms.size()-1; j >= 0; j--) {
9006                final UriPermission perm = perms.valueAt(j);
9007                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9008                    continue;
9009                }
9010                if (perm.uri.sourceUserId == grantUri.sourceUserId
9011                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9012                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9013                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9014                    persistChanged |= perm.revokeModes(
9015                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9016                            targetPackage == null);
9017                    if (perm.modeFlags == 0) {
9018                        perms.removeAt(j);
9019                    }
9020                }
9021            }
9022
9023            if (perms.isEmpty()) {
9024                mGrantedUriPermissions.removeAt(i);
9025            }
9026        }
9027
9028        if (persistChanged) {
9029            schedulePersistUriGrants();
9030        }
9031    }
9032
9033    /**
9034     * @param uri This uri must NOT contain an embedded userId.
9035     * @param userId The userId in which the uri is to be resolved.
9036     */
9037    @Override
9038    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9039            final int modeFlags, int userId) {
9040        enforceNotIsolatedCaller("revokeUriPermission");
9041        synchronized(this) {
9042            final ProcessRecord r = getRecordForAppLocked(caller);
9043            if (r == null) {
9044                throw new SecurityException("Unable to find app for caller "
9045                        + caller
9046                        + " when revoking permission to uri " + uri);
9047            }
9048            if (uri == null) {
9049                Slog.w(TAG, "revokeUriPermission: null uri");
9050                return;
9051            }
9052
9053            if (!Intent.isAccessUriMode(modeFlags)) {
9054                return;
9055            }
9056
9057            final String authority = uri.getAuthority();
9058            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9059                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9060            if (pi == null) {
9061                Slog.w(TAG, "No content provider found for permission revoke: "
9062                        + uri.toSafeString());
9063                return;
9064            }
9065
9066            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9067                    modeFlags);
9068        }
9069    }
9070
9071    /**
9072     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9073     * given package.
9074     *
9075     * @param packageName Package name to match, or {@code null} to apply to all
9076     *            packages.
9077     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9078     *            to all users.
9079     * @param persistable If persistable grants should be removed.
9080     */
9081    private void removeUriPermissionsForPackageLocked(
9082            String packageName, int userHandle, boolean persistable) {
9083        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9084            throw new IllegalArgumentException("Must narrow by either package or user");
9085        }
9086
9087        boolean persistChanged = false;
9088
9089        int N = mGrantedUriPermissions.size();
9090        for (int i = 0; i < N; i++) {
9091            final int targetUid = mGrantedUriPermissions.keyAt(i);
9092            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9093
9094            // Only inspect grants matching user
9095            if (userHandle == UserHandle.USER_ALL
9096                    || userHandle == UserHandle.getUserId(targetUid)) {
9097                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9098                    final UriPermission perm = it.next();
9099
9100                    // Only inspect grants matching package
9101                    if (packageName == null || perm.sourcePkg.equals(packageName)
9102                            || perm.targetPkg.equals(packageName)) {
9103                        // Hacky solution as part of fixing a security bug; ignore
9104                        // grants associated with DownloadManager so we don't have
9105                        // to immediately launch it to regrant the permissions
9106                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9107                                && !persistable) continue;
9108
9109                        persistChanged |= perm.revokeModes(persistable
9110                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9111
9112                        // Only remove when no modes remain; any persisted grants
9113                        // will keep this alive.
9114                        if (perm.modeFlags == 0) {
9115                            it.remove();
9116                        }
9117                    }
9118                }
9119
9120                if (perms.isEmpty()) {
9121                    mGrantedUriPermissions.remove(targetUid);
9122                    N--;
9123                    i--;
9124                }
9125            }
9126        }
9127
9128        if (persistChanged) {
9129            schedulePersistUriGrants();
9130        }
9131    }
9132
9133    @Override
9134    public IBinder newUriPermissionOwner(String name) {
9135        enforceNotIsolatedCaller("newUriPermissionOwner");
9136        synchronized(this) {
9137            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9138            return owner.getExternalTokenLocked();
9139        }
9140    }
9141
9142    @Override
9143    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9144        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9145        synchronized(this) {
9146            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9147            if (r == null) {
9148                throw new IllegalArgumentException("Activity does not exist; token="
9149                        + activityToken);
9150            }
9151            return r.getUriPermissionsLocked().getExternalTokenLocked();
9152        }
9153    }
9154    /**
9155     * @param uri This uri must NOT contain an embedded userId.
9156     * @param sourceUserId The userId in which the uri is to be resolved.
9157     * @param targetUserId The userId of the app that receives the grant.
9158     */
9159    @Override
9160    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9161            final int modeFlags, int sourceUserId, int targetUserId) {
9162        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9163                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9164                "grantUriPermissionFromOwner", null);
9165        synchronized(this) {
9166            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9167            if (owner == null) {
9168                throw new IllegalArgumentException("Unknown owner: " + token);
9169            }
9170            if (fromUid != Binder.getCallingUid()) {
9171                if (Binder.getCallingUid() != myUid()) {
9172                    // Only system code can grant URI permissions on behalf
9173                    // of other users.
9174                    throw new SecurityException("nice try");
9175                }
9176            }
9177            if (targetPkg == null) {
9178                throw new IllegalArgumentException("null target");
9179            }
9180            if (uri == null) {
9181                throw new IllegalArgumentException("null uri");
9182            }
9183
9184            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9185                    modeFlags, owner, targetUserId);
9186        }
9187    }
9188
9189    /**
9190     * @param uri This uri must NOT contain an embedded userId.
9191     * @param userId The userId in which the uri is to be resolved.
9192     */
9193    @Override
9194    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9195        synchronized(this) {
9196            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9197            if (owner == null) {
9198                throw new IllegalArgumentException("Unknown owner: " + token);
9199            }
9200
9201            if (uri == null) {
9202                owner.removeUriPermissionsLocked(mode);
9203            } else {
9204                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9205                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9206            }
9207        }
9208    }
9209
9210    private void schedulePersistUriGrants() {
9211        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9212            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9213                    10 * DateUtils.SECOND_IN_MILLIS);
9214        }
9215    }
9216
9217    private void writeGrantedUriPermissions() {
9218        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9219
9220        // Snapshot permissions so we can persist without lock
9221        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9222        synchronized (this) {
9223            final int size = mGrantedUriPermissions.size();
9224            for (int i = 0; i < size; i++) {
9225                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9226                for (UriPermission perm : perms.values()) {
9227                    if (perm.persistedModeFlags != 0) {
9228                        persist.add(perm.snapshot());
9229                    }
9230                }
9231            }
9232        }
9233
9234        FileOutputStream fos = null;
9235        try {
9236            fos = mGrantFile.startWrite();
9237
9238            XmlSerializer out = new FastXmlSerializer();
9239            out.setOutput(fos, StandardCharsets.UTF_8.name());
9240            out.startDocument(null, true);
9241            out.startTag(null, TAG_URI_GRANTS);
9242            for (UriPermission.Snapshot perm : persist) {
9243                out.startTag(null, TAG_URI_GRANT);
9244                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9245                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9246                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9247                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9248                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9249                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9250                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9251                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9252                out.endTag(null, TAG_URI_GRANT);
9253            }
9254            out.endTag(null, TAG_URI_GRANTS);
9255            out.endDocument();
9256
9257            mGrantFile.finishWrite(fos);
9258        } catch (IOException e) {
9259            if (fos != null) {
9260                mGrantFile.failWrite(fos);
9261            }
9262        }
9263    }
9264
9265    private void readGrantedUriPermissionsLocked() {
9266        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9267
9268        final long now = System.currentTimeMillis();
9269
9270        FileInputStream fis = null;
9271        try {
9272            fis = mGrantFile.openRead();
9273            final XmlPullParser in = Xml.newPullParser();
9274            in.setInput(fis, StandardCharsets.UTF_8.name());
9275
9276            int type;
9277            while ((type = in.next()) != END_DOCUMENT) {
9278                final String tag = in.getName();
9279                if (type == START_TAG) {
9280                    if (TAG_URI_GRANT.equals(tag)) {
9281                        final int sourceUserId;
9282                        final int targetUserId;
9283                        final int userHandle = readIntAttribute(in,
9284                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9285                        if (userHandle != UserHandle.USER_NULL) {
9286                            // For backwards compatibility.
9287                            sourceUserId = userHandle;
9288                            targetUserId = userHandle;
9289                        } else {
9290                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9291                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9292                        }
9293                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9294                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9295                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9296                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9297                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9298                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9299
9300                        // Sanity check that provider still belongs to source package
9301                        // Both direct boot aware and unaware packages are fine as we
9302                        // will do filtering at query time to avoid multiple parsing.
9303                        final ProviderInfo pi = getProviderInfoLocked(
9304                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9305                                        | MATCH_DIRECT_BOOT_UNAWARE);
9306                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9307                            int targetUid = -1;
9308                            try {
9309                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9310                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9311                            } catch (RemoteException e) {
9312                            }
9313                            if (targetUid != -1) {
9314                                final UriPermission perm = findOrCreateUriPermissionLocked(
9315                                        sourcePkg, targetPkg, targetUid,
9316                                        new GrantUri(sourceUserId, uri, prefix));
9317                                perm.initPersistedModes(modeFlags, createdTime);
9318                            }
9319                        } else {
9320                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9321                                    + " but instead found " + pi);
9322                        }
9323                    }
9324                }
9325            }
9326        } catch (FileNotFoundException e) {
9327            // Missing grants is okay
9328        } catch (IOException e) {
9329            Slog.wtf(TAG, "Failed reading Uri grants", e);
9330        } catch (XmlPullParserException e) {
9331            Slog.wtf(TAG, "Failed reading Uri grants", e);
9332        } finally {
9333            IoUtils.closeQuietly(fis);
9334        }
9335    }
9336
9337    /**
9338     * @param uri This uri must NOT contain an embedded userId.
9339     * @param userId The userId in which the uri is to be resolved.
9340     */
9341    @Override
9342    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9343        enforceNotIsolatedCaller("takePersistableUriPermission");
9344
9345        Preconditions.checkFlagsArgument(modeFlags,
9346                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9347
9348        synchronized (this) {
9349            final int callingUid = Binder.getCallingUid();
9350            boolean persistChanged = false;
9351            GrantUri grantUri = new GrantUri(userId, uri, false);
9352
9353            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9354                    new GrantUri(userId, uri, false));
9355            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9356                    new GrantUri(userId, uri, true));
9357
9358            final boolean exactValid = (exactPerm != null)
9359                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9360            final boolean prefixValid = (prefixPerm != null)
9361                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9362
9363            if (!(exactValid || prefixValid)) {
9364                throw new SecurityException("No persistable permission grants found for UID "
9365                        + callingUid + " and Uri " + grantUri.toSafeString());
9366            }
9367
9368            if (exactValid) {
9369                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9370            }
9371            if (prefixValid) {
9372                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9373            }
9374
9375            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9376
9377            if (persistChanged) {
9378                schedulePersistUriGrants();
9379            }
9380        }
9381    }
9382
9383    /**
9384     * @param uri This uri must NOT contain an embedded userId.
9385     * @param userId The userId in which the uri is to be resolved.
9386     */
9387    @Override
9388    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9389        enforceNotIsolatedCaller("releasePersistableUriPermission");
9390
9391        Preconditions.checkFlagsArgument(modeFlags,
9392                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9393
9394        synchronized (this) {
9395            final int callingUid = Binder.getCallingUid();
9396            boolean persistChanged = false;
9397
9398            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9399                    new GrantUri(userId, uri, false));
9400            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9401                    new GrantUri(userId, uri, true));
9402            if (exactPerm == null && prefixPerm == null) {
9403                throw new SecurityException("No permission grants found for UID " + callingUid
9404                        + " and Uri " + uri.toSafeString());
9405            }
9406
9407            if (exactPerm != null) {
9408                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9409                removeUriPermissionIfNeededLocked(exactPerm);
9410            }
9411            if (prefixPerm != null) {
9412                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9413                removeUriPermissionIfNeededLocked(prefixPerm);
9414            }
9415
9416            if (persistChanged) {
9417                schedulePersistUriGrants();
9418            }
9419        }
9420    }
9421
9422    /**
9423     * Prune any older {@link UriPermission} for the given UID until outstanding
9424     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9425     *
9426     * @return if any mutations occured that require persisting.
9427     */
9428    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9429        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9430        if (perms == null) return false;
9431        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9432
9433        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9434        for (UriPermission perm : perms.values()) {
9435            if (perm.persistedModeFlags != 0) {
9436                persisted.add(perm);
9437            }
9438        }
9439
9440        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9441        if (trimCount <= 0) return false;
9442
9443        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9444        for (int i = 0; i < trimCount; i++) {
9445            final UriPermission perm = persisted.get(i);
9446
9447            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9448                    "Trimming grant created at " + perm.persistedCreateTime);
9449
9450            perm.releasePersistableModes(~0);
9451            removeUriPermissionIfNeededLocked(perm);
9452        }
9453
9454        return true;
9455    }
9456
9457    @Override
9458    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9459            String packageName, boolean incoming) {
9460        enforceNotIsolatedCaller("getPersistedUriPermissions");
9461        Preconditions.checkNotNull(packageName, "packageName");
9462
9463        final int callingUid = Binder.getCallingUid();
9464        final int callingUserId = UserHandle.getUserId(callingUid);
9465        final IPackageManager pm = AppGlobals.getPackageManager();
9466        try {
9467            final int packageUid = pm.getPackageUid(packageName,
9468                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9469            if (packageUid != callingUid) {
9470                throw new SecurityException(
9471                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9472            }
9473        } catch (RemoteException e) {
9474            throw new SecurityException("Failed to verify package name ownership");
9475        }
9476
9477        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9478        synchronized (this) {
9479            if (incoming) {
9480                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9481                        callingUid);
9482                if (perms == null) {
9483                    Slog.w(TAG, "No permission grants found for " + packageName);
9484                } else {
9485                    for (UriPermission perm : perms.values()) {
9486                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9487                            result.add(perm.buildPersistedPublicApiObject());
9488                        }
9489                    }
9490                }
9491            } else {
9492                final int size = mGrantedUriPermissions.size();
9493                for (int i = 0; i < size; i++) {
9494                    final ArrayMap<GrantUri, UriPermission> perms =
9495                            mGrantedUriPermissions.valueAt(i);
9496                    for (UriPermission perm : perms.values()) {
9497                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9498                            result.add(perm.buildPersistedPublicApiObject());
9499                        }
9500                    }
9501                }
9502            }
9503        }
9504        return new ParceledListSlice<android.content.UriPermission>(result);
9505    }
9506
9507    @Override
9508    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9509            String packageName, int userId) {
9510        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9511                "getGrantedUriPermissions");
9512
9513        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9514        synchronized (this) {
9515            final int size = mGrantedUriPermissions.size();
9516            for (int i = 0; i < size; i++) {
9517                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9518                for (UriPermission perm : perms.values()) {
9519                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9520                            && perm.persistedModeFlags != 0) {
9521                        result.add(perm.buildPersistedPublicApiObject());
9522                    }
9523                }
9524            }
9525        }
9526        return new ParceledListSlice<android.content.UriPermission>(result);
9527    }
9528
9529    @Override
9530    public void clearGrantedUriPermissions(String packageName, int userId) {
9531        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9532                "clearGrantedUriPermissions");
9533        removeUriPermissionsForPackageLocked(packageName, userId, true);
9534    }
9535
9536    @Override
9537    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9538        synchronized (this) {
9539            ProcessRecord app =
9540                who != null ? getRecordForAppLocked(who) : null;
9541            if (app == null) return;
9542
9543            Message msg = Message.obtain();
9544            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9545            msg.obj = app;
9546            msg.arg1 = waiting ? 1 : 0;
9547            mUiHandler.sendMessage(msg);
9548        }
9549    }
9550
9551    @Override
9552    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9553        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9554        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9555        outInfo.availMem = getFreeMemory();
9556        outInfo.totalMem = getTotalMemory();
9557        outInfo.threshold = homeAppMem;
9558        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9559        outInfo.hiddenAppThreshold = cachedAppMem;
9560        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9561                ProcessList.SERVICE_ADJ);
9562        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9563                ProcessList.VISIBLE_APP_ADJ);
9564        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9565                ProcessList.FOREGROUND_APP_ADJ);
9566    }
9567
9568    // =========================================================
9569    // TASK MANAGEMENT
9570    // =========================================================
9571
9572    @Override
9573    public List<IBinder> getAppTasks(String callingPackage) {
9574        int callingUid = Binder.getCallingUid();
9575        long ident = Binder.clearCallingIdentity();
9576
9577        synchronized(this) {
9578            ArrayList<IBinder> list = new ArrayList<IBinder>();
9579            try {
9580                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9581
9582                final int N = mRecentTasks.size();
9583                for (int i = 0; i < N; i++) {
9584                    TaskRecord tr = mRecentTasks.get(i);
9585                    // Skip tasks that do not match the caller.  We don't need to verify
9586                    // callingPackage, because we are also limiting to callingUid and know
9587                    // that will limit to the correct security sandbox.
9588                    if (tr.effectiveUid != callingUid) {
9589                        continue;
9590                    }
9591                    Intent intent = tr.getBaseIntent();
9592                    if (intent == null ||
9593                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9594                        continue;
9595                    }
9596                    ActivityManager.RecentTaskInfo taskInfo =
9597                            createRecentTaskInfoFromTaskRecord(tr);
9598                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9599                    list.add(taskImpl.asBinder());
9600                }
9601            } finally {
9602                Binder.restoreCallingIdentity(ident);
9603            }
9604            return list;
9605        }
9606    }
9607
9608    @Override
9609    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9610        final int callingUid = Binder.getCallingUid();
9611        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9612
9613        synchronized(this) {
9614            if (DEBUG_ALL) Slog.v(
9615                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9616
9617            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9618                    callingUid);
9619
9620            // TODO: Improve with MRU list from all ActivityStacks.
9621            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9622        }
9623
9624        return list;
9625    }
9626
9627    /**
9628     * Creates a new RecentTaskInfo from a TaskRecord.
9629     */
9630    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9631        // Update the task description to reflect any changes in the task stack
9632        tr.updateTaskDescription();
9633
9634        // Compose the recent task info
9635        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9636        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9637        rti.persistentId = tr.taskId;
9638        rti.baseIntent = new Intent(tr.getBaseIntent());
9639        rti.origActivity = tr.origActivity;
9640        rti.realActivity = tr.realActivity;
9641        rti.description = tr.lastDescription;
9642        rti.stackId = tr.getStackId();
9643        rti.userId = tr.userId;
9644        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9645        rti.firstActiveTime = tr.firstActiveTime;
9646        rti.lastActiveTime = tr.lastActiveTime;
9647        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9648        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9649        rti.numActivities = 0;
9650        if (tr.mBounds != null) {
9651            rti.bounds = new Rect(tr.mBounds);
9652        }
9653        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9654        rti.resizeMode = tr.mResizeMode;
9655
9656        ActivityRecord base = null;
9657        ActivityRecord top = null;
9658        ActivityRecord tmp;
9659
9660        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9661            tmp = tr.mActivities.get(i);
9662            if (tmp.finishing) {
9663                continue;
9664            }
9665            base = tmp;
9666            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9667                top = base;
9668            }
9669            rti.numActivities++;
9670        }
9671
9672        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9673        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9674
9675        return rti;
9676    }
9677
9678    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9679        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9680                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9681        if (!allowed) {
9682            if (checkPermission(android.Manifest.permission.GET_TASKS,
9683                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9684                // Temporary compatibility: some existing apps on the system image may
9685                // still be requesting the old permission and not switched to the new
9686                // one; if so, we'll still allow them full access.  This means we need
9687                // to see if they are holding the old permission and are a system app.
9688                try {
9689                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9690                        allowed = true;
9691                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9692                                + " is using old GET_TASKS but privileged; allowing");
9693                    }
9694                } catch (RemoteException e) {
9695                }
9696            }
9697        }
9698        if (!allowed) {
9699            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9700                    + " does not hold REAL_GET_TASKS; limiting output");
9701        }
9702        return allowed;
9703    }
9704
9705    @Override
9706    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9707            int userId) {
9708        final int callingUid = Binder.getCallingUid();
9709        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9710                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9711
9712        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9713        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9714        synchronized (this) {
9715            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9716                    callingUid);
9717            final boolean detailed = checkCallingPermission(
9718                    android.Manifest.permission.GET_DETAILED_TASKS)
9719                    == PackageManager.PERMISSION_GRANTED;
9720
9721            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9722                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9723                return ParceledListSlice.emptyList();
9724            }
9725            mRecentTasks.loadUserRecentsLocked(userId);
9726
9727            final int recentsCount = mRecentTasks.size();
9728            ArrayList<ActivityManager.RecentTaskInfo> res =
9729                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9730
9731            final Set<Integer> includedUsers;
9732            if (includeProfiles) {
9733                includedUsers = mUserController.getProfileIds(userId);
9734            } else {
9735                includedUsers = new HashSet<>();
9736            }
9737            includedUsers.add(Integer.valueOf(userId));
9738
9739            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9740                TaskRecord tr = mRecentTasks.get(i);
9741                // Only add calling user or related users recent tasks
9742                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9743                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9744                    continue;
9745                }
9746
9747                if (tr.realActivitySuspended) {
9748                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9749                    continue;
9750                }
9751
9752                // Return the entry if desired by the caller.  We always return
9753                // the first entry, because callers always expect this to be the
9754                // foreground app.  We may filter others if the caller has
9755                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9756                // we should exclude the entry.
9757
9758                if (i == 0
9759                        || withExcluded
9760                        || (tr.intent == null)
9761                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9762                                == 0)) {
9763                    if (!allowed) {
9764                        // If the caller doesn't have the GET_TASKS permission, then only
9765                        // allow them to see a small subset of tasks -- their own and home.
9766                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9767                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9768                            continue;
9769                        }
9770                    }
9771                    final ActivityStack stack = tr.getStack();
9772                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9773                        if (stack != null && stack.isHomeOrRecentsStack()) {
9774                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9775                                    "Skipping, home or recents stack task: " + tr);
9776                            continue;
9777                        }
9778                    }
9779                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9780                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9781                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9782                                    "Skipping, top task in docked stack: " + tr);
9783                            continue;
9784                        }
9785                    }
9786                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9787                        if (stack != null && stack.isPinnedStack()) {
9788                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9789                                    "Skipping, pinned stack task: " + tr);
9790                            continue;
9791                        }
9792                    }
9793                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9794                        // Don't include auto remove tasks that are finished or finishing.
9795                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9796                                "Skipping, auto-remove without activity: " + tr);
9797                        continue;
9798                    }
9799                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9800                            && !tr.isAvailable) {
9801                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9802                                "Skipping, unavail real act: " + tr);
9803                        continue;
9804                    }
9805
9806                    if (!tr.mUserSetupComplete) {
9807                        // Don't include task launched while user is not done setting-up.
9808                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9809                                "Skipping, user setup not complete: " + tr);
9810                        continue;
9811                    }
9812
9813                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9814                    if (!detailed) {
9815                        rti.baseIntent.replaceExtras((Bundle)null);
9816                    }
9817
9818                    res.add(rti);
9819                    maxNum--;
9820                }
9821            }
9822            return new ParceledListSlice<>(res);
9823        }
9824    }
9825
9826    @Override
9827    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9828        synchronized (this) {
9829            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9830                    "getTaskThumbnail()");
9831            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9832                    id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9833            if (tr != null) {
9834                return tr.getTaskThumbnailLocked();
9835            }
9836        }
9837        return null;
9838    }
9839
9840    @Override
9841    public ActivityManager.TaskDescription getTaskDescription(int id) {
9842        synchronized (this) {
9843            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9844                    "getTaskDescription()");
9845            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9846                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9847            if (tr != null) {
9848                return tr.lastTaskDescription;
9849            }
9850        }
9851        return null;
9852    }
9853
9854    @Override
9855    public int addAppTask(IBinder activityToken, Intent intent,
9856            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9857        final int callingUid = Binder.getCallingUid();
9858        final long callingIdent = Binder.clearCallingIdentity();
9859
9860        try {
9861            synchronized (this) {
9862                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9863                if (r == null) {
9864                    throw new IllegalArgumentException("Activity does not exist; token="
9865                            + activityToken);
9866                }
9867                ComponentName comp = intent.getComponent();
9868                if (comp == null) {
9869                    throw new IllegalArgumentException("Intent " + intent
9870                            + " must specify explicit component");
9871                }
9872                if (thumbnail.getWidth() != mThumbnailWidth
9873                        || thumbnail.getHeight() != mThumbnailHeight) {
9874                    throw new IllegalArgumentException("Bad thumbnail size: got "
9875                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9876                            + mThumbnailWidth + "x" + mThumbnailHeight);
9877                }
9878                if (intent.getSelector() != null) {
9879                    intent.setSelector(null);
9880                }
9881                if (intent.getSourceBounds() != null) {
9882                    intent.setSourceBounds(null);
9883                }
9884                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9885                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9886                        // The caller has added this as an auto-remove task...  that makes no
9887                        // sense, so turn off auto-remove.
9888                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9889                    }
9890                }
9891                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9892                    mLastAddedTaskActivity = null;
9893                }
9894                ActivityInfo ainfo = mLastAddedTaskActivity;
9895                if (ainfo == null) {
9896                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9897                            comp, 0, UserHandle.getUserId(callingUid));
9898                    if (ainfo.applicationInfo.uid != callingUid) {
9899                        throw new SecurityException(
9900                                "Can't add task for another application: target uid="
9901                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9902                    }
9903                }
9904
9905                TaskRecord task = new TaskRecord(this,
9906                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9907                        ainfo, intent, description, new TaskThumbnailInfo());
9908
9909                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9910                if (trimIdx >= 0) {
9911                    // If this would have caused a trim, then we'll abort because that
9912                    // means it would be added at the end of the list but then just removed.
9913                    return INVALID_TASK_ID;
9914                }
9915
9916                final int N = mRecentTasks.size();
9917                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9918                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9919                    tr.removedFromRecents();
9920                }
9921
9922                task.inRecents = true;
9923                mRecentTasks.add(task);
9924                r.getStack().addTask(task, false, "addAppTask");
9925
9926                task.setLastThumbnailLocked(thumbnail);
9927                task.freeLastThumbnail();
9928                return task.taskId;
9929            }
9930        } finally {
9931            Binder.restoreCallingIdentity(callingIdent);
9932        }
9933    }
9934
9935    @Override
9936    public Point getAppTaskThumbnailSize() {
9937        synchronized (this) {
9938            return new Point(mThumbnailWidth,  mThumbnailHeight);
9939        }
9940    }
9941
9942    @Override
9943    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9944        synchronized (this) {
9945            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9946            if (r != null) {
9947                r.setTaskDescription(td);
9948                final TaskRecord task = r.getTask();
9949                task.updateTaskDescription();
9950                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
9951            }
9952        }
9953    }
9954
9955    @Override
9956    public void setTaskResizeable(int taskId, int resizeableMode) {
9957        synchronized (this) {
9958            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9959                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9960            if (task == null) {
9961                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9962                return;
9963            }
9964            task.setResizeMode(resizeableMode);
9965        }
9966    }
9967
9968    @Override
9969    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9970        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9971        long ident = Binder.clearCallingIdentity();
9972        try {
9973            synchronized (this) {
9974                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9975                if (task == null) {
9976                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9977                    return;
9978                }
9979                // Place the task in the right stack if it isn't there already based on
9980                // the requested bounds.
9981                // The stack transition logic is:
9982                // - a null bounds on a freeform task moves that task to fullscreen
9983                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9984                //   that task to freeform
9985                // - otherwise the task is not moved
9986                int stackId = task.getStackId();
9987                if (!StackId.isTaskResizeAllowed(stackId)) {
9988                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9989                }
9990                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9991                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9992                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9993                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9994                }
9995
9996                // Reparent the task to the right stack if necessary
9997                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9998                if (stackId != task.getStackId()) {
9999                    // Defer resume until the task is resized below
10000                    task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10001                            DEFER_RESUME, "resizeTask");
10002                    preserveWindow = false;
10003                }
10004
10005                // After reparenting (which only resizes the task to the stack bounds), resize the
10006                // task to the actual bounds provided
10007                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10008            }
10009        } finally {
10010            Binder.restoreCallingIdentity(ident);
10011        }
10012    }
10013
10014    @Override
10015    public Rect getTaskBounds(int taskId) {
10016        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10017        long ident = Binder.clearCallingIdentity();
10018        Rect rect = new Rect();
10019        try {
10020            synchronized (this) {
10021                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10022                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10023                if (task == null) {
10024                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10025                    return rect;
10026                }
10027                if (task.getStack() != null) {
10028                    // Return the bounds from window manager since it will be adjusted for various
10029                    // things like the presense of a docked stack for tasks that aren't resizeable.
10030                    task.getWindowContainerBounds(rect);
10031                } else {
10032                    // Task isn't in window manager yet since it isn't associated with a stack.
10033                    // Return the persist value from activity manager
10034                    if (task.mBounds != null) {
10035                        rect.set(task.mBounds);
10036                    } else if (task.mLastNonFullscreenBounds != null) {
10037                        rect.set(task.mLastNonFullscreenBounds);
10038                    }
10039                }
10040            }
10041        } finally {
10042            Binder.restoreCallingIdentity(ident);
10043        }
10044        return rect;
10045    }
10046
10047    @Override
10048    public void cancelTaskWindowTransition(int taskId) {
10049        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10050        final long ident = Binder.clearCallingIdentity();
10051        try {
10052            synchronized (this) {
10053                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10054                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10055                if (task == null) {
10056                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10057                    return;
10058                }
10059                task.cancelWindowTransition();
10060            }
10061        } finally {
10062            Binder.restoreCallingIdentity(ident);
10063        }
10064    }
10065
10066    @Override
10067    public void cancelTaskThumbnailTransition(int taskId) {
10068        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10069        final long ident = Binder.clearCallingIdentity();
10070        try {
10071            synchronized (this) {
10072                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10073                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10074                if (task == null) {
10075                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10076                    return;
10077                }
10078                task.cancelThumbnailTransition();
10079            }
10080        } finally {
10081            Binder.restoreCallingIdentity(ident);
10082        }
10083    }
10084
10085    @Override
10086    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10087        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10088        final long ident = Binder.clearCallingIdentity();
10089        try {
10090            final TaskRecord task;
10091            synchronized (this) {
10092                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10093                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10094                if (task == null) {
10095                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10096                    return null;
10097                }
10098            }
10099            // Don't call this while holding the lock as this operation might hit the disk.
10100            return task.getSnapshot(reducedResolution);
10101        } finally {
10102            Binder.restoreCallingIdentity(ident);
10103        }
10104    }
10105
10106    @Override
10107    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10108        if (userId != UserHandle.getCallingUserId()) {
10109            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10110                    "getTaskDescriptionIcon");
10111        }
10112        final File passedIconFile = new File(filePath);
10113        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10114                passedIconFile.getName());
10115        if (!legitIconFile.getPath().equals(filePath)
10116                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10117            throw new IllegalArgumentException("Bad file path: " + filePath
10118                    + " passed for userId " + userId);
10119        }
10120        return mRecentTasks.getTaskDescriptionIcon(filePath);
10121    }
10122
10123    @Override
10124    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10125            throws RemoteException {
10126        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10127        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10128                activityOptions.getCustomInPlaceResId() == 0) {
10129            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10130                    "with valid animation");
10131        }
10132        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10133        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10134                activityOptions.getCustomInPlaceResId());
10135        mWindowManager.executeAppTransition();
10136    }
10137
10138    private void removeTasksByPackageNameLocked(String packageName, int userId) {
10139        // Remove all tasks with activities in the specified package from the list of recent tasks
10140        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10141            TaskRecord tr = mRecentTasks.get(i);
10142            if (tr.userId != userId) continue;
10143
10144            ComponentName cn = tr.intent.getComponent();
10145            if (cn != null && cn.getPackageName().equals(packageName)) {
10146                // If the package name matches, remove the task.
10147                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10148            }
10149        }
10150    }
10151
10152    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10153            int userId) {
10154
10155        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10156            TaskRecord tr = mRecentTasks.get(i);
10157            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10158                continue;
10159            }
10160
10161            ComponentName cn = tr.intent.getComponent();
10162            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10163                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10164            if (sameComponent) {
10165                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10166            }
10167        }
10168    }
10169
10170    @Override
10171    public void removeStack(int stackId) {
10172        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10173        if (StackId.isHomeOrRecentsStack(stackId)) {
10174            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10175        }
10176
10177        synchronized (this) {
10178            final long ident = Binder.clearCallingIdentity();
10179            try {
10180                mStackSupervisor.removeStackLocked(stackId);
10181            } finally {
10182                Binder.restoreCallingIdentity(ident);
10183            }
10184        }
10185    }
10186
10187    @Override
10188    public void moveStackToDisplay(int stackId, int displayId) {
10189        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
10190
10191        synchronized (this) {
10192            final long ident = Binder.clearCallingIdentity();
10193            try {
10194                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10195                        + " to displayId=" + displayId);
10196                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10197            } finally {
10198                Binder.restoreCallingIdentity(ident);
10199            }
10200        }
10201    }
10202
10203    @Override
10204    public boolean removeTask(int taskId) {
10205        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10206        synchronized (this) {
10207            final long ident = Binder.clearCallingIdentity();
10208            try {
10209                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10210            } finally {
10211                Binder.restoreCallingIdentity(ident);
10212            }
10213        }
10214    }
10215
10216    /**
10217     * TODO: Add mController hook
10218     */
10219    @Override
10220    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10221        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10222
10223        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10224        synchronized(this) {
10225            moveTaskToFrontLocked(taskId, flags, bOptions);
10226        }
10227    }
10228
10229    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
10230        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10231
10232        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10233                Binder.getCallingUid(), -1, -1, "Task to front")) {
10234            ActivityOptions.abort(options);
10235            return;
10236        }
10237        final long origId = Binder.clearCallingIdentity();
10238        try {
10239            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10240            if (task == null) {
10241                Slog.d(TAG, "Could not find task for id: "+ taskId);
10242                return;
10243            }
10244            if (mStackSupervisor.isLockTaskModeViolation(task)) {
10245                mStackSupervisor.showLockTaskToast();
10246                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10247                return;
10248            }
10249            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10250            if (prev != null) {
10251                task.setTaskToReturnTo(prev);
10252            }
10253            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10254                    false /* forceNonResizable */);
10255
10256            final ActivityRecord topActivity = task.getTopActivity();
10257            if (topActivity != null) {
10258
10259                // We are reshowing a task, use a starting window to hide the initial draw delay
10260                // so the transition can start earlier.
10261                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10262                        true /* taskSwitch */);
10263            }
10264        } finally {
10265            Binder.restoreCallingIdentity(origId);
10266        }
10267        ActivityOptions.abort(options);
10268    }
10269
10270    /**
10271     * Attempts to move a task backwards in z-order (the order of activities within the task is
10272     * unchanged).
10273     *
10274     * There are several possible results of this call:
10275     * - if the task is locked, then we will show the lock toast
10276     * - if there is a task behind the provided task, then that task is made visible and resumed as
10277     *   this task is moved to the back
10278     * - otherwise, if there are no other tasks in the stack:
10279     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10280     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10281     *       (depending on whether it is visible)
10282     *     - otherwise, we simply return home and hide this task
10283     *
10284     * @param token A reference to the activity we wish to move
10285     * @param nonRoot If false then this only works if the activity is the root
10286     *                of a task; if true it will work for any activity in a task.
10287     * @return Returns true if the move completed, false if not.
10288     */
10289    @Override
10290    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10291        enforceNotIsolatedCaller("moveActivityTaskToBack");
10292        synchronized(this) {
10293            final long origId = Binder.clearCallingIdentity();
10294            try {
10295                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10296                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10297                if (task != null) {
10298                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10299                }
10300            } finally {
10301                Binder.restoreCallingIdentity(origId);
10302            }
10303        }
10304        return false;
10305    }
10306
10307    @Override
10308    public void moveTaskBackwards(int task) {
10309        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10310                "moveTaskBackwards()");
10311
10312        synchronized(this) {
10313            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10314                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10315                return;
10316            }
10317            final long origId = Binder.clearCallingIdentity();
10318            moveTaskBackwardsLocked(task);
10319            Binder.restoreCallingIdentity(origId);
10320        }
10321    }
10322
10323    private final void moveTaskBackwardsLocked(int task) {
10324        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10325    }
10326
10327    @Override
10328    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10329            IActivityContainerCallback callback) throws RemoteException {
10330        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10331        synchronized (this) {
10332            if (parentActivityToken == null) {
10333                throw new IllegalArgumentException("parent token must not be null");
10334            }
10335            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10336            if (r == null) {
10337                return null;
10338            }
10339            if (callback == null) {
10340                throw new IllegalArgumentException("callback must not be null");
10341            }
10342            return mStackSupervisor.createVirtualActivityContainer(r, callback);
10343        }
10344    }
10345
10346    @Override
10347    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10348        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10349        synchronized (this) {
10350            final int stackId = mStackSupervisor.getNextStackId();
10351            final ActivityStack stack =
10352                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10353            if (stack == null) {
10354                return null;
10355            }
10356            return stack.mActivityContainer;
10357        }
10358    }
10359
10360    @Override
10361    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10362        synchronized (this) {
10363            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10364            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10365                return stack.mActivityContainer.getDisplayId();
10366            }
10367            return DEFAULT_DISPLAY;
10368        }
10369    }
10370
10371    @Override
10372    public int getActivityStackId(IBinder token) throws RemoteException {
10373        synchronized (this) {
10374            ActivityStack stack = ActivityRecord.getStackLocked(token);
10375            if (stack == null) {
10376                return INVALID_STACK_ID;
10377            }
10378            return stack.mStackId;
10379        }
10380    }
10381
10382    @Override
10383    public void exitFreeformMode(IBinder token) throws RemoteException {
10384        synchronized (this) {
10385            long ident = Binder.clearCallingIdentity();
10386            try {
10387                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10388                if (r == null) {
10389                    throw new IllegalArgumentException(
10390                            "exitFreeformMode: No activity record matching token=" + token);
10391                }
10392
10393                final ActivityStack stack = r.getStack();
10394                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10395                    throw new IllegalStateException(
10396                            "exitFreeformMode: You can only go fullscreen from freeform.");
10397                }
10398
10399                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10400                r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10401                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10402            } finally {
10403                Binder.restoreCallingIdentity(ident);
10404            }
10405        }
10406    }
10407
10408    @Override
10409    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10410        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10411        if (StackId.isHomeOrRecentsStack(stackId)) {
10412            throw new IllegalArgumentException(
10413                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10414        }
10415        synchronized (this) {
10416            long ident = Binder.clearCallingIdentity();
10417            try {
10418                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10419                if (task == null) {
10420                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10421                    return;
10422                }
10423
10424                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10425                        + " to stackId=" + stackId + " toTop=" + toTop);
10426                if (stackId == DOCKED_STACK_ID) {
10427                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10428                            null /* initialBounds */);
10429                }
10430                task.reparent(stackId, toTop,
10431                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10432            } finally {
10433                Binder.restoreCallingIdentity(ident);
10434            }
10435        }
10436    }
10437
10438    @Override
10439    public void swapDockedAndFullscreenStack() throws RemoteException {
10440        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10441        synchronized (this) {
10442            long ident = Binder.clearCallingIdentity();
10443            try {
10444                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10445                        FULLSCREEN_WORKSPACE_STACK_ID);
10446                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10447                        : null;
10448                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10449                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10450                        : null;
10451                if (topTask == null || tasks == null || tasks.size() == 0) {
10452                    Slog.w(TAG,
10453                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10454                    return;
10455                }
10456
10457                // TODO: App transition
10458                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10459
10460                // Defer the resume until we move all the docked tasks to the fullscreen stack below
10461                topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10462                        DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10463                final int size = tasks.size();
10464                for (int i = 0; i < size; i++) {
10465                    final int id = tasks.get(i).taskId;
10466                    if (id == topTask.taskId) {
10467                        continue;
10468                    }
10469
10470                    // Defer the resume until after all the tasks have been moved
10471                    tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10472                            REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10473                            "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10474                }
10475
10476                // Because we deferred the resume to avoid conflicts with stack switches while
10477                // resuming, we need to do it after all the tasks are moved.
10478                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10479                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10480
10481                mWindowManager.executeAppTransition();
10482            } finally {
10483                Binder.restoreCallingIdentity(ident);
10484            }
10485        }
10486    }
10487
10488    /**
10489     * Moves the input task to the docked stack.
10490     *
10491     * @param taskId Id of task to move.
10492     * @param createMode The mode the docked stack should be created in if it doesn't exist
10493     *                   already. See
10494     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10495     *                   and
10496     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10497     * @param toTop If the task and stack should be moved to the top.
10498     * @param animate Whether we should play an animation for the moving the task
10499     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10500     *                      docked stack. Pass {@code null} to use default bounds.
10501     */
10502    @Override
10503    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10504            Rect initialBounds) {
10505        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10506        synchronized (this) {
10507            long ident = Binder.clearCallingIdentity();
10508            try {
10509                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10510                if (task == null) {
10511                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10512                    return false;
10513                }
10514
10515                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10516                        + " to createMode=" + createMode + " toTop=" + toTop);
10517                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10518
10519                // Defer resuming until we move the home stack to the front below
10520                final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10521                        REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10522                        "moveTaskToDockedStack");
10523                if (moved) {
10524                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10525                }
10526                return moved;
10527            } finally {
10528                Binder.restoreCallingIdentity(ident);
10529            }
10530        }
10531    }
10532
10533    /**
10534     * Moves the top activity in the input stackId to the pinned stack.
10535     *
10536     * @param stackId Id of stack to move the top activity to pinned stack.
10537     * @param bounds Bounds to use for pinned stack.
10538     *
10539     * @return True if the top activity of the input stack was successfully moved to the pinned
10540     *          stack.
10541     */
10542    @Override
10543    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10544        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10545        synchronized (this) {
10546            if (!mSupportsPictureInPicture) {
10547                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10548                        + "Device doesn't support picture-in-picture mode");
10549            }
10550
10551            long ident = Binder.clearCallingIdentity();
10552            try {
10553                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10554            } finally {
10555                Binder.restoreCallingIdentity(ident);
10556            }
10557        }
10558    }
10559
10560    @Override
10561    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10562            boolean preserveWindows, boolean animate, int animationDuration) {
10563        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10564        long ident = Binder.clearCallingIdentity();
10565        try {
10566            synchronized (this) {
10567                if (animate) {
10568                    if (stackId == PINNED_STACK_ID) {
10569                        final PinnedActivityStack pinnedStack =
10570                                mStackSupervisor.getStack(PINNED_STACK_ID);
10571                        if (pinnedStack != null) {
10572                            pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10573                                    destBounds, animationDuration,
10574                                    false /* schedulePipModeChangedOnAnimationEnd */);
10575                        }
10576                    } else {
10577                        throw new IllegalArgumentException("Stack: " + stackId
10578                                + " doesn't support animated resize.");
10579                    }
10580                } else {
10581                    mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10582                            null /* tempTaskInsetBounds */, preserveWindows,
10583                            allowResizeInDockedMode, !DEFER_RESUME);
10584                }
10585            }
10586        } finally {
10587            Binder.restoreCallingIdentity(ident);
10588        }
10589    }
10590
10591    @Override
10592    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10593            Rect tempDockedTaskInsetBounds,
10594            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10595        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10596                "resizeDockedStack()");
10597        long ident = Binder.clearCallingIdentity();
10598        try {
10599            synchronized (this) {
10600                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10601                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10602                        PRESERVE_WINDOWS);
10603            }
10604        } finally {
10605            Binder.restoreCallingIdentity(ident);
10606        }
10607    }
10608
10609    @Override
10610    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10611        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10612                "resizePinnedStack()");
10613        final long ident = Binder.clearCallingIdentity();
10614        try {
10615            synchronized (this) {
10616                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10617            }
10618        } finally {
10619            Binder.restoreCallingIdentity(ident);
10620        }
10621    }
10622
10623    /**
10624     * Try to place task to provided position. The final position might be different depending on
10625     * current user and stacks state. The task will be moved to target stack if it's currently in
10626     * different stack.
10627     */
10628    @Override
10629    public void positionTaskInStack(int taskId, int stackId, int position) {
10630        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10631        if (StackId.isHomeOrRecentsStack(stackId)) {
10632            throw new IllegalArgumentException(
10633                    "positionTaskInStack: Attempt to change the position of task "
10634                    + taskId + " in/to home/recents stack");
10635        }
10636        synchronized (this) {
10637            long ident = Binder.clearCallingIdentity();
10638            try {
10639                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10640                        + taskId + " in stackId=" + stackId + " at position=" + position);
10641                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10642                if (task == null) {
10643                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10644                            + taskId);
10645                }
10646
10647                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10648                        !ON_TOP);
10649
10650                // TODO: Have the callers of this API call a separate reparent method if that is
10651                // what they intended to do vs. having this method also do reparenting.
10652                if (task.getStack() == stack) {
10653                    // Change position in current stack.
10654                    stack.positionChildAt(task, position);
10655                } else {
10656                    // Reparent to new stack.
10657                    task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10658                            !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10659                }
10660            } finally {
10661                Binder.restoreCallingIdentity(ident);
10662            }
10663        }
10664    }
10665
10666    @Override
10667    public List<StackInfo> getAllStackInfos() {
10668        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10669        long ident = Binder.clearCallingIdentity();
10670        try {
10671            synchronized (this) {
10672                return mStackSupervisor.getAllStackInfosLocked();
10673            }
10674        } finally {
10675            Binder.restoreCallingIdentity(ident);
10676        }
10677    }
10678
10679    @Override
10680    public StackInfo getStackInfo(int stackId) {
10681        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10682        long ident = Binder.clearCallingIdentity();
10683        try {
10684            synchronized (this) {
10685                return mStackSupervisor.getStackInfoLocked(stackId);
10686            }
10687        } finally {
10688            Binder.restoreCallingIdentity(ident);
10689        }
10690    }
10691
10692    @Override
10693    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10694        synchronized(this) {
10695            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10696        }
10697    }
10698
10699    @Override
10700    public void updateDeviceOwner(String packageName) {
10701        final int callingUid = Binder.getCallingUid();
10702        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10703            throw new SecurityException("updateDeviceOwner called from non-system process");
10704        }
10705        synchronized (this) {
10706            mDeviceOwnerName = packageName;
10707        }
10708    }
10709
10710    @Override
10711    public void updateLockTaskPackages(int userId, String[] packages) {
10712        final int callingUid = Binder.getCallingUid();
10713        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10714            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10715                    "updateLockTaskPackages()");
10716        }
10717        synchronized (this) {
10718            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10719                    Arrays.toString(packages));
10720            mLockTaskPackages.put(userId, packages);
10721            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10722        }
10723    }
10724
10725
10726    void startLockTaskModeLocked(TaskRecord task) {
10727        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10728        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10729            return;
10730        }
10731
10732        // When a task is locked, dismiss the pinned stack if it exists
10733        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10734                PINNED_STACK_ID);
10735        if (pinnedStack != null) {
10736            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10737        }
10738
10739        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10740        // is initiated by system after the pinning request was shown and locked mode is initiated
10741        // by an authorized app directly
10742        final int callingUid = Binder.getCallingUid();
10743        boolean isSystemInitiated = callingUid == SYSTEM_UID;
10744        long ident = Binder.clearCallingIdentity();
10745        try {
10746            if (!isSystemInitiated) {
10747                task.mLockTaskUid = callingUid;
10748                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10749                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10750                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10751                    StatusBarManagerInternal statusBarManager =
10752                            LocalServices.getService(StatusBarManagerInternal.class);
10753                    if (statusBarManager != null) {
10754                        statusBarManager.showScreenPinningRequest(task.taskId);
10755                    }
10756                    return;
10757                }
10758
10759                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10760                if (stack == null || task != stack.topTask()) {
10761                    throw new IllegalArgumentException("Invalid task, not in foreground");
10762                }
10763            }
10764            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10765                    "Locking fully");
10766            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10767                    ActivityManager.LOCK_TASK_MODE_PINNED :
10768                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10769                    "startLockTask", true);
10770        } finally {
10771            Binder.restoreCallingIdentity(ident);
10772        }
10773    }
10774
10775    @Override
10776    public void startLockTaskModeById(int taskId) {
10777        synchronized (this) {
10778            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10779            if (task != null) {
10780                startLockTaskModeLocked(task);
10781            }
10782        }
10783    }
10784
10785    @Override
10786    public void startLockTaskModeByToken(IBinder token) {
10787        synchronized (this) {
10788            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10789            if (r == null) {
10790                return;
10791            }
10792            final TaskRecord task = r.getTask();
10793            if (task != null) {
10794                startLockTaskModeLocked(task);
10795            }
10796        }
10797    }
10798
10799    @Override
10800    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10801        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10802        // This makes inner call to look as if it was initiated by system.
10803        long ident = Binder.clearCallingIdentity();
10804        try {
10805            synchronized (this) {
10806                startLockTaskModeById(taskId);
10807            }
10808        } finally {
10809            Binder.restoreCallingIdentity(ident);
10810        }
10811    }
10812
10813    @Override
10814    public void stopLockTaskMode() {
10815        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10816        if (lockTask == null) {
10817            // Our work here is done.
10818            return;
10819        }
10820
10821        final int callingUid = Binder.getCallingUid();
10822        final int lockTaskUid = lockTask.mLockTaskUid;
10823        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10824        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10825            // Done.
10826            return;
10827        } else {
10828            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10829            // It is possible lockTaskMode was started by the system process because
10830            // android:lockTaskMode is set to a locking value in the application manifest
10831            // instead of the app calling startLockTaskMode. In this case
10832            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10833            // {@link TaskRecord.effectiveUid} instead. Also caller with
10834            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10835            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10836                    && callingUid != lockTaskUid
10837                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10838                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10839                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10840            }
10841        }
10842        long ident = Binder.clearCallingIdentity();
10843        try {
10844            Log.d(TAG, "stopLockTaskMode");
10845            // Stop lock task
10846            synchronized (this) {
10847                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10848                        "stopLockTask", true);
10849            }
10850            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10851            if (tm != null) {
10852                tm.showInCallScreen(false);
10853            }
10854        } finally {
10855            Binder.restoreCallingIdentity(ident);
10856        }
10857    }
10858
10859    /**
10860     * This API should be called by SystemUI only when user perform certain action to dismiss
10861     * lock task mode. We should only dismiss pinned lock task mode in this case.
10862     */
10863    @Override
10864    public void stopSystemLockTaskMode() throws RemoteException {
10865        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10866            stopLockTaskMode();
10867        } else {
10868            mStackSupervisor.showLockTaskToast();
10869        }
10870    }
10871
10872    @Override
10873    public boolean isInLockTaskMode() {
10874        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10875    }
10876
10877    @Override
10878    public int getLockTaskModeState() {
10879        synchronized (this) {
10880            return mStackSupervisor.getLockTaskModeState();
10881        }
10882    }
10883
10884    @Override
10885    public void showLockTaskEscapeMessage(IBinder token) {
10886        synchronized (this) {
10887            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10888            if (r == null) {
10889                return;
10890            }
10891            mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
10892        }
10893    }
10894
10895    @Override
10896    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
10897            throws RemoteException {
10898        synchronized (this) {
10899            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10900            if (r == null) {
10901                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
10902                        + token);
10903                return;
10904            }
10905            final long origId = Binder.clearCallingIdentity();
10906            try {
10907                r.setDisablePreviewScreenshots(disable);
10908            } finally {
10909                Binder.restoreCallingIdentity(origId);
10910            }
10911        }
10912    }
10913
10914    // =========================================================
10915    // CONTENT PROVIDERS
10916    // =========================================================
10917
10918    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10919        List<ProviderInfo> providers = null;
10920        try {
10921            providers = AppGlobals.getPackageManager()
10922                    .queryContentProviders(app.processName, app.uid,
10923                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10924                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
10925                    .getList();
10926        } catch (RemoteException ex) {
10927        }
10928        if (DEBUG_MU) Slog.v(TAG_MU,
10929                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10930        int userId = app.userId;
10931        if (providers != null) {
10932            int N = providers.size();
10933            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10934            for (int i=0; i<N; i++) {
10935                // TODO: keep logic in sync with installEncryptionUnawareProviders
10936                ProviderInfo cpi =
10937                    (ProviderInfo)providers.get(i);
10938                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10939                        cpi.name, cpi.flags);
10940                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10941                    // This is a singleton provider, but a user besides the
10942                    // default user is asking to initialize a process it runs
10943                    // in...  well, no, it doesn't actually run in this process,
10944                    // it runs in the process of the default user.  Get rid of it.
10945                    providers.remove(i);
10946                    N--;
10947                    i--;
10948                    continue;
10949                }
10950
10951                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10952                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10953                if (cpr == null) {
10954                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10955                    mProviderMap.putProviderByClass(comp, cpr);
10956                }
10957                if (DEBUG_MU) Slog.v(TAG_MU,
10958                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10959                app.pubProviders.put(cpi.name, cpr);
10960                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10961                    // Don't add this if it is a platform component that is marked
10962                    // to run in multiple processes, because this is actually
10963                    // part of the framework so doesn't make sense to track as a
10964                    // separate apk in the process.
10965                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10966                            mProcessStats);
10967                }
10968                notifyPackageUse(cpi.applicationInfo.packageName,
10969                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10970            }
10971        }
10972        return providers;
10973    }
10974
10975    /**
10976     * Check if the calling UID has a possible chance at accessing the provider
10977     * at the given authority and user.
10978     */
10979    public String checkContentProviderAccess(String authority, int userId) {
10980        if (userId == UserHandle.USER_ALL) {
10981            mContext.enforceCallingOrSelfPermission(
10982                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10983            userId = UserHandle.getCallingUserId();
10984        }
10985
10986        ProviderInfo cpi = null;
10987        try {
10988            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10989                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10990                            | PackageManager.MATCH_DISABLED_COMPONENTS
10991                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10992                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10993                    userId);
10994        } catch (RemoteException ignored) {
10995        }
10996        if (cpi == null) {
10997            return "Failed to find provider " + authority + " for user " + userId
10998                    + "; expected to find a valid ContentProvider for this authority";
10999        }
11000
11001        ProcessRecord r = null;
11002        synchronized (mPidsSelfLocked) {
11003            r = mPidsSelfLocked.get(Binder.getCallingPid());
11004        }
11005        if (r == null) {
11006            return "Failed to find PID " + Binder.getCallingPid();
11007        }
11008
11009        synchronized (this) {
11010            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11011        }
11012    }
11013
11014    /**
11015     * Check if {@link ProcessRecord} has a possible chance at accessing the
11016     * given {@link ProviderInfo}. Final permission checking is always done
11017     * in {@link ContentProvider}.
11018     */
11019    private final String checkContentProviderPermissionLocked(
11020            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11021        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11022        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11023        boolean checkedGrants = false;
11024        if (checkUser) {
11025            // Looking for cross-user grants before enforcing the typical cross-users permissions
11026            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11027            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11028                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11029                    return null;
11030                }
11031                checkedGrants = true;
11032            }
11033            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11034                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11035            if (userId != tmpTargetUserId) {
11036                // When we actually went to determine the final targer user ID, this ended
11037                // up different than our initial check for the authority.  This is because
11038                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11039                // SELF.  So we need to re-check the grants again.
11040                checkedGrants = false;
11041            }
11042        }
11043        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11044                cpi.applicationInfo.uid, cpi.exported)
11045                == PackageManager.PERMISSION_GRANTED) {
11046            return null;
11047        }
11048        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11049                cpi.applicationInfo.uid, cpi.exported)
11050                == PackageManager.PERMISSION_GRANTED) {
11051            return null;
11052        }
11053
11054        PathPermission[] pps = cpi.pathPermissions;
11055        if (pps != null) {
11056            int i = pps.length;
11057            while (i > 0) {
11058                i--;
11059                PathPermission pp = pps[i];
11060                String pprperm = pp.getReadPermission();
11061                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11062                        cpi.applicationInfo.uid, cpi.exported)
11063                        == PackageManager.PERMISSION_GRANTED) {
11064                    return null;
11065                }
11066                String ppwperm = pp.getWritePermission();
11067                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11068                        cpi.applicationInfo.uid, cpi.exported)
11069                        == PackageManager.PERMISSION_GRANTED) {
11070                    return null;
11071                }
11072            }
11073        }
11074        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11075            return null;
11076        }
11077
11078        final String suffix;
11079        if (!cpi.exported) {
11080            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11081        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11082            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11083        } else {
11084            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11085        }
11086        final String msg = "Permission Denial: opening provider " + cpi.name
11087                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11088                + ", uid=" + callingUid + ")" + suffix;
11089        Slog.w(TAG, msg);
11090        return msg;
11091    }
11092
11093    /**
11094     * Returns if the ContentProvider has granted a uri to callingUid
11095     */
11096    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11097        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11098        if (perms != null) {
11099            for (int i=perms.size()-1; i>=0; i--) {
11100                GrantUri grantUri = perms.keyAt(i);
11101                if (grantUri.sourceUserId == userId || !checkUser) {
11102                    if (matchesProvider(grantUri.uri, cpi)) {
11103                        return true;
11104                    }
11105                }
11106            }
11107        }
11108        return false;
11109    }
11110
11111    /**
11112     * Returns true if the uri authority is one of the authorities specified in the provider.
11113     */
11114    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11115        String uriAuth = uri.getAuthority();
11116        String cpiAuth = cpi.authority;
11117        if (cpiAuth.indexOf(';') == -1) {
11118            return cpiAuth.equals(uriAuth);
11119        }
11120        String[] cpiAuths = cpiAuth.split(";");
11121        int length = cpiAuths.length;
11122        for (int i = 0; i < length; i++) {
11123            if (cpiAuths[i].equals(uriAuth)) return true;
11124        }
11125        return false;
11126    }
11127
11128    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11129            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11130        if (r != null) {
11131            for (int i=0; i<r.conProviders.size(); i++) {
11132                ContentProviderConnection conn = r.conProviders.get(i);
11133                if (conn.provider == cpr) {
11134                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11135                            "Adding provider requested by "
11136                            + r.processName + " from process "
11137                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11138                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11139                    if (stable) {
11140                        conn.stableCount++;
11141                        conn.numStableIncs++;
11142                    } else {
11143                        conn.unstableCount++;
11144                        conn.numUnstableIncs++;
11145                    }
11146                    return conn;
11147                }
11148            }
11149            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11150            if (stable) {
11151                conn.stableCount = 1;
11152                conn.numStableIncs = 1;
11153            } else {
11154                conn.unstableCount = 1;
11155                conn.numUnstableIncs = 1;
11156            }
11157            cpr.connections.add(conn);
11158            r.conProviders.add(conn);
11159            startAssociationLocked(r.uid, r.processName, r.curProcState,
11160                    cpr.uid, cpr.name, cpr.info.processName);
11161            return conn;
11162        }
11163        cpr.addExternalProcessHandleLocked(externalProcessToken);
11164        return null;
11165    }
11166
11167    boolean decProviderCountLocked(ContentProviderConnection conn,
11168            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11169        if (conn != null) {
11170            cpr = conn.provider;
11171            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11172                    "Removing provider requested by "
11173                    + conn.client.processName + " from process "
11174                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11175                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11176            if (stable) {
11177                conn.stableCount--;
11178            } else {
11179                conn.unstableCount--;
11180            }
11181            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11182                cpr.connections.remove(conn);
11183                conn.client.conProviders.remove(conn);
11184                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11185                    // The client is more important than last activity -- note the time this
11186                    // is happening, so we keep the old provider process around a bit as last
11187                    // activity to avoid thrashing it.
11188                    if (cpr.proc != null) {
11189                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11190                    }
11191                }
11192                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11193                return true;
11194            }
11195            return false;
11196        }
11197        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11198        return false;
11199    }
11200
11201    private void checkTime(long startTime, String where) {
11202        long now = SystemClock.uptimeMillis();
11203        if ((now-startTime) > 50) {
11204            // If we are taking more than 50ms, log about it.
11205            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11206        }
11207    }
11208
11209    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11210            PROC_SPACE_TERM,
11211            PROC_SPACE_TERM|PROC_PARENS,
11212            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11213    };
11214
11215    private final long[] mProcessStateStatsLongs = new long[1];
11216
11217    boolean isProcessAliveLocked(ProcessRecord proc) {
11218        if (proc.procStatFile == null) {
11219            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11220        }
11221        mProcessStateStatsLongs[0] = 0;
11222        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11223                mProcessStateStatsLongs, null)) {
11224            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11225            return false;
11226        }
11227        final long state = mProcessStateStatsLongs[0];
11228        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11229                + (char)state);
11230        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11231    }
11232
11233    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11234            String name, IBinder token, boolean stable, int userId) {
11235        ContentProviderRecord cpr;
11236        ContentProviderConnection conn = null;
11237        ProviderInfo cpi = null;
11238
11239        synchronized(this) {
11240            long startTime = SystemClock.uptimeMillis();
11241
11242            ProcessRecord r = null;
11243            if (caller != null) {
11244                r = getRecordForAppLocked(caller);
11245                if (r == null) {
11246                    throw new SecurityException(
11247                            "Unable to find app for caller " + caller
11248                          + " (pid=" + Binder.getCallingPid()
11249                          + ") when getting content provider " + name);
11250                }
11251            }
11252
11253            boolean checkCrossUser = true;
11254
11255            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11256
11257            // First check if this content provider has been published...
11258            cpr = mProviderMap.getProviderByName(name, userId);
11259            // If that didn't work, check if it exists for user 0 and then
11260            // verify that it's a singleton provider before using it.
11261            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11262                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11263                if (cpr != null) {
11264                    cpi = cpr.info;
11265                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11266                            cpi.name, cpi.flags)
11267                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11268                        userId = UserHandle.USER_SYSTEM;
11269                        checkCrossUser = false;
11270                    } else {
11271                        cpr = null;
11272                        cpi = null;
11273                    }
11274                }
11275            }
11276
11277            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11278            if (providerRunning) {
11279                cpi = cpr.info;
11280                String msg;
11281                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11282                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11283                        != null) {
11284                    throw new SecurityException(msg);
11285                }
11286                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11287
11288                if (r != null && cpr.canRunHere(r)) {
11289                    // This provider has been published or is in the process
11290                    // of being published...  but it is also allowed to run
11291                    // in the caller's process, so don't make a connection
11292                    // and just let the caller instantiate its own instance.
11293                    ContentProviderHolder holder = cpr.newHolder(null);
11294                    // don't give caller the provider object, it needs
11295                    // to make its own.
11296                    holder.provider = null;
11297                    return holder;
11298                }
11299                // Don't expose providers between normal apps and instant apps
11300                try {
11301                    if (AppGlobals.getPackageManager()
11302                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11303                        return null;
11304                    }
11305                } catch (RemoteException e) {
11306                }
11307
11308                final long origId = Binder.clearCallingIdentity();
11309
11310                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11311
11312                // In this case the provider instance already exists, so we can
11313                // return it right away.
11314                conn = incProviderCountLocked(r, cpr, token, stable);
11315                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11316                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11317                        // If this is a perceptible app accessing the provider,
11318                        // make sure to count it as being accessed and thus
11319                        // back up on the LRU list.  This is good because
11320                        // content providers are often expensive to start.
11321                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11322                        updateLruProcessLocked(cpr.proc, false, null);
11323                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11324                    }
11325                }
11326
11327                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11328                final int verifiedAdj = cpr.proc.verifiedAdj;
11329                boolean success = updateOomAdjLocked(cpr.proc, true);
11330                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11331                // if the process has been successfully adjusted.  So to reduce races with
11332                // it, we will check whether the process still exists.  Note that this doesn't
11333                // completely get rid of races with LMK killing the process, but should make
11334                // them much smaller.
11335                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11336                    success = false;
11337                }
11338                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11339                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11340                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11341                // NOTE: there is still a race here where a signal could be
11342                // pending on the process even though we managed to update its
11343                // adj level.  Not sure what to do about this, but at least
11344                // the race is now smaller.
11345                if (!success) {
11346                    // Uh oh...  it looks like the provider's process
11347                    // has been killed on us.  We need to wait for a new
11348                    // process to be started, and make sure its death
11349                    // doesn't kill our process.
11350                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11351                            + " is crashing; detaching " + r);
11352                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11353                    checkTime(startTime, "getContentProviderImpl: before appDied");
11354                    appDiedLocked(cpr.proc);
11355                    checkTime(startTime, "getContentProviderImpl: after appDied");
11356                    if (!lastRef) {
11357                        // This wasn't the last ref our process had on
11358                        // the provider...  we have now been killed, bail.
11359                        return null;
11360                    }
11361                    providerRunning = false;
11362                    conn = null;
11363                } else {
11364                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11365                }
11366
11367                Binder.restoreCallingIdentity(origId);
11368            }
11369
11370            if (!providerRunning) {
11371                try {
11372                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11373                    cpi = AppGlobals.getPackageManager().
11374                        resolveContentProvider(name,
11375                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11376                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11377                } catch (RemoteException ex) {
11378                }
11379                if (cpi == null) {
11380                    return null;
11381                }
11382                // If the provider is a singleton AND
11383                // (it's a call within the same user || the provider is a
11384                // privileged app)
11385                // Then allow connecting to the singleton provider
11386                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11387                        cpi.name, cpi.flags)
11388                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11389                if (singleton) {
11390                    userId = UserHandle.USER_SYSTEM;
11391                }
11392                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11393                checkTime(startTime, "getContentProviderImpl: got app info for user");
11394
11395                String msg;
11396                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11397                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11398                        != null) {
11399                    throw new SecurityException(msg);
11400                }
11401                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11402
11403                if (!mProcessesReady
11404                        && !cpi.processName.equals("system")) {
11405                    // If this content provider does not run in the system
11406                    // process, and the system is not yet ready to run other
11407                    // processes, then fail fast instead of hanging.
11408                    throw new IllegalArgumentException(
11409                            "Attempt to launch content provider before system ready");
11410                }
11411
11412                // Make sure that the user who owns this provider is running.  If not,
11413                // we don't want to allow it to run.
11414                if (!mUserController.isUserRunningLocked(userId, 0)) {
11415                    Slog.w(TAG, "Unable to launch app "
11416                            + cpi.applicationInfo.packageName + "/"
11417                            + cpi.applicationInfo.uid + " for provider "
11418                            + name + ": user " + userId + " is stopped");
11419                    return null;
11420                }
11421
11422                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11423                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11424                cpr = mProviderMap.getProviderByClass(comp, userId);
11425                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11426                final boolean firstClass = cpr == null;
11427                if (firstClass) {
11428                    final long ident = Binder.clearCallingIdentity();
11429
11430                    // If permissions need a review before any of the app components can run,
11431                    // we return no provider and launch a review activity if the calling app
11432                    // is in the foreground.
11433                    if (mPermissionReviewRequired) {
11434                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11435                            return null;
11436                        }
11437                    }
11438
11439                    try {
11440                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11441                        ApplicationInfo ai =
11442                            AppGlobals.getPackageManager().
11443                                getApplicationInfo(
11444                                        cpi.applicationInfo.packageName,
11445                                        STOCK_PM_FLAGS, userId);
11446                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11447                        if (ai == null) {
11448                            Slog.w(TAG, "No package info for content provider "
11449                                    + cpi.name);
11450                            return null;
11451                        }
11452                        ai = getAppInfoForUser(ai, userId);
11453                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11454                    } catch (RemoteException ex) {
11455                        // pm is in same process, this will never happen.
11456                    } finally {
11457                        Binder.restoreCallingIdentity(ident);
11458                    }
11459                }
11460
11461                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11462
11463                if (r != null && cpr.canRunHere(r)) {
11464                    // If this is a multiprocess provider, then just return its
11465                    // info and allow the caller to instantiate it.  Only do
11466                    // this if the provider is the same user as the caller's
11467                    // process, or can run as root (so can be in any process).
11468                    return cpr.newHolder(null);
11469                }
11470
11471                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11472                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11473                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11474
11475                // This is single process, and our app is now connecting to it.
11476                // See if we are already in the process of launching this
11477                // provider.
11478                final int N = mLaunchingProviders.size();
11479                int i;
11480                for (i = 0; i < N; i++) {
11481                    if (mLaunchingProviders.get(i) == cpr) {
11482                        break;
11483                    }
11484                }
11485
11486                // If the provider is not already being launched, then get it
11487                // started.
11488                if (i >= N) {
11489                    final long origId = Binder.clearCallingIdentity();
11490
11491                    try {
11492                        // Content provider is now in use, its package can't be stopped.
11493                        try {
11494                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11495                            AppGlobals.getPackageManager().setPackageStoppedState(
11496                                    cpr.appInfo.packageName, false, userId);
11497                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11498                        } catch (RemoteException e) {
11499                        } catch (IllegalArgumentException e) {
11500                            Slog.w(TAG, "Failed trying to unstop package "
11501                                    + cpr.appInfo.packageName + ": " + e);
11502                        }
11503
11504                        // Use existing process if already started
11505                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11506                        ProcessRecord proc = getProcessRecordLocked(
11507                                cpi.processName, cpr.appInfo.uid, false);
11508                        if (proc != null && proc.thread != null && !proc.killed) {
11509                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11510                                    "Installing in existing process " + proc);
11511                            if (!proc.pubProviders.containsKey(cpi.name)) {
11512                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11513                                proc.pubProviders.put(cpi.name, cpr);
11514                                try {
11515                                    proc.thread.scheduleInstallProvider(cpi);
11516                                } catch (RemoteException e) {
11517                                }
11518                            }
11519                        } else {
11520                            checkTime(startTime, "getContentProviderImpl: before start process");
11521                            proc = startProcessLocked(cpi.processName,
11522                                    cpr.appInfo, false, 0, "content provider",
11523                                    new ComponentName(cpi.applicationInfo.packageName,
11524                                            cpi.name), false, false, false);
11525                            checkTime(startTime, "getContentProviderImpl: after start process");
11526                            if (proc == null) {
11527                                Slog.w(TAG, "Unable to launch app "
11528                                        + cpi.applicationInfo.packageName + "/"
11529                                        + cpi.applicationInfo.uid + " for provider "
11530                                        + name + ": process is bad");
11531                                return null;
11532                            }
11533                        }
11534                        cpr.launchingApp = proc;
11535                        mLaunchingProviders.add(cpr);
11536                    } finally {
11537                        Binder.restoreCallingIdentity(origId);
11538                    }
11539                }
11540
11541                checkTime(startTime, "getContentProviderImpl: updating data structures");
11542
11543                // Make sure the provider is published (the same provider class
11544                // may be published under multiple names).
11545                if (firstClass) {
11546                    mProviderMap.putProviderByClass(comp, cpr);
11547                }
11548
11549                mProviderMap.putProviderByName(name, cpr);
11550                conn = incProviderCountLocked(r, cpr, token, stable);
11551                if (conn != null) {
11552                    conn.waiting = true;
11553                }
11554            }
11555            checkTime(startTime, "getContentProviderImpl: done!");
11556
11557            grantEphemeralAccessLocked(userId, null /*intent*/,
11558                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11559        }
11560
11561        // Wait for the provider to be published...
11562        synchronized (cpr) {
11563            while (cpr.provider == null) {
11564                if (cpr.launchingApp == null) {
11565                    Slog.w(TAG, "Unable to launch app "
11566                            + cpi.applicationInfo.packageName + "/"
11567                            + cpi.applicationInfo.uid + " for provider "
11568                            + name + ": launching app became null");
11569                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11570                            UserHandle.getUserId(cpi.applicationInfo.uid),
11571                            cpi.applicationInfo.packageName,
11572                            cpi.applicationInfo.uid, name);
11573                    return null;
11574                }
11575                try {
11576                    if (DEBUG_MU) Slog.v(TAG_MU,
11577                            "Waiting to start provider " + cpr
11578                            + " launchingApp=" + cpr.launchingApp);
11579                    if (conn != null) {
11580                        conn.waiting = true;
11581                    }
11582                    cpr.wait();
11583                } catch (InterruptedException ex) {
11584                } finally {
11585                    if (conn != null) {
11586                        conn.waiting = false;
11587                    }
11588                }
11589            }
11590        }
11591        return cpr != null ? cpr.newHolder(conn) : null;
11592    }
11593
11594    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11595            ProcessRecord r, final int userId) {
11596        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11597                cpi.packageName, userId)) {
11598
11599            final boolean callerForeground = r == null || r.setSchedGroup
11600                    != ProcessList.SCHED_GROUP_BACKGROUND;
11601
11602            // Show a permission review UI only for starting from a foreground app
11603            if (!callerForeground) {
11604                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11605                        + cpi.packageName + " requires a permissions review");
11606                return false;
11607            }
11608
11609            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11610            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11611                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11612            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11613
11614            if (DEBUG_PERMISSIONS_REVIEW) {
11615                Slog.i(TAG, "u" + userId + " Launching permission review "
11616                        + "for package " + cpi.packageName);
11617            }
11618
11619            final UserHandle userHandle = new UserHandle(userId);
11620            mHandler.post(new Runnable() {
11621                @Override
11622                public void run() {
11623                    mContext.startActivityAsUser(intent, userHandle);
11624                }
11625            });
11626
11627            return false;
11628        }
11629
11630        return true;
11631    }
11632
11633    PackageManagerInternal getPackageManagerInternalLocked() {
11634        if (mPackageManagerInt == null) {
11635            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11636        }
11637        return mPackageManagerInt;
11638    }
11639
11640    @Override
11641    public final ContentProviderHolder getContentProvider(
11642            IApplicationThread caller, String name, int userId, boolean stable) {
11643        enforceNotIsolatedCaller("getContentProvider");
11644        if (caller == null) {
11645            String msg = "null IApplicationThread when getting content provider "
11646                    + name;
11647            Slog.w(TAG, msg);
11648            throw new SecurityException(msg);
11649        }
11650        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11651        // with cross-user grant.
11652        return getContentProviderImpl(caller, name, null, stable, userId);
11653    }
11654
11655    public ContentProviderHolder getContentProviderExternal(
11656            String name, int userId, IBinder token) {
11657        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11658            "Do not have permission in call getContentProviderExternal()");
11659        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11660                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11661        return getContentProviderExternalUnchecked(name, token, userId);
11662    }
11663
11664    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11665            IBinder token, int userId) {
11666        return getContentProviderImpl(null, name, token, true, userId);
11667    }
11668
11669    /**
11670     * Drop a content provider from a ProcessRecord's bookkeeping
11671     */
11672    public void removeContentProvider(IBinder connection, boolean stable) {
11673        enforceNotIsolatedCaller("removeContentProvider");
11674        long ident = Binder.clearCallingIdentity();
11675        try {
11676            synchronized (this) {
11677                ContentProviderConnection conn;
11678                try {
11679                    conn = (ContentProviderConnection)connection;
11680                } catch (ClassCastException e) {
11681                    String msg ="removeContentProvider: " + connection
11682                            + " not a ContentProviderConnection";
11683                    Slog.w(TAG, msg);
11684                    throw new IllegalArgumentException(msg);
11685                }
11686                if (conn == null) {
11687                    throw new NullPointerException("connection is null");
11688                }
11689                if (decProviderCountLocked(conn, null, null, stable)) {
11690                    updateOomAdjLocked();
11691                }
11692            }
11693        } finally {
11694            Binder.restoreCallingIdentity(ident);
11695        }
11696    }
11697
11698    public void removeContentProviderExternal(String name, IBinder token) {
11699        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11700            "Do not have permission in call removeContentProviderExternal()");
11701        int userId = UserHandle.getCallingUserId();
11702        long ident = Binder.clearCallingIdentity();
11703        try {
11704            removeContentProviderExternalUnchecked(name, token, userId);
11705        } finally {
11706            Binder.restoreCallingIdentity(ident);
11707        }
11708    }
11709
11710    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11711        synchronized (this) {
11712            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11713            if(cpr == null) {
11714                //remove from mProvidersByClass
11715                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11716                return;
11717            }
11718
11719            //update content provider record entry info
11720            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11721            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11722            if (localCpr.hasExternalProcessHandles()) {
11723                if (localCpr.removeExternalProcessHandleLocked(token)) {
11724                    updateOomAdjLocked();
11725                } else {
11726                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11727                            + " with no external reference for token: "
11728                            + token + ".");
11729                }
11730            } else {
11731                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11732                        + " with no external references.");
11733            }
11734        }
11735    }
11736
11737    public final void publishContentProviders(IApplicationThread caller,
11738            List<ContentProviderHolder> providers) {
11739        if (providers == null) {
11740            return;
11741        }
11742
11743        enforceNotIsolatedCaller("publishContentProviders");
11744        synchronized (this) {
11745            final ProcessRecord r = getRecordForAppLocked(caller);
11746            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11747            if (r == null) {
11748                throw new SecurityException(
11749                        "Unable to find app for caller " + caller
11750                      + " (pid=" + Binder.getCallingPid()
11751                      + ") when publishing content providers");
11752            }
11753
11754            final long origId = Binder.clearCallingIdentity();
11755
11756            final int N = providers.size();
11757            for (int i = 0; i < N; i++) {
11758                ContentProviderHolder src = providers.get(i);
11759                if (src == null || src.info == null || src.provider == null) {
11760                    continue;
11761                }
11762                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11763                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11764                if (dst != null) {
11765                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11766                    mProviderMap.putProviderByClass(comp, dst);
11767                    String names[] = dst.info.authority.split(";");
11768                    for (int j = 0; j < names.length; j++) {
11769                        mProviderMap.putProviderByName(names[j], dst);
11770                    }
11771
11772                    int launchingCount = mLaunchingProviders.size();
11773                    int j;
11774                    boolean wasInLaunchingProviders = false;
11775                    for (j = 0; j < launchingCount; j++) {
11776                        if (mLaunchingProviders.get(j) == dst) {
11777                            mLaunchingProviders.remove(j);
11778                            wasInLaunchingProviders = true;
11779                            j--;
11780                            launchingCount--;
11781                        }
11782                    }
11783                    if (wasInLaunchingProviders) {
11784                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11785                    }
11786                    synchronized (dst) {
11787                        dst.provider = src.provider;
11788                        dst.proc = r;
11789                        dst.notifyAll();
11790                    }
11791                    updateOomAdjLocked(r, true);
11792                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11793                            src.info.authority);
11794                }
11795            }
11796
11797            Binder.restoreCallingIdentity(origId);
11798        }
11799    }
11800
11801    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11802        ContentProviderConnection conn;
11803        try {
11804            conn = (ContentProviderConnection)connection;
11805        } catch (ClassCastException e) {
11806            String msg ="refContentProvider: " + connection
11807                    + " not a ContentProviderConnection";
11808            Slog.w(TAG, msg);
11809            throw new IllegalArgumentException(msg);
11810        }
11811        if (conn == null) {
11812            throw new NullPointerException("connection is null");
11813        }
11814
11815        synchronized (this) {
11816            if (stable > 0) {
11817                conn.numStableIncs += stable;
11818            }
11819            stable = conn.stableCount + stable;
11820            if (stable < 0) {
11821                throw new IllegalStateException("stableCount < 0: " + stable);
11822            }
11823
11824            if (unstable > 0) {
11825                conn.numUnstableIncs += unstable;
11826            }
11827            unstable = conn.unstableCount + unstable;
11828            if (unstable < 0) {
11829                throw new IllegalStateException("unstableCount < 0: " + unstable);
11830            }
11831
11832            if ((stable+unstable) <= 0) {
11833                throw new IllegalStateException("ref counts can't go to zero here: stable="
11834                        + stable + " unstable=" + unstable);
11835            }
11836            conn.stableCount = stable;
11837            conn.unstableCount = unstable;
11838            return !conn.dead;
11839        }
11840    }
11841
11842    public void unstableProviderDied(IBinder connection) {
11843        ContentProviderConnection conn;
11844        try {
11845            conn = (ContentProviderConnection)connection;
11846        } catch (ClassCastException e) {
11847            String msg ="refContentProvider: " + connection
11848                    + " not a ContentProviderConnection";
11849            Slog.w(TAG, msg);
11850            throw new IllegalArgumentException(msg);
11851        }
11852        if (conn == null) {
11853            throw new NullPointerException("connection is null");
11854        }
11855
11856        // Safely retrieve the content provider associated with the connection.
11857        IContentProvider provider;
11858        synchronized (this) {
11859            provider = conn.provider.provider;
11860        }
11861
11862        if (provider == null) {
11863            // Um, yeah, we're way ahead of you.
11864            return;
11865        }
11866
11867        // Make sure the caller is being honest with us.
11868        if (provider.asBinder().pingBinder()) {
11869            // Er, no, still looks good to us.
11870            synchronized (this) {
11871                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11872                        + " says " + conn + " died, but we don't agree");
11873                return;
11874            }
11875        }
11876
11877        // Well look at that!  It's dead!
11878        synchronized (this) {
11879            if (conn.provider.provider != provider) {
11880                // But something changed...  good enough.
11881                return;
11882            }
11883
11884            ProcessRecord proc = conn.provider.proc;
11885            if (proc == null || proc.thread == null) {
11886                // Seems like the process is already cleaned up.
11887                return;
11888            }
11889
11890            // As far as we're concerned, this is just like receiving a
11891            // death notification...  just a bit prematurely.
11892            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11893                    + ") early provider death");
11894            final long ident = Binder.clearCallingIdentity();
11895            try {
11896                appDiedLocked(proc);
11897            } finally {
11898                Binder.restoreCallingIdentity(ident);
11899            }
11900        }
11901    }
11902
11903    @Override
11904    public void appNotRespondingViaProvider(IBinder connection) {
11905        enforceCallingPermission(
11906                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11907
11908        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11909        if (conn == null) {
11910            Slog.w(TAG, "ContentProviderConnection is null");
11911            return;
11912        }
11913
11914        final ProcessRecord host = conn.provider.proc;
11915        if (host == null) {
11916            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11917            return;
11918        }
11919
11920        mHandler.post(new Runnable() {
11921            @Override
11922            public void run() {
11923                mAppErrors.appNotResponding(host, null, null, false,
11924                        "ContentProvider not responding");
11925            }
11926        });
11927    }
11928
11929    public final void installSystemProviders() {
11930        List<ProviderInfo> providers;
11931        synchronized (this) {
11932            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
11933            providers = generateApplicationProvidersLocked(app);
11934            if (providers != null) {
11935                for (int i=providers.size()-1; i>=0; i--) {
11936                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11937                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11938                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11939                                + ": not system .apk");
11940                        providers.remove(i);
11941                    }
11942                }
11943            }
11944        }
11945        if (providers != null) {
11946            mSystemThread.installSystemProviders(providers);
11947        }
11948
11949        mConstants.start(mContext.getContentResolver());
11950        mCoreSettingsObserver = new CoreSettingsObserver(this);
11951        mFontScaleSettingObserver = new FontScaleSettingObserver();
11952
11953        // Now that the settings provider is published we can consider sending
11954        // in a rescue party.
11955        RescueParty.onSettingsProviderPublished(mContext);
11956
11957        //mUsageStatsService.monitorPackages();
11958    }
11959
11960    private void startPersistentApps(int matchFlags) {
11961        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11962
11963        synchronized (this) {
11964            try {
11965                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11966                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11967                for (ApplicationInfo app : apps) {
11968                    if (!"android".equals(app.packageName)) {
11969                        addAppLocked(app, null, false, null /* ABI override */);
11970                    }
11971                }
11972            } catch (RemoteException ex) {
11973            }
11974        }
11975    }
11976
11977    /**
11978     * When a user is unlocked, we need to install encryption-unaware providers
11979     * belonging to any running apps.
11980     */
11981    private void installEncryptionUnawareProviders(int userId) {
11982        // We're only interested in providers that are encryption unaware, and
11983        // we don't care about uninstalled apps, since there's no way they're
11984        // running at this point.
11985        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11986
11987        synchronized (this) {
11988            final int NP = mProcessNames.getMap().size();
11989            for (int ip = 0; ip < NP; ip++) {
11990                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11991                final int NA = apps.size();
11992                for (int ia = 0; ia < NA; ia++) {
11993                    final ProcessRecord app = apps.valueAt(ia);
11994                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11995
11996                    final int NG = app.pkgList.size();
11997                    for (int ig = 0; ig < NG; ig++) {
11998                        try {
11999                            final String pkgName = app.pkgList.keyAt(ig);
12000                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12001                                    .getPackageInfo(pkgName, matchFlags, userId);
12002                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12003                                for (ProviderInfo pi : pkgInfo.providers) {
12004                                    // TODO: keep in sync with generateApplicationProvidersLocked
12005                                    final boolean processMatch = Objects.equals(pi.processName,
12006                                            app.processName) || pi.multiprocess;
12007                                    final boolean userMatch = isSingleton(pi.processName,
12008                                            pi.applicationInfo, pi.name, pi.flags)
12009                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12010                                    if (processMatch && userMatch) {
12011                                        Log.v(TAG, "Installing " + pi);
12012                                        app.thread.scheduleInstallProvider(pi);
12013                                    } else {
12014                                        Log.v(TAG, "Skipping " + pi);
12015                                    }
12016                                }
12017                            }
12018                        } catch (RemoteException ignored) {
12019                        }
12020                    }
12021                }
12022            }
12023        }
12024    }
12025
12026    /**
12027     * Allows apps to retrieve the MIME type of a URI.
12028     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12029     * users, then it does not need permission to access the ContentProvider.
12030     * Either, it needs cross-user uri grants.
12031     *
12032     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12033     *
12034     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12035     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12036     */
12037    public String getProviderMimeType(Uri uri, int userId) {
12038        enforceNotIsolatedCaller("getProviderMimeType");
12039        final String name = uri.getAuthority();
12040        int callingUid = Binder.getCallingUid();
12041        int callingPid = Binder.getCallingPid();
12042        long ident = 0;
12043        boolean clearedIdentity = false;
12044        synchronized (this) {
12045            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12046        }
12047        if (canClearIdentity(callingPid, callingUid, userId)) {
12048            clearedIdentity = true;
12049            ident = Binder.clearCallingIdentity();
12050        }
12051        ContentProviderHolder holder = null;
12052        try {
12053            holder = getContentProviderExternalUnchecked(name, null, userId);
12054            if (holder != null) {
12055                return holder.provider.getType(uri);
12056            }
12057        } catch (RemoteException e) {
12058            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12059            return null;
12060        } catch (Exception e) {
12061            Log.w(TAG, "Exception while determining type of " + uri, e);
12062            return null;
12063        } finally {
12064            // We need to clear the identity to call removeContentProviderExternalUnchecked
12065            if (!clearedIdentity) {
12066                ident = Binder.clearCallingIdentity();
12067            }
12068            try {
12069                if (holder != null) {
12070                    removeContentProviderExternalUnchecked(name, null, userId);
12071                }
12072            } finally {
12073                Binder.restoreCallingIdentity(ident);
12074            }
12075        }
12076
12077        return null;
12078    }
12079
12080    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12081        if (UserHandle.getUserId(callingUid) == userId) {
12082            return true;
12083        }
12084        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12085                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12086                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12087                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12088                return true;
12089        }
12090        return false;
12091    }
12092
12093    // =========================================================
12094    // GLOBAL MANAGEMENT
12095    // =========================================================
12096
12097    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12098            boolean isolated, int isolatedUid) {
12099        String proc = customProcess != null ? customProcess : info.processName;
12100        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12101        final int userId = UserHandle.getUserId(info.uid);
12102        int uid = info.uid;
12103        if (isolated) {
12104            if (isolatedUid == 0) {
12105                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12106                while (true) {
12107                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12108                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12109                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12110                    }
12111                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12112                    mNextIsolatedProcessUid++;
12113                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12114                        // No process for this uid, use it.
12115                        break;
12116                    }
12117                    stepsLeft--;
12118                    if (stepsLeft <= 0) {
12119                        return null;
12120                    }
12121                }
12122            } else {
12123                // Special case for startIsolatedProcess (internal only), where
12124                // the uid of the isolated process is specified by the caller.
12125                uid = isolatedUid;
12126            }
12127            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12128
12129            // Register the isolated UID with this application so BatteryStats knows to
12130            // attribute resource usage to the application.
12131            //
12132            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12133            // about the process state of the isolated UID *before* it is registered with the
12134            // owning application.
12135            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12136        }
12137        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12138        if (!mBooted && !mBooting
12139                && userId == UserHandle.USER_SYSTEM
12140                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12141            r.persistent = true;
12142            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12143        }
12144        addProcessNameLocked(r);
12145        return r;
12146    }
12147
12148    private boolean uidOnBackgroundWhitelist(final int uid) {
12149        final int appId = UserHandle.getAppId(uid);
12150        final int[] whitelist = mBackgroundAppIdWhitelist;
12151        final int N = whitelist.length;
12152        for (int i = 0; i < N; i++) {
12153            if (appId == whitelist[i]) {
12154                return true;
12155            }
12156        }
12157        return false;
12158    }
12159
12160    @Override
12161    public void backgroundWhitelistUid(final int uid) {
12162        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12163            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12164        }
12165
12166        if (DEBUG_BACKGROUND_CHECK) {
12167            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12168        }
12169        synchronized (this) {
12170            final int N = mBackgroundAppIdWhitelist.length;
12171            int[] newList = new int[N+1];
12172            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12173            newList[N] = UserHandle.getAppId(uid);
12174            mBackgroundAppIdWhitelist = newList;
12175        }
12176    }
12177
12178    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12179            String abiOverride) {
12180        ProcessRecord app;
12181        if (!isolated) {
12182            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12183                    info.uid, true);
12184        } else {
12185            app = null;
12186        }
12187
12188        if (app == null) {
12189            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12190            updateLruProcessLocked(app, false, null);
12191            updateOomAdjLocked();
12192        }
12193
12194        // This package really, really can not be stopped.
12195        try {
12196            AppGlobals.getPackageManager().setPackageStoppedState(
12197                    info.packageName, false, UserHandle.getUserId(app.uid));
12198        } catch (RemoteException e) {
12199        } catch (IllegalArgumentException e) {
12200            Slog.w(TAG, "Failed trying to unstop package "
12201                    + info.packageName + ": " + e);
12202        }
12203
12204        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12205            app.persistent = true;
12206            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12207        }
12208        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12209            mPersistentStartingProcesses.add(app);
12210            startProcessLocked(app, "added application",
12211                    customProcess != null ? customProcess : app.processName, abiOverride,
12212                    null /* entryPoint */, null /* entryPointArgs */);
12213        }
12214
12215        return app;
12216    }
12217
12218    public void unhandledBack() {
12219        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12220                "unhandledBack()");
12221
12222        synchronized(this) {
12223            final long origId = Binder.clearCallingIdentity();
12224            try {
12225                getFocusedStack().unhandledBackLocked();
12226            } finally {
12227                Binder.restoreCallingIdentity(origId);
12228            }
12229        }
12230    }
12231
12232    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12233        enforceNotIsolatedCaller("openContentUri");
12234        final int userId = UserHandle.getCallingUserId();
12235        final Uri uri = Uri.parse(uriString);
12236        String name = uri.getAuthority();
12237        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12238        ParcelFileDescriptor pfd = null;
12239        if (cph != null) {
12240            // We record the binder invoker's uid in thread-local storage before
12241            // going to the content provider to open the file.  Later, in the code
12242            // that handles all permissions checks, we look for this uid and use
12243            // that rather than the Activity Manager's own uid.  The effect is that
12244            // we do the check against the caller's permissions even though it looks
12245            // to the content provider like the Activity Manager itself is making
12246            // the request.
12247            Binder token = new Binder();
12248            sCallerIdentity.set(new Identity(
12249                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12250            try {
12251                pfd = cph.provider.openFile(null, uri, "r", null, token);
12252            } catch (FileNotFoundException e) {
12253                // do nothing; pfd will be returned null
12254            } finally {
12255                // Ensure that whatever happens, we clean up the identity state
12256                sCallerIdentity.remove();
12257                // Ensure we're done with the provider.
12258                removeContentProviderExternalUnchecked(name, null, userId);
12259            }
12260        } else {
12261            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12262        }
12263        return pfd;
12264    }
12265
12266    // Actually is sleeping or shutting down or whatever else in the future
12267    // is an inactive state.
12268    boolean isSleepingOrShuttingDownLocked() {
12269        return isSleepingLocked() || mShuttingDown;
12270    }
12271
12272    boolean isShuttingDownLocked() {
12273        return mShuttingDown;
12274    }
12275
12276    boolean isSleepingLocked() {
12277        return mSleeping;
12278    }
12279
12280    void onWakefulnessChanged(int wakefulness) {
12281        synchronized(this) {
12282            mWakefulness = wakefulness;
12283            updateSleepIfNeededLocked();
12284        }
12285    }
12286
12287    void finishRunningVoiceLocked() {
12288        if (mRunningVoice != null) {
12289            mRunningVoice = null;
12290            mVoiceWakeLock.release();
12291            updateSleepIfNeededLocked();
12292        }
12293    }
12294
12295    void startTimeTrackingFocusedActivityLocked() {
12296        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12297        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12298            mCurAppTimeTracker.start(resumedActivity.packageName);
12299        }
12300    }
12301
12302    void updateSleepIfNeededLocked() {
12303        final boolean shouldSleep = shouldSleepLocked();
12304        if (mSleeping && !shouldSleep) {
12305            mSleeping = false;
12306            startTimeTrackingFocusedActivityLocked();
12307            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12308            mStackSupervisor.comeOutOfSleepIfNeededLocked();
12309            sendNotifyVrManagerOfSleepState(false);
12310            updateOomAdjLocked();
12311        } else if (!mSleeping && shouldSleep) {
12312            mSleeping = true;
12313            if (mCurAppTimeTracker != null) {
12314                mCurAppTimeTracker.stop();
12315            }
12316            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12317            mStackSupervisor.goingToSleepLocked();
12318            sendNotifyVrManagerOfSleepState(true);
12319            updateOomAdjLocked();
12320
12321            // Initialize the wake times of all processes.
12322            checkExcessivePowerUsageLocked(false);
12323            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12324            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12325            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
12326        }
12327
12328        // Also update state in a special way for running foreground services UI.
12329        switch (mWakefulness) {
12330            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12331            case PowerManagerInternal.WAKEFULNESS_DREAMING:
12332            case PowerManagerInternal.WAKEFULNESS_DOZING:
12333                mServices.updateScreenStateLocked(false);
12334                break;
12335            case PowerManagerInternal.WAKEFULNESS_AWAKE:
12336            default:
12337                mServices.updateScreenStateLocked(true);
12338                break;
12339        }
12340    }
12341
12342    private boolean shouldSleepLocked() {
12343        // Resume applications while running a voice interactor.
12344        if (mRunningVoice != null) {
12345            return false;
12346        }
12347
12348        // TODO: Transform the lock screen state into a sleep token instead.
12349        switch (mWakefulness) {
12350            case PowerManagerInternal.WAKEFULNESS_AWAKE:
12351            case PowerManagerInternal.WAKEFULNESS_DREAMING:
12352            case PowerManagerInternal.WAKEFULNESS_DOZING:
12353                // Pause applications whenever the lock screen is shown or any sleep
12354                // tokens have been acquired.
12355                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12356            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12357            default:
12358                // If we're asleep then pause applications unconditionally.
12359                return true;
12360        }
12361    }
12362
12363    /** Pokes the task persister. */
12364    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12365        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12366    }
12367
12368    /**
12369     * Notifies all listeners when the pinned stack animation starts.
12370     */
12371    @Override
12372    public void notifyPinnedStackAnimationStarted() {
12373        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12374    }
12375
12376    /**
12377     * Notifies all listeners when the pinned stack animation ends.
12378     */
12379    @Override
12380    public void notifyPinnedStackAnimationEnded() {
12381        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12382    }
12383
12384    @Override
12385    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12386        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12387    }
12388
12389    @Override
12390    public boolean shutdown(int timeout) {
12391        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12392                != PackageManager.PERMISSION_GRANTED) {
12393            throw new SecurityException("Requires permission "
12394                    + android.Manifest.permission.SHUTDOWN);
12395        }
12396
12397        boolean timedout = false;
12398
12399        synchronized(this) {
12400            mShuttingDown = true;
12401            updateEventDispatchingLocked();
12402            timedout = mStackSupervisor.shutdownLocked(timeout);
12403        }
12404
12405        mAppOpsService.shutdown();
12406        if (mUsageStatsService != null) {
12407            mUsageStatsService.prepareShutdown();
12408        }
12409        mBatteryStatsService.shutdown();
12410        synchronized (this) {
12411            mProcessStats.shutdownLocked();
12412            notifyTaskPersisterLocked(null, true);
12413        }
12414
12415        return timedout;
12416    }
12417
12418    public final void activitySlept(IBinder token) {
12419        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12420
12421        final long origId = Binder.clearCallingIdentity();
12422
12423        synchronized (this) {
12424            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12425            if (r != null) {
12426                mStackSupervisor.activitySleptLocked(r);
12427            }
12428        }
12429
12430        Binder.restoreCallingIdentity(origId);
12431    }
12432
12433    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12434        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12435        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12436        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12437            boolean wasRunningVoice = mRunningVoice != null;
12438            mRunningVoice = session;
12439            if (!wasRunningVoice) {
12440                mVoiceWakeLock.acquire();
12441                updateSleepIfNeededLocked();
12442            }
12443        }
12444    }
12445
12446    private void updateEventDispatchingLocked() {
12447        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12448    }
12449
12450    @Override
12451    public void setLockScreenShown(boolean showing) {
12452        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12453                != PackageManager.PERMISSION_GRANTED) {
12454            throw new SecurityException("Requires permission "
12455                    + android.Manifest.permission.DEVICE_POWER);
12456        }
12457
12458        synchronized(this) {
12459            long ident = Binder.clearCallingIdentity();
12460            try {
12461                mKeyguardController.setKeyguardShown(showing);
12462            } finally {
12463                Binder.restoreCallingIdentity(ident);
12464            }
12465        }
12466    }
12467
12468    @Override
12469    public void notifyLockedProfile(@UserIdInt int userId) {
12470        try {
12471            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12472                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12473            }
12474        } catch (RemoteException ex) {
12475            throw new SecurityException("Fail to check is caller a privileged app", ex);
12476        }
12477
12478        synchronized (this) {
12479            final long ident = Binder.clearCallingIdentity();
12480            try {
12481                if (mUserController.shouldConfirmCredentials(userId)) {
12482                    if (mKeyguardController.isKeyguardLocked()) {
12483                        // Showing launcher to avoid user entering credential twice.
12484                        final int currentUserId = mUserController.getCurrentUserIdLocked();
12485                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12486                    }
12487                    mStackSupervisor.lockAllProfileTasks(userId);
12488                }
12489            } finally {
12490                Binder.restoreCallingIdentity(ident);
12491            }
12492        }
12493    }
12494
12495    @Override
12496    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12497        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12498        synchronized (this) {
12499            final long ident = Binder.clearCallingIdentity();
12500            try {
12501                mActivityStarter.startConfirmCredentialIntent(intent, options);
12502            } finally {
12503                Binder.restoreCallingIdentity(ident);
12504            }
12505        }
12506    }
12507
12508    @Override
12509    public void stopAppSwitches() {
12510        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12511                != PackageManager.PERMISSION_GRANTED) {
12512            throw new SecurityException("viewquires permission "
12513                    + android.Manifest.permission.STOP_APP_SWITCHES);
12514        }
12515
12516        synchronized(this) {
12517            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12518                    + APP_SWITCH_DELAY_TIME;
12519            mDidAppSwitch = false;
12520            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12521            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12522            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12523        }
12524    }
12525
12526    public void resumeAppSwitches() {
12527        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12528                != PackageManager.PERMISSION_GRANTED) {
12529            throw new SecurityException("Requires permission "
12530                    + android.Manifest.permission.STOP_APP_SWITCHES);
12531        }
12532
12533        synchronized(this) {
12534            // Note that we don't execute any pending app switches... we will
12535            // let those wait until either the timeout, or the next start
12536            // activity request.
12537            mAppSwitchesAllowedTime = 0;
12538        }
12539    }
12540
12541    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12542            int callingPid, int callingUid, String name) {
12543        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12544            return true;
12545        }
12546
12547        int perm = checkComponentPermission(
12548                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12549                sourceUid, -1, true);
12550        if (perm == PackageManager.PERMISSION_GRANTED) {
12551            return true;
12552        }
12553
12554        // If the actual IPC caller is different from the logical source, then
12555        // also see if they are allowed to control app switches.
12556        if (callingUid != -1 && callingUid != sourceUid) {
12557            perm = checkComponentPermission(
12558                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12559                    callingUid, -1, true);
12560            if (perm == PackageManager.PERMISSION_GRANTED) {
12561                return true;
12562            }
12563        }
12564
12565        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12566        return false;
12567    }
12568
12569    public void setDebugApp(String packageName, boolean waitForDebugger,
12570            boolean persistent) {
12571        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12572                "setDebugApp()");
12573
12574        long ident = Binder.clearCallingIdentity();
12575        try {
12576            // Note that this is not really thread safe if there are multiple
12577            // callers into it at the same time, but that's not a situation we
12578            // care about.
12579            if (persistent) {
12580                final ContentResolver resolver = mContext.getContentResolver();
12581                Settings.Global.putString(
12582                    resolver, Settings.Global.DEBUG_APP,
12583                    packageName);
12584                Settings.Global.putInt(
12585                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12586                    waitForDebugger ? 1 : 0);
12587            }
12588
12589            synchronized (this) {
12590                if (!persistent) {
12591                    mOrigDebugApp = mDebugApp;
12592                    mOrigWaitForDebugger = mWaitForDebugger;
12593                }
12594                mDebugApp = packageName;
12595                mWaitForDebugger = waitForDebugger;
12596                mDebugTransient = !persistent;
12597                if (packageName != null) {
12598                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12599                            false, UserHandle.USER_ALL, "set debug app");
12600                }
12601            }
12602        } finally {
12603            Binder.restoreCallingIdentity(ident);
12604        }
12605    }
12606
12607    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12608        synchronized (this) {
12609            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12610            if (!isDebuggable) {
12611                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12612                    throw new SecurityException("Process not debuggable: " + app.packageName);
12613                }
12614            }
12615
12616            mTrackAllocationApp = processName;
12617        }
12618    }
12619
12620    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12621        synchronized (this) {
12622            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12623            if (!isDebuggable) {
12624                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12625                    throw new SecurityException("Process not debuggable: " + app.packageName);
12626                }
12627            }
12628            mProfileApp = processName;
12629            mProfileFile = profilerInfo.profileFile;
12630            if (mProfileFd != null) {
12631                try {
12632                    mProfileFd.close();
12633                } catch (IOException e) {
12634                }
12635                mProfileFd = null;
12636            }
12637            mProfileFd = profilerInfo.profileFd;
12638            mSamplingInterval = profilerInfo.samplingInterval;
12639            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12640            mStreamingOutput = profilerInfo.streamingOutput;
12641            mProfileType = 0;
12642        }
12643    }
12644
12645    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12646        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12647        if (!isDebuggable) {
12648            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12649                throw new SecurityException("Process not debuggable: " + app.packageName);
12650            }
12651        }
12652        mNativeDebuggingApp = processName;
12653    }
12654
12655    @Override
12656    public void setAlwaysFinish(boolean enabled) {
12657        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12658                "setAlwaysFinish()");
12659
12660        long ident = Binder.clearCallingIdentity();
12661        try {
12662            Settings.Global.putInt(
12663                    mContext.getContentResolver(),
12664                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12665
12666            synchronized (this) {
12667                mAlwaysFinishActivities = enabled;
12668            }
12669        } finally {
12670            Binder.restoreCallingIdentity(ident);
12671        }
12672    }
12673
12674    @Override
12675    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12676        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12677                "setActivityController()");
12678        synchronized (this) {
12679            mController = controller;
12680            mControllerIsAMonkey = imAMonkey;
12681            Watchdog.getInstance().setActivityController(controller);
12682        }
12683    }
12684
12685    @Override
12686    public void setUserIsMonkey(boolean userIsMonkey) {
12687        synchronized (this) {
12688            synchronized (mPidsSelfLocked) {
12689                final int callingPid = Binder.getCallingPid();
12690                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12691                if (proc == null) {
12692                    throw new SecurityException("Unknown process: " + callingPid);
12693                }
12694                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12695                    throw new SecurityException("Only an instrumentation process "
12696                            + "with a UiAutomation can call setUserIsMonkey");
12697                }
12698            }
12699            mUserIsMonkey = userIsMonkey;
12700        }
12701    }
12702
12703    @Override
12704    public boolean isUserAMonkey() {
12705        synchronized (this) {
12706            // If there is a controller also implies the user is a monkey.
12707            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12708        }
12709    }
12710
12711    /**
12712     * @deprecated This method is only used by a few internal components and it will soon be
12713     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12714     * No new code should be calling it.
12715     */
12716    @Deprecated
12717    @Override
12718    public void requestBugReport(int bugreportType) {
12719        String extraOptions = null;
12720        switch (bugreportType) {
12721            case ActivityManager.BUGREPORT_OPTION_FULL:
12722                // Default options.
12723                break;
12724            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12725                extraOptions = "bugreportplus";
12726                break;
12727            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12728                extraOptions = "bugreportremote";
12729                break;
12730            case ActivityManager.BUGREPORT_OPTION_WEAR:
12731                extraOptions = "bugreportwear";
12732                break;
12733            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12734                extraOptions = "bugreporttelephony";
12735                break;
12736            default:
12737                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12738                        + bugreportType);
12739        }
12740        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12741        if (extraOptions != null) {
12742            SystemProperties.set("dumpstate.options", extraOptions);
12743        }
12744        SystemProperties.set("ctl.start", "bugreport");
12745    }
12746
12747    /**
12748     * @deprecated This method is only used by a few internal components and it will soon be
12749     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12750     * No new code should be calling it.
12751     */
12752    @Deprecated
12753    @Override
12754    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12755
12756        if (!TextUtils.isEmpty(shareTitle)) {
12757            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12758                String errorStr = "shareTitle should be less than " +
12759                        MAX_BUGREPORT_TITLE_SIZE + " characters";
12760                throw new IllegalArgumentException(errorStr);
12761            } else {
12762                if (!TextUtils.isEmpty(shareDescription)) {
12763                    int length;
12764                    try {
12765                        length = shareDescription.getBytes("UTF-8").length;
12766                    } catch (UnsupportedEncodingException e) {
12767                        String errorStr = "shareDescription: UnsupportedEncodingException";
12768                        throw new IllegalArgumentException(errorStr);
12769                    }
12770                    if (length > SystemProperties.PROP_VALUE_MAX) {
12771                        String errorStr = "shareTitle should be less than " +
12772                                SystemProperties.PROP_VALUE_MAX + " bytes";
12773                        throw new IllegalArgumentException(errorStr);
12774                    } else {
12775                        SystemProperties.set("dumpstate.options.description", shareDescription);
12776                    }
12777                }
12778                SystemProperties.set("dumpstate.options.title", shareTitle);
12779            }
12780        }
12781
12782        Slog.d(TAG, "Bugreport notification title " + shareTitle
12783                + " description " + shareDescription);
12784        requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12785    }
12786
12787    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12788        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12789    }
12790
12791    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12792        if (r != null && (r.instr != null || r.usingWrapper)) {
12793            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12794        }
12795        return KEY_DISPATCHING_TIMEOUT;
12796    }
12797
12798    @Override
12799    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12800        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12801                != PackageManager.PERMISSION_GRANTED) {
12802            throw new SecurityException("Requires permission "
12803                    + android.Manifest.permission.FILTER_EVENTS);
12804        }
12805        ProcessRecord proc;
12806        long timeout;
12807        synchronized (this) {
12808            synchronized (mPidsSelfLocked) {
12809                proc = mPidsSelfLocked.get(pid);
12810            }
12811            timeout = getInputDispatchingTimeoutLocked(proc);
12812        }
12813
12814        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12815            return -1;
12816        }
12817
12818        return timeout;
12819    }
12820
12821    /**
12822     * Handle input dispatching timeouts.
12823     * Returns whether input dispatching should be aborted or not.
12824     */
12825    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12826            final ActivityRecord activity, final ActivityRecord parent,
12827            final boolean aboveSystem, String reason) {
12828        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12829                != PackageManager.PERMISSION_GRANTED) {
12830            throw new SecurityException("Requires permission "
12831                    + android.Manifest.permission.FILTER_EVENTS);
12832        }
12833
12834        final String annotation;
12835        if (reason == null) {
12836            annotation = "Input dispatching timed out";
12837        } else {
12838            annotation = "Input dispatching timed out (" + reason + ")";
12839        }
12840
12841        if (proc != null) {
12842            synchronized (this) {
12843                if (proc.debugging) {
12844                    return false;
12845                }
12846
12847                if (mDidDexOpt) {
12848                    // Give more time since we were dexopting.
12849                    mDidDexOpt = false;
12850                    return false;
12851                }
12852
12853                if (proc.instr != null) {
12854                    Bundle info = new Bundle();
12855                    info.putString("shortMsg", "keyDispatchingTimedOut");
12856                    info.putString("longMsg", annotation);
12857                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12858                    return true;
12859                }
12860            }
12861            mHandler.post(new Runnable() {
12862                @Override
12863                public void run() {
12864                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12865                }
12866            });
12867        }
12868
12869        return true;
12870    }
12871
12872    @Override
12873    public Bundle getAssistContextExtras(int requestType) {
12874        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12875                null, null, true /* focused */, true /* newSessionId */,
12876                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12877        if (pae == null) {
12878            return null;
12879        }
12880        synchronized (pae) {
12881            while (!pae.haveResult) {
12882                try {
12883                    pae.wait();
12884                } catch (InterruptedException e) {
12885                }
12886            }
12887        }
12888        synchronized (this) {
12889            buildAssistBundleLocked(pae, pae.result);
12890            mPendingAssistExtras.remove(pae);
12891            mUiHandler.removeCallbacks(pae);
12892        }
12893        return pae.extras;
12894    }
12895
12896    @Override
12897    public boolean isAssistDataAllowedOnCurrentActivity() {
12898        int userId;
12899        synchronized (this) {
12900            final ActivityStack focusedStack = getFocusedStack();
12901            if (focusedStack == null || focusedStack.isAssistantStack()) {
12902                return false;
12903            }
12904
12905            final ActivityRecord activity = focusedStack.topActivity();
12906            if (activity == null) {
12907                return false;
12908            }
12909            userId = activity.userId;
12910        }
12911        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12912                Context.DEVICE_POLICY_SERVICE);
12913        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12914    }
12915
12916    @Override
12917    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12918        long ident = Binder.clearCallingIdentity();
12919        try {
12920            synchronized (this) {
12921                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12922                ActivityRecord top = getFocusedStack().topActivity();
12923                if (top != caller) {
12924                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12925                            + " is not current top " + top);
12926                    return false;
12927                }
12928                if (!top.nowVisible) {
12929                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12930                            + " is not visible");
12931                    return false;
12932                }
12933            }
12934            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
12935                    token);
12936        } finally {
12937            Binder.restoreCallingIdentity(ident);
12938        }
12939    }
12940
12941    @Override
12942    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12943            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
12944        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12945                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
12946                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
12947    }
12948
12949    @Override
12950    public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
12951            IBinder activityToken, int flags) {
12952        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
12953                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
12954                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
12955    }
12956
12957    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12958            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12959            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
12960            int flags) {
12961        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12962                "enqueueAssistContext()");
12963
12964        synchronized (this) {
12965            ActivityRecord activity = getFocusedStack().topActivity();
12966            if (activity == null) {
12967                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12968                return null;
12969            }
12970            if (activity.app == null || activity.app.thread == null) {
12971                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12972                return null;
12973            }
12974            if (focused) {
12975                if (activityToken != null) {
12976                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12977                    if (activity != caller) {
12978                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12979                                + " is not current top " + activity);
12980                        return null;
12981                    }
12982                }
12983            } else {
12984                activity = ActivityRecord.forTokenLocked(activityToken);
12985                if (activity == null) {
12986                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12987                            + " couldn't be found");
12988                    return null;
12989                }
12990            }
12991
12992            PendingAssistExtras pae;
12993            Bundle extras = new Bundle();
12994            if (args != null) {
12995                extras.putAll(args);
12996            }
12997            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12998            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12999
13000            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13001                    userHandle);
13002            pae.isHome = activity.isHomeActivity();
13003
13004            // Increment the sessionId if necessary
13005            if (newSessionId) {
13006                mViSessionId++;
13007            }
13008            try {
13009                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13010                        mViSessionId, flags);
13011                mPendingAssistExtras.add(pae);
13012                mUiHandler.postDelayed(pae, timeout);
13013            } catch (RemoteException e) {
13014                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13015                return null;
13016            }
13017            return pae;
13018        }
13019    }
13020
13021    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13022        IResultReceiver receiver;
13023        synchronized (this) {
13024            mPendingAssistExtras.remove(pae);
13025            receiver = pae.receiver;
13026        }
13027        if (receiver != null) {
13028            // Caller wants result sent back to them.
13029            Bundle sendBundle = new Bundle();
13030            // At least return the receiver extras
13031            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13032                    pae.receiverExtras);
13033            try {
13034                pae.receiver.send(0, sendBundle);
13035            } catch (RemoteException e) {
13036            }
13037        }
13038    }
13039
13040    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13041        if (result != null) {
13042            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13043        }
13044        if (pae.hint != null) {
13045            pae.extras.putBoolean(pae.hint, true);
13046        }
13047    }
13048
13049    /** Called from an app when assist data is ready. */
13050    @Override
13051    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13052            AssistContent content, Uri referrer) {
13053        PendingAssistExtras pae = (PendingAssistExtras)token;
13054        synchronized (pae) {
13055            pae.result = extras;
13056            pae.structure = structure;
13057            pae.content = content;
13058            if (referrer != null) {
13059                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13060            }
13061            if (structure != null) {
13062                structure.setHomeActivity(pae.isHome);
13063            }
13064            pae.haveResult = true;
13065            pae.notifyAll();
13066            if (pae.intent == null && pae.receiver == null) {
13067                // Caller is just waiting for the result.
13068                return;
13069            }
13070        }
13071
13072        // We are now ready to launch the assist activity.
13073        IResultReceiver sendReceiver = null;
13074        Bundle sendBundle = null;
13075        synchronized (this) {
13076            buildAssistBundleLocked(pae, extras);
13077            boolean exists = mPendingAssistExtras.remove(pae);
13078            mUiHandler.removeCallbacks(pae);
13079            if (!exists) {
13080                // Timed out.
13081                return;
13082            }
13083            if ((sendReceiver=pae.receiver) != null) {
13084                // Caller wants result sent back to them.
13085                sendBundle = new Bundle();
13086                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13087                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13088                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13089                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13090                        pae.receiverExtras);
13091            }
13092        }
13093        if (sendReceiver != null) {
13094            try {
13095                sendReceiver.send(0, sendBundle);
13096            } catch (RemoteException e) {
13097            }
13098            return;
13099        }
13100
13101        long ident = Binder.clearCallingIdentity();
13102        try {
13103            pae.intent.replaceExtras(pae.extras);
13104            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13105                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
13106                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13107            closeSystemDialogs("assist");
13108            try {
13109                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13110            } catch (ActivityNotFoundException e) {
13111                Slog.w(TAG, "No activity to handle assist action.", e);
13112            }
13113        } finally {
13114            Binder.restoreCallingIdentity(ident);
13115        }
13116    }
13117
13118    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13119            Bundle args) {
13120        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13121                true /* focused */, true /* newSessionId */, userHandle, args,
13122                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13123    }
13124
13125    public void registerProcessObserver(IProcessObserver observer) {
13126        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13127                "registerProcessObserver()");
13128        synchronized (this) {
13129            mProcessObservers.register(observer);
13130        }
13131    }
13132
13133    @Override
13134    public void unregisterProcessObserver(IProcessObserver observer) {
13135        synchronized (this) {
13136            mProcessObservers.unregister(observer);
13137        }
13138    }
13139
13140    @Override
13141    public int getUidProcessState(int uid, String callingPackage) {
13142        if (!hasUsageStatsPermission(callingPackage)) {
13143            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13144                    "getUidProcessState");
13145        }
13146
13147        synchronized (this) {
13148            UidRecord uidRec = mActiveUids.get(uid);
13149            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13150        }
13151    }
13152
13153    @Override
13154    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13155            String callingPackage) {
13156        if (!hasUsageStatsPermission(callingPackage)) {
13157            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13158                    "registerUidObserver");
13159        }
13160        synchronized (this) {
13161            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13162                    callingPackage, which, cutpoint));
13163        }
13164    }
13165
13166    @Override
13167    public void unregisterUidObserver(IUidObserver observer) {
13168        synchronized (this) {
13169            mUidObservers.unregister(observer);
13170        }
13171    }
13172
13173    @Override
13174    public boolean convertFromTranslucent(IBinder token) {
13175        final long origId = Binder.clearCallingIdentity();
13176        try {
13177            synchronized (this) {
13178                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13179                if (r == null) {
13180                    return false;
13181                }
13182                final boolean translucentChanged = r.changeWindowTranslucency(true);
13183                if (translucentChanged) {
13184                    r.getStack().releaseBackgroundResources(r);
13185                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13186                }
13187                mWindowManager.setAppFullscreen(token, true);
13188                return translucentChanged;
13189            }
13190        } finally {
13191            Binder.restoreCallingIdentity(origId);
13192        }
13193    }
13194
13195    @Override
13196    public boolean convertToTranslucent(IBinder token, Bundle options) {
13197        final long origId = Binder.clearCallingIdentity();
13198        try {
13199            synchronized (this) {
13200                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13201                if (r == null) {
13202                    return false;
13203                }
13204                final TaskRecord task = r.getTask();
13205                int index = task.mActivities.lastIndexOf(r);
13206                if (index > 0) {
13207                    ActivityRecord under = task.mActivities.get(index - 1);
13208                    under.returningOptions = ActivityOptions.fromBundle(options);
13209                }
13210                final boolean translucentChanged = r.changeWindowTranslucency(false);
13211                if (translucentChanged) {
13212                    r.getStack().convertActivityToTranslucent(r);
13213                }
13214                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13215                mWindowManager.setAppFullscreen(token, false);
13216                return translucentChanged;
13217            }
13218        } finally {
13219            Binder.restoreCallingIdentity(origId);
13220        }
13221    }
13222
13223    @Override
13224    public boolean requestVisibleBehind(IBinder token, boolean visible) {
13225        final long origId = Binder.clearCallingIdentity();
13226        try {
13227            synchronized (this) {
13228                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13229                if (r != null) {
13230                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13231                }
13232            }
13233            return false;
13234        } finally {
13235            Binder.restoreCallingIdentity(origId);
13236        }
13237    }
13238
13239    @Override
13240    public boolean isBackgroundVisibleBehind(IBinder token) {
13241        final long origId = Binder.clearCallingIdentity();
13242        try {
13243            synchronized (this) {
13244                final ActivityStack stack = ActivityRecord.getStackLocked(token);
13245                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13246                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13247                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13248                return visible;
13249            }
13250        } finally {
13251            Binder.restoreCallingIdentity(origId);
13252        }
13253    }
13254
13255    @Override
13256    public Bundle getActivityOptions(IBinder token) {
13257        final long origId = Binder.clearCallingIdentity();
13258        try {
13259            synchronized (this) {
13260                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13261                if (r != null) {
13262                    final ActivityOptions activityOptions = r.pendingOptions;
13263                    r.pendingOptions = null;
13264                    return activityOptions == null ? null : activityOptions.toBundle();
13265                }
13266                return null;
13267            }
13268        } finally {
13269            Binder.restoreCallingIdentity(origId);
13270        }
13271    }
13272
13273    @Override
13274    public void setImmersive(IBinder token, boolean immersive) {
13275        synchronized(this) {
13276            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13277            if (r == null) {
13278                throw new IllegalArgumentException();
13279            }
13280            r.immersive = immersive;
13281
13282            // update associated state if we're frontmost
13283            if (r == mStackSupervisor.getResumedActivityLocked()) {
13284                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13285                applyUpdateLockStateLocked(r);
13286            }
13287        }
13288    }
13289
13290    @Override
13291    public boolean isImmersive(IBinder token) {
13292        synchronized (this) {
13293            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13294            if (r == null) {
13295                throw new IllegalArgumentException();
13296            }
13297            return r.immersive;
13298        }
13299    }
13300
13301    @Override
13302    public void setVrThread(int tid) {
13303        enforceSystemHasVrFeature();
13304        synchronized (this) {
13305            synchronized (mPidsSelfLocked) {
13306                final int pid = Binder.getCallingPid();
13307                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13308                mVrController.setVrThreadLocked(tid, pid, proc);
13309            }
13310        }
13311    }
13312
13313    @Override
13314    public void setPersistentVrThread(int tid) {
13315        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13316            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13317                    + Binder.getCallingPid()
13318                    + ", uid=" + Binder.getCallingUid()
13319                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13320            Slog.w(TAG, msg);
13321            throw new SecurityException(msg);
13322        }
13323        enforceSystemHasVrFeature();
13324        synchronized (this) {
13325            synchronized (mPidsSelfLocked) {
13326                final int pid = Binder.getCallingPid();
13327                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13328                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13329            }
13330        }
13331    }
13332
13333    /**
13334     * Schedule the given thread a normal scheduling priority.
13335     *
13336     * @param newTid the tid of the thread to adjust the scheduling of.
13337     * @param suppressLogs {@code true} if any error logging should be disabled.
13338     *
13339     * @return {@code true} if this succeeded.
13340     */
13341    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13342        try {
13343            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13344            return true;
13345        } catch (IllegalArgumentException e) {
13346            if (!suppressLogs) {
13347                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13348            }
13349        }
13350        return false;
13351    }
13352
13353    /**
13354     * Schedule the given thread an FIFO scheduling priority.
13355     *
13356     * @param newTid the tid of the thread to adjust the scheduling of.
13357     * @param suppressLogs {@code true} if any error logging should be disabled.
13358     *
13359     * @return {@code true} if this succeeded.
13360     */
13361    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13362        try {
13363            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13364            return true;
13365        } catch (IllegalArgumentException e) {
13366            if (!suppressLogs) {
13367                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13368            }
13369        }
13370        return false;
13371    }
13372
13373    /**
13374     * Check that we have the features required for VR-related API calls, and throw an exception if
13375     * not.
13376     */
13377    private void enforceSystemHasVrFeature() {
13378        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13379            throw new UnsupportedOperationException("VR mode not supported on this device!");
13380        }
13381    }
13382
13383    @Override
13384    public void setRenderThread(int tid) {
13385        synchronized (this) {
13386            ProcessRecord proc;
13387            synchronized (mPidsSelfLocked) {
13388                int pid = Binder.getCallingPid();
13389                proc = mPidsSelfLocked.get(pid);
13390                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13391                    // ensure the tid belongs to the process
13392                    if (!isThreadInProcess(pid, tid)) {
13393                        throw new IllegalArgumentException(
13394                            "Render thread does not belong to process");
13395                    }
13396                    proc.renderThreadTid = tid;
13397                    if (DEBUG_OOM_ADJ) {
13398                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13399                    }
13400                    // promote to FIFO now
13401                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13402                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13403                        if (mUseFifoUiScheduling) {
13404                            setThreadScheduler(proc.renderThreadTid,
13405                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13406                        } else {
13407                            setThreadPriority(proc.renderThreadTid, -10);
13408                        }
13409                    }
13410                } else {
13411                    if (DEBUG_OOM_ADJ) {
13412                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13413                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13414                               mUseFifoUiScheduling);
13415                    }
13416                }
13417            }
13418        }
13419    }
13420
13421    @Override
13422    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13423        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13424            throw new UnsupportedOperationException("VR mode not supported on this device!");
13425        }
13426
13427        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13428
13429        ActivityRecord r;
13430        synchronized (this) {
13431            r = ActivityRecord.isInStackLocked(token);
13432        }
13433
13434        if (r == null) {
13435            throw new IllegalArgumentException();
13436        }
13437
13438        int err;
13439        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13440                VrManagerInternal.NO_ERROR) {
13441            return err;
13442        }
13443
13444        synchronized(this) {
13445            r.requestedVrComponent = (enabled) ? packageName : null;
13446
13447            // Update associated state if this activity is currently focused
13448            if (r == mStackSupervisor.getResumedActivityLocked()) {
13449                applyUpdateVrModeLocked(r);
13450            }
13451            return 0;
13452        }
13453    }
13454
13455    @Override
13456    public boolean isVrModePackageEnabled(ComponentName packageName) {
13457        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13458            throw new UnsupportedOperationException("VR mode not supported on this device!");
13459        }
13460
13461        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13462
13463        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13464                VrManagerInternal.NO_ERROR;
13465    }
13466
13467    public boolean isTopActivityImmersive() {
13468        enforceNotIsolatedCaller("startActivity");
13469        synchronized (this) {
13470            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13471            return (r != null) ? r.immersive : false;
13472        }
13473    }
13474
13475    /**
13476     * @return whether the system should disable UI modes incompatible with VR mode.
13477     */
13478    boolean shouldDisableNonVrUiLocked() {
13479        return mVrController.shouldDisableNonVrUiLocked();
13480    }
13481
13482    @Override
13483    public boolean isTopOfTask(IBinder token) {
13484        synchronized (this) {
13485            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13486            if (r == null) {
13487                throw new IllegalArgumentException();
13488            }
13489            return r.getTask().getTopActivity() == r;
13490        }
13491    }
13492
13493    @Override
13494    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13495        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13496            String msg = "Permission Denial: setHasTopUi() from pid="
13497                    + Binder.getCallingPid()
13498                    + ", uid=" + Binder.getCallingUid()
13499                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13500            Slog.w(TAG, msg);
13501            throw new SecurityException(msg);
13502        }
13503        final int pid = Binder.getCallingPid();
13504        final long origId = Binder.clearCallingIdentity();
13505        try {
13506            synchronized (this) {
13507                boolean changed = false;
13508                ProcessRecord pr;
13509                synchronized (mPidsSelfLocked) {
13510                    pr = mPidsSelfLocked.get(pid);
13511                    if (pr == null) {
13512                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13513                        return;
13514                    }
13515                    if (pr.hasTopUi != hasTopUi) {
13516                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13517                        pr.hasTopUi = hasTopUi;
13518                        changed = true;
13519                    }
13520                }
13521                if (changed) {
13522                    updateOomAdjLocked(pr, true);
13523                }
13524            }
13525        } finally {
13526            Binder.restoreCallingIdentity(origId);
13527        }
13528    }
13529
13530    public final void enterSafeMode() {
13531        synchronized(this) {
13532            // It only makes sense to do this before the system is ready
13533            // and started launching other packages.
13534            if (!mSystemReady) {
13535                try {
13536                    AppGlobals.getPackageManager().enterSafeMode();
13537                } catch (RemoteException e) {
13538                }
13539            }
13540
13541            mSafeMode = true;
13542        }
13543    }
13544
13545    public final void showSafeModeOverlay() {
13546        View v = LayoutInflater.from(mContext).inflate(
13547                com.android.internal.R.layout.safe_mode, null);
13548        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13549        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13550        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13551        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13552        lp.gravity = Gravity.BOTTOM | Gravity.START;
13553        lp.format = v.getBackground().getOpacity();
13554        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13555                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13556        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13557        ((WindowManager)mContext.getSystemService(
13558                Context.WINDOW_SERVICE)).addView(v, lp);
13559    }
13560
13561    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13562        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13563            return;
13564        }
13565        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13566        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13567        synchronized (stats) {
13568            if (mBatteryStatsService.isOnBattery()) {
13569                mBatteryStatsService.enforceCallingPermission();
13570                int MY_UID = Binder.getCallingUid();
13571                final int uid;
13572                if (sender == null) {
13573                    uid = sourceUid;
13574                } else {
13575                    uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13576                }
13577                BatteryStatsImpl.Uid.Pkg pkg =
13578                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13579                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13580                pkg.noteWakeupAlarmLocked(tag);
13581            }
13582        }
13583    }
13584
13585    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13586        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13587            return;
13588        }
13589        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13590        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13591        synchronized (stats) {
13592            mBatteryStatsService.enforceCallingPermission();
13593            int MY_UID = Binder.getCallingUid();
13594            final int uid;
13595            if (sender == null) {
13596                uid = sourceUid;
13597            } else {
13598                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13599            }
13600            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13601        }
13602    }
13603
13604    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13605        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13606            return;
13607        }
13608        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13609        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13610        synchronized (stats) {
13611            mBatteryStatsService.enforceCallingPermission();
13612            int MY_UID = Binder.getCallingUid();
13613            final int uid;
13614            if (sender == null) {
13615                uid = sourceUid;
13616            } else {
13617                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13618            }
13619            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13620        }
13621    }
13622
13623    public boolean killPids(int[] pids, String pReason, boolean secure) {
13624        if (Binder.getCallingUid() != SYSTEM_UID) {
13625            throw new SecurityException("killPids only available to the system");
13626        }
13627        String reason = (pReason == null) ? "Unknown" : pReason;
13628        // XXX Note: don't acquire main activity lock here, because the window
13629        // manager calls in with its locks held.
13630
13631        boolean killed = false;
13632        synchronized (mPidsSelfLocked) {
13633            int worstType = 0;
13634            for (int i=0; i<pids.length; i++) {
13635                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13636                if (proc != null) {
13637                    int type = proc.setAdj;
13638                    if (type > worstType) {
13639                        worstType = type;
13640                    }
13641                }
13642            }
13643
13644            // If the worst oom_adj is somewhere in the cached proc LRU range,
13645            // then constrain it so we will kill all cached procs.
13646            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13647                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13648                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13649            }
13650
13651            // If this is not a secure call, don't let it kill processes that
13652            // are important.
13653            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13654                worstType = ProcessList.SERVICE_ADJ;
13655            }
13656
13657            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13658            for (int i=0; i<pids.length; i++) {
13659                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13660                if (proc == null) {
13661                    continue;
13662                }
13663                int adj = proc.setAdj;
13664                if (adj >= worstType && !proc.killedByAm) {
13665                    proc.kill(reason, true);
13666                    killed = true;
13667                }
13668            }
13669        }
13670        return killed;
13671    }
13672
13673    @Override
13674    public void killUid(int appId, int userId, String reason) {
13675        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13676        synchronized (this) {
13677            final long identity = Binder.clearCallingIdentity();
13678            try {
13679                killPackageProcessesLocked(null, appId, userId,
13680                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13681                        reason != null ? reason : "kill uid");
13682            } finally {
13683                Binder.restoreCallingIdentity(identity);
13684            }
13685        }
13686    }
13687
13688    @Override
13689    public boolean killProcessesBelowForeground(String reason) {
13690        if (Binder.getCallingUid() != SYSTEM_UID) {
13691            throw new SecurityException("killProcessesBelowForeground() only available to system");
13692        }
13693
13694        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13695    }
13696
13697    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13698        if (Binder.getCallingUid() != SYSTEM_UID) {
13699            throw new SecurityException("killProcessesBelowAdj() only available to system");
13700        }
13701
13702        boolean killed = false;
13703        synchronized (mPidsSelfLocked) {
13704            final int size = mPidsSelfLocked.size();
13705            for (int i = 0; i < size; i++) {
13706                final int pid = mPidsSelfLocked.keyAt(i);
13707                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13708                if (proc == null) continue;
13709
13710                final int adj = proc.setAdj;
13711                if (adj > belowAdj && !proc.killedByAm) {
13712                    proc.kill(reason, true);
13713                    killed = true;
13714                }
13715            }
13716        }
13717        return killed;
13718    }
13719
13720    @Override
13721    public void hang(final IBinder who, boolean allowRestart) {
13722        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13723                != PackageManager.PERMISSION_GRANTED) {
13724            throw new SecurityException("Requires permission "
13725                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13726        }
13727
13728        final IBinder.DeathRecipient death = new DeathRecipient() {
13729            @Override
13730            public void binderDied() {
13731                synchronized (this) {
13732                    notifyAll();
13733                }
13734            }
13735        };
13736
13737        try {
13738            who.linkToDeath(death, 0);
13739        } catch (RemoteException e) {
13740            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13741            return;
13742        }
13743
13744        synchronized (this) {
13745            Watchdog.getInstance().setAllowRestart(allowRestart);
13746            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13747            synchronized (death) {
13748                while (who.isBinderAlive()) {
13749                    try {
13750                        death.wait();
13751                    } catch (InterruptedException e) {
13752                    }
13753                }
13754            }
13755            Watchdog.getInstance().setAllowRestart(true);
13756        }
13757    }
13758
13759    @Override
13760    public void restart() {
13761        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13762                != PackageManager.PERMISSION_GRANTED) {
13763            throw new SecurityException("Requires permission "
13764                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13765        }
13766
13767        Log.i(TAG, "Sending shutdown broadcast...");
13768
13769        BroadcastReceiver br = new BroadcastReceiver() {
13770            @Override public void onReceive(Context context, Intent intent) {
13771                // Now the broadcast is done, finish up the low-level shutdown.
13772                Log.i(TAG, "Shutting down activity manager...");
13773                shutdown(10000);
13774                Log.i(TAG, "Shutdown complete, restarting!");
13775                killProcess(myPid());
13776                System.exit(10);
13777            }
13778        };
13779
13780        // First send the high-level shut down broadcast.
13781        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13782        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13783        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13784        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13785        mContext.sendOrderedBroadcastAsUser(intent,
13786                UserHandle.ALL, null, br, mHandler, 0, null, null);
13787        */
13788        br.onReceive(mContext, intent);
13789    }
13790
13791    private long getLowRamTimeSinceIdle(long now) {
13792        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13793    }
13794
13795    @Override
13796    public void performIdleMaintenance() {
13797        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13798                != PackageManager.PERMISSION_GRANTED) {
13799            throw new SecurityException("Requires permission "
13800                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13801        }
13802
13803        synchronized (this) {
13804            final long now = SystemClock.uptimeMillis();
13805            final long timeSinceLastIdle = now - mLastIdleTime;
13806            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13807            mLastIdleTime = now;
13808            mLowRamTimeSinceLastIdle = 0;
13809            if (mLowRamStartTime != 0) {
13810                mLowRamStartTime = now;
13811            }
13812
13813            StringBuilder sb = new StringBuilder(128);
13814            sb.append("Idle maintenance over ");
13815            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13816            sb.append(" low RAM for ");
13817            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13818            Slog.i(TAG, sb.toString());
13819
13820            // If at least 1/3 of our time since the last idle period has been spent
13821            // with RAM low, then we want to kill processes.
13822            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13823
13824            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13825                ProcessRecord proc = mLruProcesses.get(i);
13826                if (proc.notCachedSinceIdle) {
13827                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13828                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13829                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13830                        if (doKilling && proc.initialIdlePss != 0
13831                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13832                            sb = new StringBuilder(128);
13833                            sb.append("Kill");
13834                            sb.append(proc.processName);
13835                            sb.append(" in idle maint: pss=");
13836                            sb.append(proc.lastPss);
13837                            sb.append(", swapPss=");
13838                            sb.append(proc.lastSwapPss);
13839                            sb.append(", initialPss=");
13840                            sb.append(proc.initialIdlePss);
13841                            sb.append(", period=");
13842                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13843                            sb.append(", lowRamPeriod=");
13844                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13845                            Slog.wtfQuiet(TAG, sb.toString());
13846                            proc.kill("idle maint (pss " + proc.lastPss
13847                                    + " from " + proc.initialIdlePss + ")", true);
13848                        }
13849                    }
13850                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13851                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13852                    proc.notCachedSinceIdle = true;
13853                    proc.initialIdlePss = 0;
13854                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13855                            mTestPssMode, isSleepingLocked(), now);
13856                }
13857            }
13858
13859            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13860            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13861        }
13862    }
13863
13864    @Override
13865    public void sendIdleJobTrigger() {
13866        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13867                != PackageManager.PERMISSION_GRANTED) {
13868            throw new SecurityException("Requires permission "
13869                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13870        }
13871
13872        final long ident = Binder.clearCallingIdentity();
13873        try {
13874            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13875                    .setPackage("android")
13876                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13877            broadcastIntent(null, intent, null, null, 0, null, null, null,
13878                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13879        } finally {
13880            Binder.restoreCallingIdentity(ident);
13881        }
13882    }
13883
13884    private void retrieveSettings() {
13885        final ContentResolver resolver = mContext.getContentResolver();
13886        final boolean freeformWindowManagement =
13887                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13888                        || Settings.Global.getInt(
13889                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13890        final boolean supportsPictureInPicture =
13891                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13892
13893        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13894        final boolean supportsSplitScreenMultiWindow =
13895                ActivityManager.supportsSplitScreenMultiWindow();
13896        final boolean supportsMultiDisplay = mContext.getPackageManager()
13897                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
13898        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13899        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13900        final boolean alwaysFinishActivities =
13901                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13902        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13903        final boolean forceResizable = Settings.Global.getInt(
13904                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13905        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
13906                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
13907        final boolean supportsLeanbackOnly =
13908                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13909
13910        // Transfer any global setting for forcing RTL layout, into a System Property
13911        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13912
13913        final Configuration configuration = new Configuration();
13914        Settings.System.getConfiguration(resolver, configuration);
13915        if (forceRtl) {
13916            // This will take care of setting the correct layout direction flags
13917            configuration.setLayoutDirection(configuration.locale);
13918        }
13919
13920        synchronized (this) {
13921            mDebugApp = mOrigDebugApp = debugApp;
13922            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13923            mAlwaysFinishActivities = alwaysFinishActivities;
13924            mSupportsLeanbackOnly = supportsLeanbackOnly;
13925            mForceResizableActivities = forceResizable;
13926            if (supportsMultiWindow || forceResizable) {
13927                mSupportsMultiWindow = true;
13928                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13929            } else {
13930                mSupportsMultiWindow = false;
13931                mSupportsFreeformWindowManagement = false;
13932            }
13933            mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13934            mSupportsPictureInPicture = supportsPictureInPicture;
13935            mSupportsMultiDisplay = supportsMultiDisplay;
13936            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13937            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13938            // This happens before any activities are started, so we can change global configuration
13939            // in-place.
13940            updateConfigurationLocked(configuration, null, true);
13941            final Configuration globalConfig = getGlobalConfiguration();
13942            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13943
13944            // Load resources only after the current configuration has been set.
13945            final Resources res = mContext.getResources();
13946            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13947            mThumbnailWidth = res.getDimensionPixelSize(
13948                    com.android.internal.R.dimen.thumbnail_width);
13949            mThumbnailHeight = res.getDimensionPixelSize(
13950                    com.android.internal.R.dimen.thumbnail_height);
13951            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13952                    com.android.internal.R.string.config_appsNotReportingCrashes));
13953            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13954                    com.android.internal.R.bool.config_customUserSwitchUi);
13955            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13956                mFullscreenThumbnailScale = (float) res
13957                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13958                    (float) globalConfig.screenWidthDp;
13959            } else {
13960                mFullscreenThumbnailScale = res.getFraction(
13961                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13962            }
13963            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
13964        }
13965    }
13966
13967    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
13968        traceLog.traceBegin("PhaseActivityManagerReady");
13969        synchronized(this) {
13970            if (mSystemReady) {
13971                // If we're done calling all the receivers, run the next "boot phase" passed in
13972                // by the SystemServer
13973                if (goingCallback != null) {
13974                    goingCallback.run();
13975                }
13976                return;
13977            }
13978
13979            mLocalDeviceIdleController
13980                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13981            mAssistUtils = new AssistUtils(mContext);
13982            mVrController.onSystemReady();
13983            // Make sure we have the current profile info, since it is needed for security checks.
13984            mUserController.onSystemReady();
13985            mRecentTasks.onSystemReadyLocked();
13986            mAppOpsService.systemReady();
13987            mSystemReady = true;
13988        }
13989
13990        ArrayList<ProcessRecord> procsToKill = null;
13991        synchronized(mPidsSelfLocked) {
13992            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13993                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13994                if (!isAllowedWhileBooting(proc.info)){
13995                    if (procsToKill == null) {
13996                        procsToKill = new ArrayList<ProcessRecord>();
13997                    }
13998                    procsToKill.add(proc);
13999                }
14000            }
14001        }
14002
14003        synchronized(this) {
14004            if (procsToKill != null) {
14005                for (int i=procsToKill.size()-1; i>=0; i--) {
14006                    ProcessRecord proc = procsToKill.get(i);
14007                    Slog.i(TAG, "Removing system update proc: " + proc);
14008                    removeProcessLocked(proc, true, false, "system update done");
14009                }
14010            }
14011
14012            // Now that we have cleaned up any update processes, we
14013            // are ready to start launching real processes and know that
14014            // we won't trample on them any more.
14015            mProcessesReady = true;
14016        }
14017
14018        Slog.i(TAG, "System now ready");
14019        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14020            SystemClock.uptimeMillis());
14021
14022        synchronized(this) {
14023            // Make sure we have no pre-ready processes sitting around.
14024
14025            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14026                ResolveInfo ri = mContext.getPackageManager()
14027                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14028                                STOCK_PM_FLAGS);
14029                CharSequence errorMsg = null;
14030                if (ri != null) {
14031                    ActivityInfo ai = ri.activityInfo;
14032                    ApplicationInfo app = ai.applicationInfo;
14033                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14034                        mTopAction = Intent.ACTION_FACTORY_TEST;
14035                        mTopData = null;
14036                        mTopComponent = new ComponentName(app.packageName,
14037                                ai.name);
14038                    } else {
14039                        errorMsg = mContext.getResources().getText(
14040                                com.android.internal.R.string.factorytest_not_system);
14041                    }
14042                } else {
14043                    errorMsg = mContext.getResources().getText(
14044                            com.android.internal.R.string.factorytest_no_action);
14045                }
14046                if (errorMsg != null) {
14047                    mTopAction = null;
14048                    mTopData = null;
14049                    mTopComponent = null;
14050                    Message msg = Message.obtain();
14051                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14052                    msg.getData().putCharSequence("msg", errorMsg);
14053                    mUiHandler.sendMessage(msg);
14054                }
14055            }
14056        }
14057
14058        retrieveSettings();
14059        final int currentUserId;
14060        synchronized (this) {
14061            currentUserId = mUserController.getCurrentUserIdLocked();
14062            readGrantedUriPermissionsLocked();
14063        }
14064
14065        if (goingCallback != null) goingCallback.run();
14066        traceLog.traceBegin("ActivityManagerStartApps");
14067        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14068                Integer.toString(currentUserId), currentUserId);
14069        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14070                Integer.toString(currentUserId), currentUserId);
14071        mSystemServiceManager.startUser(currentUserId);
14072
14073        synchronized (this) {
14074            // Only start up encryption-aware persistent apps; once user is
14075            // unlocked we'll come back around and start unaware apps
14076            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14077
14078            // Start up initial activity.
14079            mBooting = true;
14080            // Enable home activity for system user, so that the system can always boot. We don't
14081            // do this when the system user is not setup since the setup wizard should be the one
14082            // to handle home activity in this case.
14083            if (UserManager.isSplitSystemUser() &&
14084                    Settings.Secure.getInt(mContext.getContentResolver(),
14085                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14086                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14087                try {
14088                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14089                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14090                            UserHandle.USER_SYSTEM);
14091                } catch (RemoteException e) {
14092                    throw e.rethrowAsRuntimeException();
14093                }
14094            }
14095            startHomeActivityLocked(currentUserId, "systemReady");
14096
14097            try {
14098                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14099                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14100                            + " data partition or your device will be unstable.");
14101                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14102                }
14103            } catch (RemoteException e) {
14104            }
14105
14106            if (!Build.isBuildConsistent()) {
14107                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14108                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14109            }
14110
14111            long ident = Binder.clearCallingIdentity();
14112            try {
14113                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14114                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14115                        | Intent.FLAG_RECEIVER_FOREGROUND);
14116                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14117                broadcastIntentLocked(null, null, intent,
14118                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14119                        null, false, false, MY_PID, SYSTEM_UID,
14120                        currentUserId);
14121                intent = new Intent(Intent.ACTION_USER_STARTING);
14122                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14123                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14124                broadcastIntentLocked(null, null, intent,
14125                        null, new IIntentReceiver.Stub() {
14126                            @Override
14127                            public void performReceive(Intent intent, int resultCode, String data,
14128                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14129                                    throws RemoteException {
14130                            }
14131                        }, 0, null, null,
14132                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14133                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14134            } catch (Throwable t) {
14135                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14136            } finally {
14137                Binder.restoreCallingIdentity(ident);
14138            }
14139            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14140            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14141            traceLog.traceEnd(); // ActivityManagerStartApps
14142            traceLog.traceEnd(); // PhaseActivityManagerReady
14143        }
14144    }
14145
14146    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14147        synchronized (this) {
14148            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14149        }
14150    }
14151
14152    void skipCurrentReceiverLocked(ProcessRecord app) {
14153        for (BroadcastQueue queue : mBroadcastQueues) {
14154            queue.skipCurrentReceiverLocked(app);
14155        }
14156    }
14157
14158    /**
14159     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14160     * The application process will exit immediately after this call returns.
14161     * @param app object of the crashing app, null for the system server
14162     * @param crashInfo describing the exception
14163     */
14164    public void handleApplicationCrash(IBinder app,
14165            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14166        ProcessRecord r = findAppProcess(app, "Crash");
14167        final String processName = app == null ? "system_server"
14168                : (r == null ? "unknown" : r.processName);
14169
14170        handleApplicationCrashInner("crash", r, processName, crashInfo);
14171    }
14172
14173    /* Native crash reporting uses this inner version because it needs to be somewhat
14174     * decoupled from the AM-managed cleanup lifecycle
14175     */
14176    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14177            ApplicationErrorReport.CrashInfo crashInfo) {
14178        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14179                UserHandle.getUserId(Binder.getCallingUid()), processName,
14180                r == null ? -1 : r.info.flags,
14181                crashInfo.exceptionClassName,
14182                crashInfo.exceptionMessage,
14183                crashInfo.throwFileName,
14184                crashInfo.throwLineNumber);
14185
14186        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14187
14188        mAppErrors.crashApplication(r, crashInfo);
14189    }
14190
14191    public void handleApplicationStrictModeViolation(
14192            IBinder app,
14193            int violationMask,
14194            StrictMode.ViolationInfo info) {
14195        ProcessRecord r = findAppProcess(app, "StrictMode");
14196        if (r == null) {
14197            return;
14198        }
14199
14200        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14201            Integer stackFingerprint = info.hashCode();
14202            boolean logIt = true;
14203            synchronized (mAlreadyLoggedViolatedStacks) {
14204                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14205                    logIt = false;
14206                    // TODO: sub-sample into EventLog for these, with
14207                    // the info.durationMillis?  Then we'd get
14208                    // the relative pain numbers, without logging all
14209                    // the stack traces repeatedly.  We'd want to do
14210                    // likewise in the client code, which also does
14211                    // dup suppression, before the Binder call.
14212                } else {
14213                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14214                        mAlreadyLoggedViolatedStacks.clear();
14215                    }
14216                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14217                }
14218            }
14219            if (logIt) {
14220                logStrictModeViolationToDropBox(r, info);
14221            }
14222        }
14223
14224        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14225            AppErrorResult result = new AppErrorResult();
14226            synchronized (this) {
14227                final long origId = Binder.clearCallingIdentity();
14228
14229                Message msg = Message.obtain();
14230                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14231                HashMap<String, Object> data = new HashMap<String, Object>();
14232                data.put("result", result);
14233                data.put("app", r);
14234                data.put("violationMask", violationMask);
14235                data.put("info", info);
14236                msg.obj = data;
14237                mUiHandler.sendMessage(msg);
14238
14239                Binder.restoreCallingIdentity(origId);
14240            }
14241            int res = result.get();
14242            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14243        }
14244    }
14245
14246    // Depending on the policy in effect, there could be a bunch of
14247    // these in quick succession so we try to batch these together to
14248    // minimize disk writes, number of dropbox entries, and maximize
14249    // compression, by having more fewer, larger records.
14250    private void logStrictModeViolationToDropBox(
14251            ProcessRecord process,
14252            StrictMode.ViolationInfo info) {
14253        if (info == null) {
14254            return;
14255        }
14256        final boolean isSystemApp = process == null ||
14257                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14258                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14259        final String processName = process == null ? "unknown" : process.processName;
14260        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14261        final DropBoxManager dbox = (DropBoxManager)
14262                mContext.getSystemService(Context.DROPBOX_SERVICE);
14263
14264        // Exit early if the dropbox isn't configured to accept this report type.
14265        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14266
14267        boolean bufferWasEmpty;
14268        boolean needsFlush;
14269        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14270        synchronized (sb) {
14271            bufferWasEmpty = sb.length() == 0;
14272            appendDropBoxProcessHeaders(process, processName, sb);
14273            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14274            sb.append("System-App: ").append(isSystemApp).append("\n");
14275            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14276            if (info.violationNumThisLoop != 0) {
14277                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14278            }
14279            if (info.numAnimationsRunning != 0) {
14280                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14281            }
14282            if (info.broadcastIntentAction != null) {
14283                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14284            }
14285            if (info.durationMillis != -1) {
14286                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14287            }
14288            if (info.numInstances != -1) {
14289                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14290            }
14291            if (info.tags != null) {
14292                for (String tag : info.tags) {
14293                    sb.append("Span-Tag: ").append(tag).append("\n");
14294                }
14295            }
14296            sb.append("\n");
14297            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14298                sb.append(info.crashInfo.stackTrace);
14299                sb.append("\n");
14300            }
14301            if (info.message != null) {
14302                sb.append(info.message);
14303                sb.append("\n");
14304            }
14305
14306            // Only buffer up to ~64k.  Various logging bits truncate
14307            // things at 128k.
14308            needsFlush = (sb.length() > 64 * 1024);
14309        }
14310
14311        // Flush immediately if the buffer's grown too large, or this
14312        // is a non-system app.  Non-system apps are isolated with a
14313        // different tag & policy and not batched.
14314        //
14315        // Batching is useful during internal testing with
14316        // StrictMode settings turned up high.  Without batching,
14317        // thousands of separate files could be created on boot.
14318        if (!isSystemApp || needsFlush) {
14319            new Thread("Error dump: " + dropboxTag) {
14320                @Override
14321                public void run() {
14322                    String report;
14323                    synchronized (sb) {
14324                        report = sb.toString();
14325                        sb.delete(0, sb.length());
14326                        sb.trimToSize();
14327                    }
14328                    if (report.length() != 0) {
14329                        dbox.addText(dropboxTag, report);
14330                    }
14331                }
14332            }.start();
14333            return;
14334        }
14335
14336        // System app batching:
14337        if (!bufferWasEmpty) {
14338            // An existing dropbox-writing thread is outstanding, so
14339            // we don't need to start it up.  The existing thread will
14340            // catch the buffer appends we just did.
14341            return;
14342        }
14343
14344        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14345        // (After this point, we shouldn't access AMS internal data structures.)
14346        new Thread("Error dump: " + dropboxTag) {
14347            @Override
14348            public void run() {
14349                // 5 second sleep to let stacks arrive and be batched together
14350                try {
14351                    Thread.sleep(5000);  // 5 seconds
14352                } catch (InterruptedException e) {}
14353
14354                String errorReport;
14355                synchronized (mStrictModeBuffer) {
14356                    errorReport = mStrictModeBuffer.toString();
14357                    if (errorReport.length() == 0) {
14358                        return;
14359                    }
14360                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14361                    mStrictModeBuffer.trimToSize();
14362                }
14363                dbox.addText(dropboxTag, errorReport);
14364            }
14365        }.start();
14366    }
14367
14368    /**
14369     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14370     * @param app object of the crashing app, null for the system server
14371     * @param tag reported by the caller
14372     * @param system whether this wtf is coming from the system
14373     * @param crashInfo describing the context of the error
14374     * @return true if the process should exit immediately (WTF is fatal)
14375     */
14376    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14377            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14378        final int callingUid = Binder.getCallingUid();
14379        final int callingPid = Binder.getCallingPid();
14380
14381        if (system) {
14382            // If this is coming from the system, we could very well have low-level
14383            // system locks held, so we want to do this all asynchronously.  And we
14384            // never want this to become fatal, so there is that too.
14385            mHandler.post(new Runnable() {
14386                @Override public void run() {
14387                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14388                }
14389            });
14390            return false;
14391        }
14392
14393        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14394                crashInfo);
14395
14396        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14397                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14398        final boolean isSystem = (r == null) || r.persistent;
14399
14400        if (isFatal && !isSystem) {
14401            mAppErrors.crashApplication(r, crashInfo);
14402            return true;
14403        } else {
14404            return false;
14405        }
14406    }
14407
14408    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14409            final ApplicationErrorReport.CrashInfo crashInfo) {
14410        final ProcessRecord r = findAppProcess(app, "WTF");
14411        final String processName = app == null ? "system_server"
14412                : (r == null ? "unknown" : r.processName);
14413
14414        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14415                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14416
14417        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14418
14419        return r;
14420    }
14421
14422    /**
14423     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14424     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14425     */
14426    private ProcessRecord findAppProcess(IBinder app, String reason) {
14427        if (app == null) {
14428            return null;
14429        }
14430
14431        synchronized (this) {
14432            final int NP = mProcessNames.getMap().size();
14433            for (int ip=0; ip<NP; ip++) {
14434                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14435                final int NA = apps.size();
14436                for (int ia=0; ia<NA; ia++) {
14437                    ProcessRecord p = apps.valueAt(ia);
14438                    if (p.thread != null && p.thread.asBinder() == app) {
14439                        return p;
14440                    }
14441                }
14442            }
14443
14444            Slog.w(TAG, "Can't find mystery application for " + reason
14445                    + " from pid=" + Binder.getCallingPid()
14446                    + " uid=" + Binder.getCallingUid() + ": " + app);
14447            return null;
14448        }
14449    }
14450
14451    /**
14452     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14453     * to append various headers to the dropbox log text.
14454     */
14455    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14456            StringBuilder sb) {
14457        // Watchdog thread ends up invoking this function (with
14458        // a null ProcessRecord) to add the stack file to dropbox.
14459        // Do not acquire a lock on this (am) in such cases, as it
14460        // could cause a potential deadlock, if and when watchdog
14461        // is invoked due to unavailability of lock on am and it
14462        // would prevent watchdog from killing system_server.
14463        if (process == null) {
14464            sb.append("Process: ").append(processName).append("\n");
14465            return;
14466        }
14467        // Note: ProcessRecord 'process' is guarded by the service
14468        // instance.  (notably process.pkgList, which could otherwise change
14469        // concurrently during execution of this method)
14470        synchronized (this) {
14471            sb.append("Process: ").append(processName).append("\n");
14472            sb.append("PID: ").append(process.pid).append("\n");
14473            int flags = process.info.flags;
14474            IPackageManager pm = AppGlobals.getPackageManager();
14475            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14476            for (int ip=0; ip<process.pkgList.size(); ip++) {
14477                String pkg = process.pkgList.keyAt(ip);
14478                sb.append("Package: ").append(pkg);
14479                try {
14480                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14481                    if (pi != null) {
14482                        sb.append(" v").append(pi.versionCode);
14483                        if (pi.versionName != null) {
14484                            sb.append(" (").append(pi.versionName).append(")");
14485                        }
14486                    }
14487                } catch (RemoteException e) {
14488                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14489                }
14490                sb.append("\n");
14491            }
14492        }
14493    }
14494
14495    private static String processClass(ProcessRecord process) {
14496        if (process == null || process.pid == MY_PID) {
14497            return "system_server";
14498        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14499            return "system_app";
14500        } else {
14501            return "data_app";
14502        }
14503    }
14504
14505    private volatile long mWtfClusterStart;
14506    private volatile int mWtfClusterCount;
14507
14508    /**
14509     * Write a description of an error (crash, WTF, ANR) to the drop box.
14510     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14511     * @param process which caused the error, null means the system server
14512     * @param activity which triggered the error, null if unknown
14513     * @param parent activity related to the error, null if unknown
14514     * @param subject line related to the error, null if absent
14515     * @param report in long form describing the error, null if absent
14516     * @param dataFile text file to include in the report, null if none
14517     * @param crashInfo giving an application stack trace, null if absent
14518     */
14519    public void addErrorToDropBox(String eventType,
14520            ProcessRecord process, String processName, ActivityRecord activity,
14521            ActivityRecord parent, String subject,
14522            final String report, final File dataFile,
14523            final ApplicationErrorReport.CrashInfo crashInfo) {
14524        // NOTE -- this must never acquire the ActivityManagerService lock,
14525        // otherwise the watchdog may be prevented from resetting the system.
14526
14527        // Bail early if not published yet
14528        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14529        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14530
14531        // Exit early if the dropbox isn't configured to accept this report type.
14532        final String dropboxTag = processClass(process) + "_" + eventType;
14533        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14534
14535        // Rate-limit how often we're willing to do the heavy lifting below to
14536        // collect and record logs; currently 5 logs per 10 second period.
14537        final long now = SystemClock.elapsedRealtime();
14538        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14539            mWtfClusterStart = now;
14540            mWtfClusterCount = 1;
14541        } else {
14542            if (mWtfClusterCount++ >= 5) return;
14543        }
14544
14545        final StringBuilder sb = new StringBuilder(1024);
14546        appendDropBoxProcessHeaders(process, processName, sb);
14547        if (process != null) {
14548            sb.append("Foreground: ")
14549                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14550                    .append("\n");
14551        }
14552        if (activity != null) {
14553            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14554        }
14555        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14556            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14557        }
14558        if (parent != null && parent != activity) {
14559            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14560        }
14561        if (subject != null) {
14562            sb.append("Subject: ").append(subject).append("\n");
14563        }
14564        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14565        if (Debug.isDebuggerConnected()) {
14566            sb.append("Debugger: Connected\n");
14567        }
14568        sb.append("\n");
14569
14570        // Do the rest in a worker thread to avoid blocking the caller on I/O
14571        // (After this point, we shouldn't access AMS internal data structures.)
14572        Thread worker = new Thread("Error dump: " + dropboxTag) {
14573            @Override
14574            public void run() {
14575                if (report != null) {
14576                    sb.append(report);
14577                }
14578
14579                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14580                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14581                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14582                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14583
14584                if (dataFile != null && maxDataFileSize > 0) {
14585                    try {
14586                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14587                                    "\n\n[[TRUNCATED]]"));
14588                    } catch (IOException e) {
14589                        Slog.e(TAG, "Error reading " + dataFile, e);
14590                    }
14591                }
14592                if (crashInfo != null && crashInfo.stackTrace != null) {
14593                    sb.append(crashInfo.stackTrace);
14594                }
14595
14596                if (lines > 0) {
14597                    sb.append("\n");
14598
14599                    // Merge several logcat streams, and take the last N lines
14600                    InputStreamReader input = null;
14601                    try {
14602                        java.lang.Process logcat = new ProcessBuilder(
14603                                "/system/bin/timeout", "-k", "15s", "10s",
14604                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14605                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14606                                        .redirectErrorStream(true).start();
14607
14608                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14609                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14610                        input = new InputStreamReader(logcat.getInputStream());
14611
14612                        int num;
14613                        char[] buf = new char[8192];
14614                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14615                    } catch (IOException e) {
14616                        Slog.e(TAG, "Error running logcat", e);
14617                    } finally {
14618                        if (input != null) try { input.close(); } catch (IOException e) {}
14619                    }
14620                }
14621
14622                dbox.addText(dropboxTag, sb.toString());
14623            }
14624        };
14625
14626        if (process == null) {
14627            // If process is null, we are being called from some internal code
14628            // and may be about to die -- run this synchronously.
14629            worker.run();
14630        } else {
14631            worker.start();
14632        }
14633    }
14634
14635    @Override
14636    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14637        enforceNotIsolatedCaller("getProcessesInErrorState");
14638        // assume our apps are happy - lazy create the list
14639        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14640
14641        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14642                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14643        int userId = UserHandle.getUserId(Binder.getCallingUid());
14644
14645        synchronized (this) {
14646
14647            // iterate across all processes
14648            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14649                ProcessRecord app = mLruProcesses.get(i);
14650                if (!allUsers && app.userId != userId) {
14651                    continue;
14652                }
14653                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14654                    // This one's in trouble, so we'll generate a report for it
14655                    // crashes are higher priority (in case there's a crash *and* an anr)
14656                    ActivityManager.ProcessErrorStateInfo report = null;
14657                    if (app.crashing) {
14658                        report = app.crashingReport;
14659                    } else if (app.notResponding) {
14660                        report = app.notRespondingReport;
14661                    }
14662
14663                    if (report != null) {
14664                        if (errList == null) {
14665                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14666                        }
14667                        errList.add(report);
14668                    } else {
14669                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14670                                " crashing = " + app.crashing +
14671                                " notResponding = " + app.notResponding);
14672                    }
14673                }
14674            }
14675        }
14676
14677        return errList;
14678    }
14679
14680    static int procStateToImportance(int procState, int memAdj,
14681            ActivityManager.RunningAppProcessInfo currApp,
14682            int clientTargetSdk) {
14683        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14684                procState, clientTargetSdk);
14685        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14686            currApp.lru = memAdj;
14687        } else {
14688            currApp.lru = 0;
14689        }
14690        return imp;
14691    }
14692
14693    private void fillInProcMemInfo(ProcessRecord app,
14694            ActivityManager.RunningAppProcessInfo outInfo,
14695            int clientTargetSdk) {
14696        outInfo.pid = app.pid;
14697        outInfo.uid = app.info.uid;
14698        if (mHeavyWeightProcess == app) {
14699            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14700        }
14701        if (app.persistent) {
14702            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14703        }
14704        if (app.activities.size() > 0) {
14705            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14706        }
14707        outInfo.lastTrimLevel = app.trimMemoryLevel;
14708        int adj = app.curAdj;
14709        int procState = app.curProcState;
14710        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14711        outInfo.importanceReasonCode = app.adjTypeCode;
14712        outInfo.processState = app.curProcState;
14713    }
14714
14715    @Override
14716    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14717        enforceNotIsolatedCaller("getRunningAppProcesses");
14718
14719        final int callingUid = Binder.getCallingUid();
14720        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14721
14722        // Lazy instantiation of list
14723        List<ActivityManager.RunningAppProcessInfo> runList = null;
14724        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14725                callingUid) == PackageManager.PERMISSION_GRANTED;
14726        final int userId = UserHandle.getUserId(callingUid);
14727        final boolean allUids = isGetTasksAllowed(
14728                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14729
14730        synchronized (this) {
14731            // Iterate across all processes
14732            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14733                ProcessRecord app = mLruProcesses.get(i);
14734                if ((!allUsers && app.userId != userId)
14735                        || (!allUids && app.uid != callingUid)) {
14736                    continue;
14737                }
14738                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14739                    // Generate process state info for running application
14740                    ActivityManager.RunningAppProcessInfo currApp =
14741                        new ActivityManager.RunningAppProcessInfo(app.processName,
14742                                app.pid, app.getPackageList());
14743                    fillInProcMemInfo(app, currApp, clientTargetSdk);
14744                    if (app.adjSource instanceof ProcessRecord) {
14745                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14746                        currApp.importanceReasonImportance =
14747                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14748                                        app.adjSourceProcState);
14749                    } else if (app.adjSource instanceof ActivityRecord) {
14750                        ActivityRecord r = (ActivityRecord)app.adjSource;
14751                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14752                    }
14753                    if (app.adjTarget instanceof ComponentName) {
14754                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14755                    }
14756                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14757                    //        + " lru=" + currApp.lru);
14758                    if (runList == null) {
14759                        runList = new ArrayList<>();
14760                    }
14761                    runList.add(currApp);
14762                }
14763            }
14764        }
14765        return runList;
14766    }
14767
14768    @Override
14769    public List<ApplicationInfo> getRunningExternalApplications() {
14770        enforceNotIsolatedCaller("getRunningExternalApplications");
14771        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14772        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14773        if (runningApps != null && runningApps.size() > 0) {
14774            Set<String> extList = new HashSet<String>();
14775            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14776                if (app.pkgList != null) {
14777                    for (String pkg : app.pkgList) {
14778                        extList.add(pkg);
14779                    }
14780                }
14781            }
14782            IPackageManager pm = AppGlobals.getPackageManager();
14783            for (String pkg : extList) {
14784                try {
14785                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14786                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14787                        retList.add(info);
14788                    }
14789                } catch (RemoteException e) {
14790                }
14791            }
14792        }
14793        return retList;
14794    }
14795
14796    @Override
14797    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14798        enforceNotIsolatedCaller("getMyMemoryState");
14799
14800        final int callingUid = Binder.getCallingUid();
14801        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14802
14803        synchronized (this) {
14804            ProcessRecord proc;
14805            synchronized (mPidsSelfLocked) {
14806                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14807            }
14808            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14809        }
14810    }
14811
14812    @Override
14813    public int getMemoryTrimLevel() {
14814        enforceNotIsolatedCaller("getMyMemoryState");
14815        synchronized (this) {
14816            return mLastMemoryLevel;
14817        }
14818    }
14819
14820    @Override
14821    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14822            FileDescriptor err, String[] args, ShellCallback callback,
14823            ResultReceiver resultReceiver) {
14824        (new ActivityManagerShellCommand(this, false)).exec(
14825                this, in, out, err, args, callback, resultReceiver);
14826    }
14827
14828    @Override
14829    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14830        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14831
14832        boolean dumpAll = false;
14833        boolean dumpClient = false;
14834        boolean dumpCheckin = false;
14835        boolean dumpCheckinFormat = false;
14836        boolean dumpVisibleStacksOnly = false;
14837        boolean dumpFocusedStackOnly = false;
14838        String dumpPackage = null;
14839
14840        int opti = 0;
14841        while (opti < args.length) {
14842            String opt = args[opti];
14843            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14844                break;
14845            }
14846            opti++;
14847            if ("-a".equals(opt)) {
14848                dumpAll = true;
14849            } else if ("-c".equals(opt)) {
14850                dumpClient = true;
14851            } else if ("-v".equals(opt)) {
14852                dumpVisibleStacksOnly = true;
14853            } else if ("-f".equals(opt)) {
14854                dumpFocusedStackOnly = true;
14855            } else if ("-p".equals(opt)) {
14856                if (opti < args.length) {
14857                    dumpPackage = args[opti];
14858                    opti++;
14859                } else {
14860                    pw.println("Error: -p option requires package argument");
14861                    return;
14862                }
14863                dumpClient = true;
14864            } else if ("--checkin".equals(opt)) {
14865                dumpCheckin = dumpCheckinFormat = true;
14866            } else if ("-C".equals(opt)) {
14867                dumpCheckinFormat = true;
14868            } else if ("-h".equals(opt)) {
14869                ActivityManagerShellCommand.dumpHelp(pw, true);
14870                return;
14871            } else {
14872                pw.println("Unknown argument: " + opt + "; use -h for help");
14873            }
14874        }
14875
14876        long origId = Binder.clearCallingIdentity();
14877        boolean more = false;
14878        // Is the caller requesting to dump a particular piece of data?
14879        if (opti < args.length) {
14880            String cmd = args[opti];
14881            opti++;
14882            if ("activities".equals(cmd) || "a".equals(cmd)) {
14883                synchronized (this) {
14884                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14885                }
14886            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14887                synchronized (this) {
14888                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14889                }
14890            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14891                String[] newArgs;
14892                String name;
14893                if (opti >= args.length) {
14894                    name = null;
14895                    newArgs = EMPTY_STRING_ARRAY;
14896                } else {
14897                    dumpPackage = args[opti];
14898                    opti++;
14899                    newArgs = new String[args.length - opti];
14900                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14901                            args.length - opti);
14902                }
14903                synchronized (this) {
14904                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14905                }
14906            } else if ("broadcast-stats".equals(cmd)) {
14907                String[] newArgs;
14908                String name;
14909                if (opti >= args.length) {
14910                    name = null;
14911                    newArgs = EMPTY_STRING_ARRAY;
14912                } else {
14913                    dumpPackage = args[opti];
14914                    opti++;
14915                    newArgs = new String[args.length - opti];
14916                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14917                            args.length - opti);
14918                }
14919                synchronized (this) {
14920                    if (dumpCheckinFormat) {
14921                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14922                                dumpPackage);
14923                    } else {
14924                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14925                    }
14926                }
14927            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14928                String[] newArgs;
14929                String name;
14930                if (opti >= args.length) {
14931                    name = null;
14932                    newArgs = EMPTY_STRING_ARRAY;
14933                } else {
14934                    dumpPackage = args[opti];
14935                    opti++;
14936                    newArgs = new String[args.length - opti];
14937                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14938                            args.length - opti);
14939                }
14940                synchronized (this) {
14941                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14942                }
14943            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14944                String[] newArgs;
14945                String name;
14946                if (opti >= args.length) {
14947                    name = null;
14948                    newArgs = EMPTY_STRING_ARRAY;
14949                } else {
14950                    dumpPackage = args[opti];
14951                    opti++;
14952                    newArgs = new String[args.length - opti];
14953                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14954                            args.length - opti);
14955                }
14956                synchronized (this) {
14957                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14958                }
14959            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14960                synchronized (this) {
14961                    dumpOomLocked(fd, pw, args, opti, true);
14962                }
14963            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14964                synchronized (this) {
14965                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14966                }
14967            } else if ("provider".equals(cmd)) {
14968                String[] newArgs;
14969                String name;
14970                if (opti >= args.length) {
14971                    name = null;
14972                    newArgs = EMPTY_STRING_ARRAY;
14973                } else {
14974                    name = args[opti];
14975                    opti++;
14976                    newArgs = new String[args.length - opti];
14977                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14978                }
14979                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14980                    pw.println("No providers match: " + name);
14981                    pw.println("Use -h for help.");
14982                }
14983            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14984                synchronized (this) {
14985                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14986                }
14987            } else if ("service".equals(cmd)) {
14988                String[] newArgs;
14989                String name;
14990                if (opti >= args.length) {
14991                    name = null;
14992                    newArgs = EMPTY_STRING_ARRAY;
14993                } else {
14994                    name = args[opti];
14995                    opti++;
14996                    newArgs = new String[args.length - opti];
14997                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14998                            args.length - opti);
14999                }
15000                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15001                    pw.println("No services match: " + name);
15002                    pw.println("Use -h for help.");
15003                }
15004            } else if ("package".equals(cmd)) {
15005                String[] newArgs;
15006                if (opti >= args.length) {
15007                    pw.println("package: no package name specified");
15008                    pw.println("Use -h for help.");
15009                } else {
15010                    dumpPackage = args[opti];
15011                    opti++;
15012                    newArgs = new String[args.length - opti];
15013                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15014                            args.length - opti);
15015                    args = newArgs;
15016                    opti = 0;
15017                    more = true;
15018                }
15019            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15020                synchronized (this) {
15021                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15022                }
15023            } else if ("settings".equals(cmd)) {
15024                synchronized (this) {
15025                    mConstants.dump(pw);
15026                }
15027            } else if ("services".equals(cmd) || "s".equals(cmd)) {
15028                if (dumpClient) {
15029                    ActiveServices.ServiceDumper dumper;
15030                    synchronized (this) {
15031                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15032                                dumpPackage);
15033                    }
15034                    dumper.dumpWithClient();
15035                } else {
15036                    synchronized (this) {
15037                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15038                                dumpPackage).dumpLocked();
15039                    }
15040                }
15041            } else if ("locks".equals(cmd)) {
15042                LockGuard.dump(fd, pw, args);
15043            } else {
15044                // Dumping a single activity?
15045                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15046                        dumpFocusedStackOnly)) {
15047                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15048                    int res = shell.exec(this, null, fd, null, args, null,
15049                            new ResultReceiver(null));
15050                    if (res < 0) {
15051                        pw.println("Bad activity command, or no activities match: " + cmd);
15052                        pw.println("Use -h for help.");
15053                    }
15054                }
15055            }
15056            if (!more) {
15057                Binder.restoreCallingIdentity(origId);
15058                return;
15059            }
15060        }
15061
15062        // No piece of data specified, dump everything.
15063        if (dumpCheckinFormat) {
15064            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15065        } else if (dumpClient) {
15066            ActiveServices.ServiceDumper sdumper;
15067            synchronized (this) {
15068                mConstants.dump(pw);
15069                pw.println();
15070                if (dumpAll) {
15071                    pw.println("-------------------------------------------------------------------------------");
15072                }
15073                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15074                pw.println();
15075                if (dumpAll) {
15076                    pw.println("-------------------------------------------------------------------------------");
15077                }
15078                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15079                pw.println();
15080                if (dumpAll) {
15081                    pw.println("-------------------------------------------------------------------------------");
15082                }
15083                if (dumpAll || dumpPackage != null) {
15084                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15085                    pw.println();
15086                    if (dumpAll) {
15087                        pw.println("-------------------------------------------------------------------------------");
15088                    }
15089                }
15090                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15091                pw.println();
15092                if (dumpAll) {
15093                    pw.println("-------------------------------------------------------------------------------");
15094                }
15095                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15096                pw.println();
15097                if (dumpAll) {
15098                    pw.println("-------------------------------------------------------------------------------");
15099                }
15100                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15101                        dumpPackage);
15102            }
15103            sdumper.dumpWithClient();
15104            pw.println();
15105            synchronized (this) {
15106                if (dumpAll) {
15107                    pw.println("-------------------------------------------------------------------------------");
15108                }
15109                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15110                pw.println();
15111                if (dumpAll) {
15112                    pw.println("-------------------------------------------------------------------------------");
15113                }
15114                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15115                if (mAssociations.size() > 0) {
15116                    pw.println();
15117                    if (dumpAll) {
15118                        pw.println("-------------------------------------------------------------------------------");
15119                    }
15120                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15121                }
15122                pw.println();
15123                if (dumpAll) {
15124                    pw.println("-------------------------------------------------------------------------------");
15125                }
15126                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15127            }
15128
15129        } else {
15130            synchronized (this) {
15131                mConstants.dump(pw);
15132                pw.println();
15133                if (dumpAll) {
15134                    pw.println("-------------------------------------------------------------------------------");
15135                }
15136                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15137                pw.println();
15138                if (dumpAll) {
15139                    pw.println("-------------------------------------------------------------------------------");
15140                }
15141                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15142                pw.println();
15143                if (dumpAll) {
15144                    pw.println("-------------------------------------------------------------------------------");
15145                }
15146                if (dumpAll || dumpPackage != null) {
15147                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15148                    pw.println();
15149                    if (dumpAll) {
15150                        pw.println("-------------------------------------------------------------------------------");
15151                    }
15152                }
15153                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15154                pw.println();
15155                if (dumpAll) {
15156                    pw.println("-------------------------------------------------------------------------------");
15157                }
15158                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15159                pw.println();
15160                if (dumpAll) {
15161                    pw.println("-------------------------------------------------------------------------------");
15162                }
15163                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15164                        .dumpLocked();
15165                pw.println();
15166                if (dumpAll) {
15167                    pw.println("-------------------------------------------------------------------------------");
15168                }
15169                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15170                pw.println();
15171                if (dumpAll) {
15172                    pw.println("-------------------------------------------------------------------------------");
15173                }
15174                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15175                if (mAssociations.size() > 0) {
15176                    pw.println();
15177                    if (dumpAll) {
15178                        pw.println("-------------------------------------------------------------------------------");
15179                    }
15180                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15181                }
15182                pw.println();
15183                if (dumpAll) {
15184                    pw.println("-------------------------------------------------------------------------------");
15185                }
15186                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15187            }
15188        }
15189        Binder.restoreCallingIdentity(origId);
15190    }
15191
15192    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15193            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15194        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15195
15196        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15197                dumpPackage);
15198        boolean needSep = printedAnything;
15199
15200        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15201                mStackSupervisor.getResumedActivityLocked(),
15202                dumpPackage, needSep, "  ResumedActivity: ");
15203        if (printed) {
15204            printedAnything = true;
15205            needSep = false;
15206        }
15207
15208        if (dumpPackage == null) {
15209            if (needSep) {
15210                pw.println();
15211            }
15212            needSep = true;
15213            printedAnything = true;
15214            mStackSupervisor.dump(pw, "  ");
15215        }
15216
15217        if (!printedAnything) {
15218            pw.println("  (nothing)");
15219        }
15220    }
15221
15222    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15223            int opti, boolean dumpAll, String dumpPackage) {
15224        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15225
15226        boolean printedAnything = false;
15227
15228        if (mRecentTasks != null && mRecentTasks.size() > 0) {
15229            boolean printedHeader = false;
15230
15231            final int N = mRecentTasks.size();
15232            for (int i=0; i<N; i++) {
15233                TaskRecord tr = mRecentTasks.get(i);
15234                if (dumpPackage != null) {
15235                    if (tr.realActivity == null ||
15236                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
15237                        continue;
15238                    }
15239                }
15240                if (!printedHeader) {
15241                    pw.println("  Recent tasks:");
15242                    printedHeader = true;
15243                    printedAnything = true;
15244                }
15245                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15246                        pw.println(tr);
15247                if (dumpAll) {
15248                    mRecentTasks.get(i).dump(pw, "    ");
15249                }
15250            }
15251        }
15252
15253        if (!printedAnything) {
15254            pw.println("  (nothing)");
15255        }
15256    }
15257
15258    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15259            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15260        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15261
15262        int dumpUid = 0;
15263        if (dumpPackage != null) {
15264            IPackageManager pm = AppGlobals.getPackageManager();
15265            try {
15266                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15267            } catch (RemoteException e) {
15268            }
15269        }
15270
15271        boolean printedAnything = false;
15272
15273        final long now = SystemClock.uptimeMillis();
15274
15275        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15276            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15277                    = mAssociations.valueAt(i1);
15278            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15279                SparseArray<ArrayMap<String, Association>> sourceUids
15280                        = targetComponents.valueAt(i2);
15281                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15282                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15283                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15284                        Association ass = sourceProcesses.valueAt(i4);
15285                        if (dumpPackage != null) {
15286                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15287                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15288                                continue;
15289                            }
15290                        }
15291                        printedAnything = true;
15292                        pw.print("  ");
15293                        pw.print(ass.mTargetProcess);
15294                        pw.print("/");
15295                        UserHandle.formatUid(pw, ass.mTargetUid);
15296                        pw.print(" <- ");
15297                        pw.print(ass.mSourceProcess);
15298                        pw.print("/");
15299                        UserHandle.formatUid(pw, ass.mSourceUid);
15300                        pw.println();
15301                        pw.print("    via ");
15302                        pw.print(ass.mTargetComponent.flattenToShortString());
15303                        pw.println();
15304                        pw.print("    ");
15305                        long dur = ass.mTime;
15306                        if (ass.mNesting > 0) {
15307                            dur += now - ass.mStartTime;
15308                        }
15309                        TimeUtils.formatDuration(dur, pw);
15310                        pw.print(" (");
15311                        pw.print(ass.mCount);
15312                        pw.print(" times)");
15313                        pw.print("  ");
15314                        for (int i=0; i<ass.mStateTimes.length; i++) {
15315                            long amt = ass.mStateTimes[i];
15316                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15317                                amt += now - ass.mLastStateUptime;
15318                            }
15319                            if (amt != 0) {
15320                                pw.print(" ");
15321                                pw.print(ProcessList.makeProcStateString(
15322                                            i + ActivityManager.MIN_PROCESS_STATE));
15323                                pw.print("=");
15324                                TimeUtils.formatDuration(amt, pw);
15325                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15326                                    pw.print("*");
15327                                }
15328                            }
15329                        }
15330                        pw.println();
15331                        if (ass.mNesting > 0) {
15332                            pw.print("    Currently active: ");
15333                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15334                            pw.println();
15335                        }
15336                    }
15337                }
15338            }
15339
15340        }
15341
15342        if (!printedAnything) {
15343            pw.println("  (nothing)");
15344        }
15345    }
15346
15347    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15348            String header, boolean needSep) {
15349        boolean printed = false;
15350        int whichAppId = -1;
15351        if (dumpPackage != null) {
15352            try {
15353                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15354                        dumpPackage, 0);
15355                whichAppId = UserHandle.getAppId(info.uid);
15356            } catch (NameNotFoundException e) {
15357                e.printStackTrace();
15358            }
15359        }
15360        for (int i=0; i<uids.size(); i++) {
15361            UidRecord uidRec = uids.valueAt(i);
15362            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15363                continue;
15364            }
15365            if (!printed) {
15366                printed = true;
15367                if (needSep) {
15368                    pw.println();
15369                }
15370                pw.print("  ");
15371                pw.println(header);
15372                needSep = true;
15373            }
15374            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15375            pw.print(": "); pw.println(uidRec);
15376        }
15377        return printed;
15378    }
15379
15380    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15381            int opti, boolean dumpAll, String dumpPackage) {
15382        boolean needSep = false;
15383        boolean printedAnything = false;
15384        int numPers = 0;
15385
15386        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15387
15388        if (dumpAll) {
15389            final int NP = mProcessNames.getMap().size();
15390            for (int ip=0; ip<NP; ip++) {
15391                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15392                final int NA = procs.size();
15393                for (int ia=0; ia<NA; ia++) {
15394                    ProcessRecord r = procs.valueAt(ia);
15395                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15396                        continue;
15397                    }
15398                    if (!needSep) {
15399                        pw.println("  All known processes:");
15400                        needSep = true;
15401                        printedAnything = true;
15402                    }
15403                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15404                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15405                        pw.print(" "); pw.println(r);
15406                    r.dump(pw, "    ");
15407                    if (r.persistent) {
15408                        numPers++;
15409                    }
15410                }
15411            }
15412        }
15413
15414        if (mIsolatedProcesses.size() > 0) {
15415            boolean printed = false;
15416            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15417                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15418                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15419                    continue;
15420                }
15421                if (!printed) {
15422                    if (needSep) {
15423                        pw.println();
15424                    }
15425                    pw.println("  Isolated process list (sorted by uid):");
15426                    printedAnything = true;
15427                    printed = true;
15428                    needSep = true;
15429                }
15430                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15431                pw.println(r);
15432            }
15433        }
15434
15435        if (mActiveInstrumentation.size() > 0) {
15436            boolean printed = false;
15437            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15438                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15439                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15440                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15441                    continue;
15442                }
15443                if (!printed) {
15444                    if (needSep) {
15445                        pw.println();
15446                    }
15447                    pw.println("  Active instrumentation:");
15448                    printedAnything = true;
15449                    printed = true;
15450                    needSep = true;
15451                }
15452                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15453                pw.println(ai);
15454                ai.dump(pw, "      ");
15455            }
15456        }
15457
15458        if (mActiveUids.size() > 0) {
15459            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15460                printedAnything = needSep = true;
15461            }
15462        }
15463        if (dumpAll) {
15464            if (mValidateUids.size() > 0) {
15465                if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15466                    printedAnything = needSep = true;
15467                }
15468            }
15469        }
15470
15471        if (mLruProcesses.size() > 0) {
15472            if (needSep) {
15473                pw.println();
15474            }
15475            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15476                    pw.print(" total, non-act at ");
15477                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15478                    pw.print(", non-svc at ");
15479                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15480                    pw.println("):");
15481            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15482            needSep = true;
15483            printedAnything = true;
15484        }
15485
15486        if (dumpAll || dumpPackage != null) {
15487            synchronized (mPidsSelfLocked) {
15488                boolean printed = false;
15489                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15490                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15491                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15492                        continue;
15493                    }
15494                    if (!printed) {
15495                        if (needSep) pw.println();
15496                        needSep = true;
15497                        pw.println("  PID mappings:");
15498                        printed = true;
15499                        printedAnything = true;
15500                    }
15501                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15502                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15503                }
15504            }
15505        }
15506
15507        if (mImportantProcesses.size() > 0) {
15508            synchronized (mPidsSelfLocked) {
15509                boolean printed = false;
15510                for (int i = 0; i< mImportantProcesses.size(); i++) {
15511                    ProcessRecord r = mPidsSelfLocked.get(
15512                            mImportantProcesses.valueAt(i).pid);
15513                    if (dumpPackage != null && (r == null
15514                            || !r.pkgList.containsKey(dumpPackage))) {
15515                        continue;
15516                    }
15517                    if (!printed) {
15518                        if (needSep) pw.println();
15519                        needSep = true;
15520                        pw.println("  Foreground Processes:");
15521                        printed = true;
15522                        printedAnything = true;
15523                    }
15524                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15525                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15526                }
15527            }
15528        }
15529
15530        if (mPersistentStartingProcesses.size() > 0) {
15531            if (needSep) pw.println();
15532            needSep = true;
15533            printedAnything = true;
15534            pw.println("  Persisent processes that are starting:");
15535            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15536                    "Starting Norm", "Restarting PERS", dumpPackage);
15537        }
15538
15539        if (mRemovedProcesses.size() > 0) {
15540            if (needSep) pw.println();
15541            needSep = true;
15542            printedAnything = true;
15543            pw.println("  Processes that are being removed:");
15544            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15545                    "Removed Norm", "Removed PERS", dumpPackage);
15546        }
15547
15548        if (mProcessesOnHold.size() > 0) {
15549            if (needSep) pw.println();
15550            needSep = true;
15551            printedAnything = true;
15552            pw.println("  Processes that are on old until the system is ready:");
15553            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15554                    "OnHold Norm", "OnHold PERS", dumpPackage);
15555        }
15556
15557        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15558
15559        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15560        if (needSep) {
15561            printedAnything = true;
15562        }
15563
15564        if (dumpPackage == null) {
15565            pw.println();
15566            needSep = false;
15567            mUserController.dump(pw, dumpAll);
15568        }
15569        if (mHomeProcess != null && (dumpPackage == null
15570                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15571            if (needSep) {
15572                pw.println();
15573                needSep = false;
15574            }
15575            pw.println("  mHomeProcess: " + mHomeProcess);
15576        }
15577        if (mPreviousProcess != null && (dumpPackage == null
15578                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15579            if (needSep) {
15580                pw.println();
15581                needSep = false;
15582            }
15583            pw.println("  mPreviousProcess: " + mPreviousProcess);
15584        }
15585        if (dumpAll) {
15586            StringBuilder sb = new StringBuilder(128);
15587            sb.append("  mPreviousProcessVisibleTime: ");
15588            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15589            pw.println(sb);
15590        }
15591        if (mHeavyWeightProcess != null && (dumpPackage == null
15592                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15593            if (needSep) {
15594                pw.println();
15595                needSep = false;
15596            }
15597            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15598        }
15599        if (dumpPackage == null) {
15600            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15601            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15602        }
15603        if (dumpAll) {
15604            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15605            if (mCompatModePackages.getPackages().size() > 0) {
15606                boolean printed = false;
15607                for (Map.Entry<String, Integer> entry
15608                        : mCompatModePackages.getPackages().entrySet()) {
15609                    String pkg = entry.getKey();
15610                    int mode = entry.getValue();
15611                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15612                        continue;
15613                    }
15614                    if (!printed) {
15615                        pw.println("  mScreenCompatPackages:");
15616                        printed = true;
15617                    }
15618                    pw.print("    "); pw.print(pkg); pw.print(": ");
15619                            pw.print(mode); pw.println();
15620                }
15621            }
15622            final int NI = mUidObservers.getRegisteredCallbackCount();
15623            boolean printed = false;
15624            for (int i=0; i<NI; i++) {
15625                final UidObserverRegistration reg = (UidObserverRegistration)
15626                        mUidObservers.getRegisteredCallbackCookie(i);
15627                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15628                    if (!printed) {
15629                        pw.println("  mUidObservers:");
15630                        printed = true;
15631                    }
15632                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15633                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15634                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15635                        pw.print(" IDLE");
15636                    }
15637                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15638                        pw.print(" ACT" );
15639                    }
15640                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15641                        pw.print(" GONE");
15642                    }
15643                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15644                        pw.print(" STATE");
15645                        pw.print(" (cut="); pw.print(reg.cutpoint);
15646                        pw.print(")");
15647                    }
15648                    pw.println();
15649                    if (reg.lastProcStates != null) {
15650                        final int NJ = reg.lastProcStates.size();
15651                        for (int j=0; j<NJ; j++) {
15652                            pw.print("      Last ");
15653                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15654                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15655                        }
15656                    }
15657                }
15658            }
15659            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15660            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15661            if (mPendingTempWhitelist.size() > 0) {
15662                pw.println("  mPendingTempWhitelist:");
15663                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15664                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15665                    pw.print("    ");
15666                    UserHandle.formatUid(pw, ptw.targetUid);
15667                    pw.print(": ");
15668                    TimeUtils.formatDuration(ptw.duration, pw);
15669                    pw.print(" ");
15670                    pw.println(ptw.tag);
15671                }
15672            }
15673        }
15674        if (dumpPackage == null) {
15675            pw.println("  mWakefulness="
15676                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15677            pw.println("  mSleepTokens=" + mSleepTokens);
15678            pw.println("  mSleeping=" + mSleeping);
15679            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15680            if (mRunningVoice != null) {
15681                pw.println("  mRunningVoice=" + mRunningVoice);
15682                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15683            }
15684        }
15685        pw.println("  mVrController=" + mVrController);
15686        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15687                || mOrigWaitForDebugger) {
15688            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15689                    || dumpPackage.equals(mOrigDebugApp)) {
15690                if (needSep) {
15691                    pw.println();
15692                    needSep = false;
15693                }
15694                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15695                        + " mDebugTransient=" + mDebugTransient
15696                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15697            }
15698        }
15699        if (mCurAppTimeTracker != null) {
15700            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15701        }
15702        if (mMemWatchProcesses.getMap().size() > 0) {
15703            pw.println("  Mem watch processes:");
15704            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15705                    = mMemWatchProcesses.getMap();
15706            for (int i=0; i<procs.size(); i++) {
15707                final String proc = procs.keyAt(i);
15708                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15709                for (int j=0; j<uids.size(); j++) {
15710                    if (needSep) {
15711                        pw.println();
15712                        needSep = false;
15713                    }
15714                    StringBuilder sb = new StringBuilder();
15715                    sb.append("    ").append(proc).append('/');
15716                    UserHandle.formatUid(sb, uids.keyAt(j));
15717                    Pair<Long, String> val = uids.valueAt(j);
15718                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15719                    if (val.second != null) {
15720                        sb.append(", report to ").append(val.second);
15721                    }
15722                    pw.println(sb.toString());
15723                }
15724            }
15725            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15726            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15727            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15728                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15729        }
15730        if (mTrackAllocationApp != null) {
15731            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15732                if (needSep) {
15733                    pw.println();
15734                    needSep = false;
15735                }
15736                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15737            }
15738        }
15739        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15740                || mProfileFd != null) {
15741            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15742                if (needSep) {
15743                    pw.println();
15744                    needSep = false;
15745                }
15746                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15747                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15748                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15749                        + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15750                pw.println("  mProfileType=" + mProfileType);
15751            }
15752        }
15753        if (mNativeDebuggingApp != null) {
15754            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15755                if (needSep) {
15756                    pw.println();
15757                    needSep = false;
15758                }
15759                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15760            }
15761        }
15762        if (dumpPackage == null) {
15763            if (mAlwaysFinishActivities) {
15764                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15765            }
15766            if (mController != null) {
15767                pw.println("  mController=" + mController
15768                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15769            }
15770            if (dumpAll) {
15771                pw.println("  Total persistent processes: " + numPers);
15772                pw.println("  mProcessesReady=" + mProcessesReady
15773                        + " mSystemReady=" + mSystemReady
15774                        + " mBooted=" + mBooted
15775                        + " mFactoryTest=" + mFactoryTest);
15776                pw.println("  mBooting=" + mBooting
15777                        + " mCallFinishBooting=" + mCallFinishBooting
15778                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15779                pw.print("  mLastPowerCheckRealtime=");
15780                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15781                        pw.println("");
15782                pw.print("  mLastPowerCheckUptime=");
15783                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15784                        pw.println("");
15785                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15786                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15787                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15788                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15789                        + " (" + mLruProcesses.size() + " total)"
15790                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15791                        + " mNumServiceProcs=" + mNumServiceProcs
15792                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15793                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15794                        + " mLastMemoryLevel=" + mLastMemoryLevel
15795                        + " mLastNumProcesses=" + mLastNumProcesses);
15796                long now = SystemClock.uptimeMillis();
15797                pw.print("  mLastIdleTime=");
15798                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15799                        pw.print(" mLowRamSinceLastIdle=");
15800                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15801                        pw.println();
15802            }
15803        }
15804
15805        if (!printedAnything) {
15806            pw.println("  (nothing)");
15807        }
15808    }
15809
15810    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15811            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15812        if (mProcessesToGc.size() > 0) {
15813            boolean printed = false;
15814            long now = SystemClock.uptimeMillis();
15815            for (int i=0; i<mProcessesToGc.size(); i++) {
15816                ProcessRecord proc = mProcessesToGc.get(i);
15817                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15818                    continue;
15819                }
15820                if (!printed) {
15821                    if (needSep) pw.println();
15822                    needSep = true;
15823                    pw.println("  Processes that are waiting to GC:");
15824                    printed = true;
15825                }
15826                pw.print("    Process "); pw.println(proc);
15827                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15828                        pw.print(", last gced=");
15829                        pw.print(now-proc.lastRequestedGc);
15830                        pw.print(" ms ago, last lowMem=");
15831                        pw.print(now-proc.lastLowMemory);
15832                        pw.println(" ms ago");
15833
15834            }
15835        }
15836        return needSep;
15837    }
15838
15839    void printOomLevel(PrintWriter pw, String name, int adj) {
15840        pw.print("    ");
15841        if (adj >= 0) {
15842            pw.print(' ');
15843            if (adj < 10) pw.print(' ');
15844        } else {
15845            if (adj > -10) pw.print(' ');
15846        }
15847        pw.print(adj);
15848        pw.print(": ");
15849        pw.print(name);
15850        pw.print(" (");
15851        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15852        pw.println(")");
15853    }
15854
15855    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15856            int opti, boolean dumpAll) {
15857        boolean needSep = false;
15858
15859        if (mLruProcesses.size() > 0) {
15860            if (needSep) pw.println();
15861            needSep = true;
15862            pw.println("  OOM levels:");
15863            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15864            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15865            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15866            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15867            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15868            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15869            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15870            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15871            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15872            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15873            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15874            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15875            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15876            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15877
15878            if (needSep) pw.println();
15879            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15880                    pw.print(" total, non-act at ");
15881                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15882                    pw.print(", non-svc at ");
15883                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15884                    pw.println("):");
15885            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15886            needSep = true;
15887        }
15888
15889        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15890
15891        pw.println();
15892        pw.println("  mHomeProcess: " + mHomeProcess);
15893        pw.println("  mPreviousProcess: " + mPreviousProcess);
15894        if (mHeavyWeightProcess != null) {
15895            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15896        }
15897
15898        return true;
15899    }
15900
15901    /**
15902     * There are three ways to call this:
15903     *  - no provider specified: dump all the providers
15904     *  - a flattened component name that matched an existing provider was specified as the
15905     *    first arg: dump that one provider
15906     *  - the first arg isn't the flattened component name of an existing provider:
15907     *    dump all providers whose component contains the first arg as a substring
15908     */
15909    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15910            int opti, boolean dumpAll) {
15911        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15912    }
15913
15914    static class ItemMatcher {
15915        ArrayList<ComponentName> components;
15916        ArrayList<String> strings;
15917        ArrayList<Integer> objects;
15918        boolean all;
15919
15920        ItemMatcher() {
15921            all = true;
15922        }
15923
15924        void build(String name) {
15925            ComponentName componentName = ComponentName.unflattenFromString(name);
15926            if (componentName != null) {
15927                if (components == null) {
15928                    components = new ArrayList<ComponentName>();
15929                }
15930                components.add(componentName);
15931                all = false;
15932            } else {
15933                int objectId = 0;
15934                // Not a '/' separated full component name; maybe an object ID?
15935                try {
15936                    objectId = Integer.parseInt(name, 16);
15937                    if (objects == null) {
15938                        objects = new ArrayList<Integer>();
15939                    }
15940                    objects.add(objectId);
15941                    all = false;
15942                } catch (RuntimeException e) {
15943                    // Not an integer; just do string match.
15944                    if (strings == null) {
15945                        strings = new ArrayList<String>();
15946                    }
15947                    strings.add(name);
15948                    all = false;
15949                }
15950            }
15951        }
15952
15953        int build(String[] args, int opti) {
15954            for (; opti<args.length; opti++) {
15955                String name = args[opti];
15956                if ("--".equals(name)) {
15957                    return opti+1;
15958                }
15959                build(name);
15960            }
15961            return opti;
15962        }
15963
15964        boolean match(Object object, ComponentName comp) {
15965            if (all) {
15966                return true;
15967            }
15968            if (components != null) {
15969                for (int i=0; i<components.size(); i++) {
15970                    if (components.get(i).equals(comp)) {
15971                        return true;
15972                    }
15973                }
15974            }
15975            if (objects != null) {
15976                for (int i=0; i<objects.size(); i++) {
15977                    if (System.identityHashCode(object) == objects.get(i)) {
15978                        return true;
15979                    }
15980                }
15981            }
15982            if (strings != null) {
15983                String flat = comp.flattenToString();
15984                for (int i=0; i<strings.size(); i++) {
15985                    if (flat.contains(strings.get(i))) {
15986                        return true;
15987                    }
15988                }
15989            }
15990            return false;
15991        }
15992    }
15993
15994    /**
15995     * There are three things that cmd can be:
15996     *  - a flattened component name that matches an existing activity
15997     *  - the cmd arg isn't the flattened component name of an existing activity:
15998     *    dump all activity whose component contains the cmd as a substring
15999     *  - A hex number of the ActivityRecord object instance.
16000     *
16001     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16002     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16003     */
16004    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16005            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16006        ArrayList<ActivityRecord> activities;
16007
16008        synchronized (this) {
16009            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16010                    dumpFocusedStackOnly);
16011        }
16012
16013        if (activities.size() <= 0) {
16014            return false;
16015        }
16016
16017        String[] newArgs = new String[args.length - opti];
16018        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16019
16020        TaskRecord lastTask = null;
16021        boolean needSep = false;
16022        for (int i=activities.size()-1; i>=0; i--) {
16023            ActivityRecord r = activities.get(i);
16024            if (needSep) {
16025                pw.println();
16026            }
16027            needSep = true;
16028            synchronized (this) {
16029                final TaskRecord task = r.getTask();
16030                if (lastTask != task) {
16031                    lastTask = task;
16032                    pw.print("TASK "); pw.print(lastTask.affinity);
16033                            pw.print(" id="); pw.print(lastTask.taskId);
16034                            pw.print(" userId="); pw.println(lastTask.userId);
16035                    if (dumpAll) {
16036                        lastTask.dump(pw, "  ");
16037                    }
16038                }
16039            }
16040            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16041        }
16042        return true;
16043    }
16044
16045    /**
16046     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16047     * there is a thread associated with the activity.
16048     */
16049    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16050            final ActivityRecord r, String[] args, boolean dumpAll) {
16051        String innerPrefix = prefix + "  ";
16052        synchronized (this) {
16053            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16054                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16055                    pw.print(" pid=");
16056                    if (r.app != null) pw.println(r.app.pid);
16057                    else pw.println("(not running)");
16058            if (dumpAll) {
16059                r.dump(pw, innerPrefix);
16060            }
16061        }
16062        if (r.app != null && r.app.thread != null) {
16063            // flush anything that is already in the PrintWriter since the thread is going
16064            // to write to the file descriptor directly
16065            pw.flush();
16066            try {
16067                TransferPipe tp = new TransferPipe();
16068                try {
16069                    r.app.thread.dumpActivity(tp.getWriteFd(),
16070                            r.appToken, innerPrefix, args);
16071                    tp.go(fd);
16072                } finally {
16073                    tp.kill();
16074                }
16075            } catch (IOException e) {
16076                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16077            } catch (RemoteException e) {
16078                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16079            }
16080        }
16081    }
16082
16083    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16084            int opti, boolean dumpAll, String dumpPackage) {
16085        boolean needSep = false;
16086        boolean onlyHistory = false;
16087        boolean printedAnything = false;
16088
16089        if ("history".equals(dumpPackage)) {
16090            if (opti < args.length && "-s".equals(args[opti])) {
16091                dumpAll = false;
16092            }
16093            onlyHistory = true;
16094            dumpPackage = null;
16095        }
16096
16097        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16098        if (!onlyHistory && dumpAll) {
16099            if (mRegisteredReceivers.size() > 0) {
16100                boolean printed = false;
16101                Iterator it = mRegisteredReceivers.values().iterator();
16102                while (it.hasNext()) {
16103                    ReceiverList r = (ReceiverList)it.next();
16104                    if (dumpPackage != null && (r.app == null ||
16105                            !dumpPackage.equals(r.app.info.packageName))) {
16106                        continue;
16107                    }
16108                    if (!printed) {
16109                        pw.println("  Registered Receivers:");
16110                        needSep = true;
16111                        printed = true;
16112                        printedAnything = true;
16113                    }
16114                    pw.print("  * "); pw.println(r);
16115                    r.dump(pw, "    ");
16116                }
16117            }
16118
16119            if (mReceiverResolver.dump(pw, needSep ?
16120                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16121                    "    ", dumpPackage, false, false)) {
16122                needSep = true;
16123                printedAnything = true;
16124            }
16125        }
16126
16127        for (BroadcastQueue q : mBroadcastQueues) {
16128            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16129            printedAnything |= needSep;
16130        }
16131
16132        needSep = true;
16133
16134        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16135            for (int user=0; user<mStickyBroadcasts.size(); user++) {
16136                if (needSep) {
16137                    pw.println();
16138                }
16139                needSep = true;
16140                printedAnything = true;
16141                pw.print("  Sticky broadcasts for user ");
16142                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16143                StringBuilder sb = new StringBuilder(128);
16144                for (Map.Entry<String, ArrayList<Intent>> ent
16145                        : mStickyBroadcasts.valueAt(user).entrySet()) {
16146                    pw.print("  * Sticky action "); pw.print(ent.getKey());
16147                    if (dumpAll) {
16148                        pw.println(":");
16149                        ArrayList<Intent> intents = ent.getValue();
16150                        final int N = intents.size();
16151                        for (int i=0; i<N; i++) {
16152                            sb.setLength(0);
16153                            sb.append("    Intent: ");
16154                            intents.get(i).toShortString(sb, false, true, false, false);
16155                            pw.println(sb.toString());
16156                            Bundle bundle = intents.get(i).getExtras();
16157                            if (bundle != null) {
16158                                pw.print("      ");
16159                                pw.println(bundle.toString());
16160                            }
16161                        }
16162                    } else {
16163                        pw.println("");
16164                    }
16165                }
16166            }
16167        }
16168
16169        if (!onlyHistory && dumpAll) {
16170            pw.println();
16171            for (BroadcastQueue queue : mBroadcastQueues) {
16172                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16173                        + queue.mBroadcastsScheduled);
16174            }
16175            pw.println("  mHandler:");
16176            mHandler.dump(new PrintWriterPrinter(pw), "    ");
16177            needSep = true;
16178            printedAnything = true;
16179        }
16180
16181        if (!printedAnything) {
16182            pw.println("  (nothing)");
16183        }
16184    }
16185
16186    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16187            int opti, boolean dumpAll, String dumpPackage) {
16188        if (mCurBroadcastStats == null) {
16189            return;
16190        }
16191
16192        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16193        final long now = SystemClock.elapsedRealtime();
16194        if (mLastBroadcastStats != null) {
16195            pw.print("  Last stats (from ");
16196            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16197            pw.print(" to ");
16198            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16199            pw.print(", ");
16200            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16201                    - mLastBroadcastStats.mStartUptime, pw);
16202            pw.println(" uptime):");
16203            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16204                pw.println("    (nothing)");
16205            }
16206            pw.println();
16207        }
16208        pw.print("  Current stats (from ");
16209        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16210        pw.print(" to now, ");
16211        TimeUtils.formatDuration(SystemClock.uptimeMillis()
16212                - mCurBroadcastStats.mStartUptime, pw);
16213        pw.println(" uptime):");
16214        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16215            pw.println("    (nothing)");
16216        }
16217    }
16218
16219    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16220            int opti, boolean fullCheckin, String dumpPackage) {
16221        if (mCurBroadcastStats == null) {
16222            return;
16223        }
16224
16225        if (mLastBroadcastStats != null) {
16226            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16227            if (fullCheckin) {
16228                mLastBroadcastStats = null;
16229                return;
16230            }
16231        }
16232        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16233        if (fullCheckin) {
16234            mCurBroadcastStats = null;
16235        }
16236    }
16237
16238    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16239            int opti, boolean dumpAll, String dumpPackage) {
16240        boolean needSep;
16241        boolean printedAnything = false;
16242
16243        ItemMatcher matcher = new ItemMatcher();
16244        matcher.build(args, opti);
16245
16246        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16247
16248        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16249        printedAnything |= needSep;
16250
16251        if (mLaunchingProviders.size() > 0) {
16252            boolean printed = false;
16253            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16254                ContentProviderRecord r = mLaunchingProviders.get(i);
16255                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16256                    continue;
16257                }
16258                if (!printed) {
16259                    if (needSep) pw.println();
16260                    needSep = true;
16261                    pw.println("  Launching content providers:");
16262                    printed = true;
16263                    printedAnything = true;
16264                }
16265                pw.print("  Launching #"); pw.print(i); pw.print(": ");
16266                        pw.println(r);
16267            }
16268        }
16269
16270        if (!printedAnything) {
16271            pw.println("  (nothing)");
16272        }
16273    }
16274
16275    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16276            int opti, boolean dumpAll, String dumpPackage) {
16277        boolean needSep = false;
16278        boolean printedAnything = false;
16279
16280        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16281
16282        if (mGrantedUriPermissions.size() > 0) {
16283            boolean printed = false;
16284            int dumpUid = -2;
16285            if (dumpPackage != null) {
16286                try {
16287                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16288                            MATCH_ANY_USER, 0);
16289                } catch (NameNotFoundException e) {
16290                    dumpUid = -1;
16291                }
16292            }
16293            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16294                int uid = mGrantedUriPermissions.keyAt(i);
16295                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16296                    continue;
16297                }
16298                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16299                if (!printed) {
16300                    if (needSep) pw.println();
16301                    needSep = true;
16302                    pw.println("  Granted Uri Permissions:");
16303                    printed = true;
16304                    printedAnything = true;
16305                }
16306                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16307                for (UriPermission perm : perms.values()) {
16308                    pw.print("    "); pw.println(perm);
16309                    if (dumpAll) {
16310                        perm.dump(pw, "      ");
16311                    }
16312                }
16313            }
16314        }
16315
16316        if (!printedAnything) {
16317            pw.println("  (nothing)");
16318        }
16319    }
16320
16321    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16322            int opti, boolean dumpAll, String dumpPackage) {
16323        boolean printed = false;
16324
16325        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16326
16327        if (mIntentSenderRecords.size() > 0) {
16328            // Organize these by package name, so they are easier to read.
16329            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16330            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16331            final Iterator<WeakReference<PendingIntentRecord>> it
16332                    = mIntentSenderRecords.values().iterator();
16333            while (it.hasNext()) {
16334                WeakReference<PendingIntentRecord> ref = it.next();
16335                PendingIntentRecord rec = ref != null ? ref.get() : null;
16336                if (rec == null) {
16337                    weakRefs.add(ref);
16338                    continue;
16339                }
16340                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16341                    continue;
16342                }
16343                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16344                if (list == null) {
16345                    list = new ArrayList<>();
16346                    byPackage.put(rec.key.packageName, list);
16347                }
16348                list.add(rec);
16349            }
16350            for (int i = 0; i < byPackage.size(); i++) {
16351                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16352                printed = true;
16353                pw.print("  * "); pw.print(byPackage.keyAt(i));
16354                pw.print(": "); pw.print(intents.size()); pw.println(" items");
16355                for (int j = 0; j < intents.size(); j++) {
16356                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16357                    if (dumpAll) {
16358                        intents.get(j).dump(pw, "      ");
16359                    }
16360                }
16361            }
16362            if (weakRefs.size() > 0) {
16363                printed = true;
16364                pw.println("  * WEAK REFS:");
16365                for (int i = 0; i < weakRefs.size(); i++) {
16366                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16367                }
16368            }
16369        }
16370
16371        if (!printed) {
16372            pw.println("  (nothing)");
16373        }
16374    }
16375
16376    private static final int dumpProcessList(PrintWriter pw,
16377            ActivityManagerService service, List list,
16378            String prefix, String normalLabel, String persistentLabel,
16379            String dumpPackage) {
16380        int numPers = 0;
16381        final int N = list.size()-1;
16382        for (int i=N; i>=0; i--) {
16383            ProcessRecord r = (ProcessRecord)list.get(i);
16384            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16385                continue;
16386            }
16387            pw.println(String.format("%s%s #%2d: %s",
16388                    prefix, (r.persistent ? persistentLabel : normalLabel),
16389                    i, r.toString()));
16390            if (r.persistent) {
16391                numPers++;
16392            }
16393        }
16394        return numPers;
16395    }
16396
16397    private static final boolean dumpProcessOomList(PrintWriter pw,
16398            ActivityManagerService service, List<ProcessRecord> origList,
16399            String prefix, String normalLabel, String persistentLabel,
16400            boolean inclDetails, String dumpPackage) {
16401
16402        ArrayList<Pair<ProcessRecord, Integer>> list
16403                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16404        for (int i=0; i<origList.size(); i++) {
16405            ProcessRecord r = origList.get(i);
16406            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16407                continue;
16408            }
16409            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16410        }
16411
16412        if (list.size() <= 0) {
16413            return false;
16414        }
16415
16416        Comparator<Pair<ProcessRecord, Integer>> comparator
16417                = new Comparator<Pair<ProcessRecord, Integer>>() {
16418            @Override
16419            public int compare(Pair<ProcessRecord, Integer> object1,
16420                    Pair<ProcessRecord, Integer> object2) {
16421                if (object1.first.setAdj != object2.first.setAdj) {
16422                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16423                }
16424                if (object1.first.setProcState != object2.first.setProcState) {
16425                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16426                }
16427                if (object1.second.intValue() != object2.second.intValue()) {
16428                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16429                }
16430                return 0;
16431            }
16432        };
16433
16434        Collections.sort(list, comparator);
16435
16436        final long curRealtime = SystemClock.elapsedRealtime();
16437        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16438        final long curUptime = SystemClock.uptimeMillis();
16439        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16440
16441        for (int i=list.size()-1; i>=0; i--) {
16442            ProcessRecord r = list.get(i).first;
16443            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16444            char schedGroup;
16445            switch (r.setSchedGroup) {
16446                case ProcessList.SCHED_GROUP_BACKGROUND:
16447                    schedGroup = 'B';
16448                    break;
16449                case ProcessList.SCHED_GROUP_DEFAULT:
16450                    schedGroup = 'F';
16451                    break;
16452                case ProcessList.SCHED_GROUP_TOP_APP:
16453                    schedGroup = 'T';
16454                    break;
16455                default:
16456                    schedGroup = '?';
16457                    break;
16458            }
16459            char foreground;
16460            if (r.foregroundActivities) {
16461                foreground = 'A';
16462            } else if (r.foregroundServices) {
16463                foreground = 'S';
16464            } else {
16465                foreground = ' ';
16466            }
16467            String procState = ProcessList.makeProcStateString(r.curProcState);
16468            pw.print(prefix);
16469            pw.print(r.persistent ? persistentLabel : normalLabel);
16470            pw.print(" #");
16471            int num = (origList.size()-1)-list.get(i).second;
16472            if (num < 10) pw.print(' ');
16473            pw.print(num);
16474            pw.print(": ");
16475            pw.print(oomAdj);
16476            pw.print(' ');
16477            pw.print(schedGroup);
16478            pw.print('/');
16479            pw.print(foreground);
16480            pw.print('/');
16481            pw.print(procState);
16482            pw.print(" trm:");
16483            if (r.trimMemoryLevel < 10) pw.print(' ');
16484            pw.print(r.trimMemoryLevel);
16485            pw.print(' ');
16486            pw.print(r.toShortString());
16487            pw.print(" (");
16488            pw.print(r.adjType);
16489            pw.println(')');
16490            if (r.adjSource != null || r.adjTarget != null) {
16491                pw.print(prefix);
16492                pw.print("    ");
16493                if (r.adjTarget instanceof ComponentName) {
16494                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16495                } else if (r.adjTarget != null) {
16496                    pw.print(r.adjTarget.toString());
16497                } else {
16498                    pw.print("{null}");
16499                }
16500                pw.print("<=");
16501                if (r.adjSource instanceof ProcessRecord) {
16502                    pw.print("Proc{");
16503                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16504                    pw.println("}");
16505                } else if (r.adjSource != null) {
16506                    pw.println(r.adjSource.toString());
16507                } else {
16508                    pw.println("{null}");
16509                }
16510            }
16511            if (inclDetails) {
16512                pw.print(prefix);
16513                pw.print("    ");
16514                pw.print("oom: max="); pw.print(r.maxAdj);
16515                pw.print(" curRaw="); pw.print(r.curRawAdj);
16516                pw.print(" setRaw="); pw.print(r.setRawAdj);
16517                pw.print(" cur="); pw.print(r.curAdj);
16518                pw.print(" set="); pw.println(r.setAdj);
16519                pw.print(prefix);
16520                pw.print("    ");
16521                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16522                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16523                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16524                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16525                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16526                pw.println();
16527                pw.print(prefix);
16528                pw.print("    ");
16529                pw.print("cached="); pw.print(r.cached);
16530                pw.print(" empty="); pw.print(r.empty);
16531                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16532
16533                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16534                    if (r.lastWakeTime != 0) {
16535                        long wtime;
16536                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16537                        synchronized (stats) {
16538                            wtime = stats.getProcessWakeTime(r.info.uid,
16539                                    r.pid, curRealtime);
16540                        }
16541                        long timeUsed = wtime - r.lastWakeTime;
16542                        pw.print(prefix);
16543                        pw.print("    ");
16544                        pw.print("keep awake over ");
16545                        TimeUtils.formatDuration(realtimeSince, pw);
16546                        pw.print(" used ");
16547                        TimeUtils.formatDuration(timeUsed, pw);
16548                        pw.print(" (");
16549                        pw.print((timeUsed*100)/realtimeSince);
16550                        pw.println("%)");
16551                    }
16552                    if (r.lastCpuTime != 0) {
16553                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16554                        pw.print(prefix);
16555                        pw.print("    ");
16556                        pw.print("run cpu over ");
16557                        TimeUtils.formatDuration(uptimeSince, pw);
16558                        pw.print(" used ");
16559                        TimeUtils.formatDuration(timeUsed, pw);
16560                        pw.print(" (");
16561                        pw.print((timeUsed*100)/uptimeSince);
16562                        pw.println("%)");
16563                    }
16564                }
16565            }
16566        }
16567        return true;
16568    }
16569
16570    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16571            String[] args) {
16572        ArrayList<ProcessRecord> procs;
16573        synchronized (this) {
16574            if (args != null && args.length > start
16575                    && args[start].charAt(0) != '-') {
16576                procs = new ArrayList<ProcessRecord>();
16577                int pid = -1;
16578                try {
16579                    pid = Integer.parseInt(args[start]);
16580                } catch (NumberFormatException e) {
16581                }
16582                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16583                    ProcessRecord proc = mLruProcesses.get(i);
16584                    if (proc.pid == pid) {
16585                        procs.add(proc);
16586                    } else if (allPkgs && proc.pkgList != null
16587                            && proc.pkgList.containsKey(args[start])) {
16588                        procs.add(proc);
16589                    } else if (proc.processName.equals(args[start])) {
16590                        procs.add(proc);
16591                    }
16592                }
16593                if (procs.size() <= 0) {
16594                    return null;
16595                }
16596            } else {
16597                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16598            }
16599        }
16600        return procs;
16601    }
16602
16603    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16604            PrintWriter pw, String[] args) {
16605        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16606        if (procs == null) {
16607            pw.println("No process found for: " + args[0]);
16608            return;
16609        }
16610
16611        long uptime = SystemClock.uptimeMillis();
16612        long realtime = SystemClock.elapsedRealtime();
16613        pw.println("Applications Graphics Acceleration Info:");
16614        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16615
16616        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16617            ProcessRecord r = procs.get(i);
16618            if (r.thread != null) {
16619                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16620                pw.flush();
16621                try {
16622                    TransferPipe tp = new TransferPipe();
16623                    try {
16624                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16625                        tp.go(fd);
16626                    } finally {
16627                        tp.kill();
16628                    }
16629                } catch (IOException e) {
16630                    pw.println("Failure while dumping the app: " + r);
16631                    pw.flush();
16632                } catch (RemoteException e) {
16633                    pw.println("Got a RemoteException while dumping the app " + r);
16634                    pw.flush();
16635                }
16636            }
16637        }
16638    }
16639
16640    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16641        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16642        if (procs == null) {
16643            pw.println("No process found for: " + args[0]);
16644            return;
16645        }
16646
16647        pw.println("Applications Database Info:");
16648
16649        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16650            ProcessRecord r = procs.get(i);
16651            if (r.thread != null) {
16652                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16653                pw.flush();
16654                try {
16655                    TransferPipe tp = new TransferPipe();
16656                    try {
16657                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16658                        tp.go(fd);
16659                    } finally {
16660                        tp.kill();
16661                    }
16662                } catch (IOException e) {
16663                    pw.println("Failure while dumping the app: " + r);
16664                    pw.flush();
16665                } catch (RemoteException e) {
16666                    pw.println("Got a RemoteException while dumping the app " + r);
16667                    pw.flush();
16668                }
16669            }
16670        }
16671    }
16672
16673    final static class MemItem {
16674        final boolean isProc;
16675        final String label;
16676        final String shortLabel;
16677        final long pss;
16678        final long swapPss;
16679        final int id;
16680        final boolean hasActivities;
16681        ArrayList<MemItem> subitems;
16682
16683        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16684                boolean _hasActivities) {
16685            isProc = true;
16686            label = _label;
16687            shortLabel = _shortLabel;
16688            pss = _pss;
16689            swapPss = _swapPss;
16690            id = _id;
16691            hasActivities = _hasActivities;
16692        }
16693
16694        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16695            isProc = false;
16696            label = _label;
16697            shortLabel = _shortLabel;
16698            pss = _pss;
16699            swapPss = _swapPss;
16700            id = _id;
16701            hasActivities = false;
16702        }
16703    }
16704
16705    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16706            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16707        if (sort && !isCompact) {
16708            Collections.sort(items, new Comparator<MemItem>() {
16709                @Override
16710                public int compare(MemItem lhs, MemItem rhs) {
16711                    if (lhs.pss < rhs.pss) {
16712                        return 1;
16713                    } else if (lhs.pss > rhs.pss) {
16714                        return -1;
16715                    }
16716                    return 0;
16717                }
16718            });
16719        }
16720
16721        for (int i=0; i<items.size(); i++) {
16722            MemItem mi = items.get(i);
16723            if (!isCompact) {
16724                if (dumpSwapPss) {
16725                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16726                            mi.label, stringifyKBSize(mi.swapPss));
16727                } else {
16728                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16729                }
16730            } else if (mi.isProc) {
16731                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16732                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16733                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16734                pw.println(mi.hasActivities ? ",a" : ",e");
16735            } else {
16736                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16737                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16738            }
16739            if (mi.subitems != null) {
16740                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16741                        true, isCompact, dumpSwapPss);
16742            }
16743        }
16744    }
16745
16746    // These are in KB.
16747    static final long[] DUMP_MEM_BUCKETS = new long[] {
16748        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16749        120*1024, 160*1024, 200*1024,
16750        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16751        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16752    };
16753
16754    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16755            boolean stackLike) {
16756        int start = label.lastIndexOf('.');
16757        if (start >= 0) start++;
16758        else start = 0;
16759        int end = label.length();
16760        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16761            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16762                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16763                out.append(bucket);
16764                out.append(stackLike ? "MB." : "MB ");
16765                out.append(label, start, end);
16766                return;
16767            }
16768        }
16769        out.append(memKB/1024);
16770        out.append(stackLike ? "MB." : "MB ");
16771        out.append(label, start, end);
16772    }
16773
16774    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16775            ProcessList.NATIVE_ADJ,
16776            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16777            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16778            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16779            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16780            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16781            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16782    };
16783    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16784            "Native",
16785            "System", "Persistent", "Persistent Service", "Foreground",
16786            "Visible", "Perceptible",
16787            "Heavy Weight", "Backup",
16788            "A Services", "Home",
16789            "Previous", "B Services", "Cached"
16790    };
16791    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16792            "native",
16793            "sys", "pers", "persvc", "fore",
16794            "vis", "percept",
16795            "heavy", "backup",
16796            "servicea", "home",
16797            "prev", "serviceb", "cached"
16798    };
16799
16800    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16801            long realtime, boolean isCheckinRequest, boolean isCompact) {
16802        if (isCompact) {
16803            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16804        }
16805        if (isCheckinRequest || isCompact) {
16806            // short checkin version
16807            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16808        } else {
16809            pw.println("Applications Memory Usage (in Kilobytes):");
16810            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16811        }
16812    }
16813
16814    private static final int KSM_SHARED = 0;
16815    private static final int KSM_SHARING = 1;
16816    private static final int KSM_UNSHARED = 2;
16817    private static final int KSM_VOLATILE = 3;
16818
16819    private final long[] getKsmInfo() {
16820        long[] longOut = new long[4];
16821        final int[] SINGLE_LONG_FORMAT = new int[] {
16822            PROC_SPACE_TERM| PROC_OUT_LONG
16823        };
16824        long[] longTmp = new long[1];
16825        readProcFile("/sys/kernel/mm/ksm/pages_shared",
16826                SINGLE_LONG_FORMAT, null, longTmp, null);
16827        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16828        longTmp[0] = 0;
16829        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16830                SINGLE_LONG_FORMAT, null, longTmp, null);
16831        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16832        longTmp[0] = 0;
16833        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16834                SINGLE_LONG_FORMAT, null, longTmp, null);
16835        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16836        longTmp[0] = 0;
16837        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16838                SINGLE_LONG_FORMAT, null, longTmp, null);
16839        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16840        return longOut;
16841    }
16842
16843    private static String stringifySize(long size, int order) {
16844        Locale locale = Locale.US;
16845        switch (order) {
16846            case 1:
16847                return String.format(locale, "%,13d", size);
16848            case 1024:
16849                return String.format(locale, "%,9dK", size / 1024);
16850            case 1024 * 1024:
16851                return String.format(locale, "%,5dM", size / 1024 / 1024);
16852            case 1024 * 1024 * 1024:
16853                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16854            default:
16855                throw new IllegalArgumentException("Invalid size order");
16856        }
16857    }
16858
16859    private static String stringifyKBSize(long size) {
16860        return stringifySize(size * 1024, 1024);
16861    }
16862
16863    // Update this version number in case you change the 'compact' format
16864    private static final int MEMINFO_COMPACT_VERSION = 1;
16865
16866    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16867            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16868        boolean dumpDetails = false;
16869        boolean dumpFullDetails = false;
16870        boolean dumpDalvik = false;
16871        boolean dumpSummaryOnly = false;
16872        boolean dumpUnreachable = false;
16873        boolean oomOnly = false;
16874        boolean isCompact = false;
16875        boolean localOnly = false;
16876        boolean packages = false;
16877        boolean isCheckinRequest = false;
16878        boolean dumpSwapPss = false;
16879
16880        int opti = 0;
16881        while (opti < args.length) {
16882            String opt = args[opti];
16883            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16884                break;
16885            }
16886            opti++;
16887            if ("-a".equals(opt)) {
16888                dumpDetails = true;
16889                dumpFullDetails = true;
16890                dumpDalvik = true;
16891                dumpSwapPss = true;
16892            } else if ("-d".equals(opt)) {
16893                dumpDalvik = true;
16894            } else if ("-c".equals(opt)) {
16895                isCompact = true;
16896            } else if ("-s".equals(opt)) {
16897                dumpDetails = true;
16898                dumpSummaryOnly = true;
16899            } else if ("-S".equals(opt)) {
16900                dumpSwapPss = true;
16901            } else if ("--unreachable".equals(opt)) {
16902                dumpUnreachable = true;
16903            } else if ("--oom".equals(opt)) {
16904                oomOnly = true;
16905            } else if ("--local".equals(opt)) {
16906                localOnly = true;
16907            } else if ("--package".equals(opt)) {
16908                packages = true;
16909            } else if ("--checkin".equals(opt)) {
16910                isCheckinRequest = true;
16911
16912            } else if ("-h".equals(opt)) {
16913                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16914                pw.println("  -a: include all available information for each process.");
16915                pw.println("  -d: include dalvik details.");
16916                pw.println("  -c: dump in a compact machine-parseable representation.");
16917                pw.println("  -s: dump only summary of application memory usage.");
16918                pw.println("  -S: dump also SwapPss.");
16919                pw.println("  --oom: only show processes organized by oom adj.");
16920                pw.println("  --local: only collect details locally, don't call process.");
16921                pw.println("  --package: interpret process arg as package, dumping all");
16922                pw.println("             processes that have loaded that package.");
16923                pw.println("  --checkin: dump data for a checkin");
16924                pw.println("If [process] is specified it can be the name or ");
16925                pw.println("pid of a specific process to dump.");
16926                return;
16927            } else {
16928                pw.println("Unknown argument: " + opt + "; use -h for help");
16929            }
16930        }
16931
16932        long uptime = SystemClock.uptimeMillis();
16933        long realtime = SystemClock.elapsedRealtime();
16934        final long[] tmpLong = new long[1];
16935
16936        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16937        if (procs == null) {
16938            // No Java processes.  Maybe they want to print a native process.
16939            if (args != null && args.length > opti
16940                    && args[opti].charAt(0) != '-') {
16941                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16942                        = new ArrayList<ProcessCpuTracker.Stats>();
16943                updateCpuStatsNow();
16944                int findPid = -1;
16945                try {
16946                    findPid = Integer.parseInt(args[opti]);
16947                } catch (NumberFormatException e) {
16948                }
16949                synchronized (mProcessCpuTracker) {
16950                    final int N = mProcessCpuTracker.countStats();
16951                    for (int i=0; i<N; i++) {
16952                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16953                        if (st.pid == findPid || (st.baseName != null
16954                                && st.baseName.equals(args[opti]))) {
16955                            nativeProcs.add(st);
16956                        }
16957                    }
16958                }
16959                if (nativeProcs.size() > 0) {
16960                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16961                            isCompact);
16962                    Debug.MemoryInfo mi = null;
16963                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16964                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16965                        final int pid = r.pid;
16966                        if (!isCheckinRequest && dumpDetails) {
16967                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16968                        }
16969                        if (mi == null) {
16970                            mi = new Debug.MemoryInfo();
16971                        }
16972                        if (dumpDetails || (!brief && !oomOnly)) {
16973                            Debug.getMemoryInfo(pid, mi);
16974                        } else {
16975                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16976                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16977                        }
16978                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16979                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16980                        if (isCheckinRequest) {
16981                            pw.println();
16982                        }
16983                    }
16984                    return;
16985                }
16986            }
16987            pw.println("No process found for: " + args[opti]);
16988            return;
16989        }
16990
16991        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16992            dumpDetails = true;
16993        }
16994
16995        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16996
16997        String[] innerArgs = new String[args.length-opti];
16998        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16999
17000        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17001        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17002        long nativePss = 0;
17003        long nativeSwapPss = 0;
17004        long dalvikPss = 0;
17005        long dalvikSwapPss = 0;
17006        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17007                EmptyArray.LONG;
17008        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17009                EmptyArray.LONG;
17010        long otherPss = 0;
17011        long otherSwapPss = 0;
17012        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17013        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17014
17015        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17016        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17017        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17018                new ArrayList[DUMP_MEM_OOM_LABEL.length];
17019
17020        long totalPss = 0;
17021        long totalSwapPss = 0;
17022        long cachedPss = 0;
17023        long cachedSwapPss = 0;
17024        boolean hasSwapPss = false;
17025
17026        Debug.MemoryInfo mi = null;
17027        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17028            final ProcessRecord r = procs.get(i);
17029            final IApplicationThread thread;
17030            final int pid;
17031            final int oomAdj;
17032            final boolean hasActivities;
17033            synchronized (this) {
17034                thread = r.thread;
17035                pid = r.pid;
17036                oomAdj = r.getSetAdjWithServices();
17037                hasActivities = r.activities.size() > 0;
17038            }
17039            if (thread != null) {
17040                if (!isCheckinRequest && dumpDetails) {
17041                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17042                }
17043                if (mi == null) {
17044                    mi = new Debug.MemoryInfo();
17045                }
17046                if (dumpDetails || (!brief && !oomOnly)) {
17047                    Debug.getMemoryInfo(pid, mi);
17048                    hasSwapPss = mi.hasSwappedOutPss;
17049                } else {
17050                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17051                    mi.dalvikPrivateDirty = (int)tmpLong[0];
17052                }
17053                if (dumpDetails) {
17054                    if (localOnly) {
17055                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17056                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17057                        if (isCheckinRequest) {
17058                            pw.println();
17059                        }
17060                    } else {
17061                        pw.flush();
17062                        try {
17063                            TransferPipe tp = new TransferPipe();
17064                            try {
17065                                thread.dumpMemInfo(tp.getWriteFd(),
17066                                        mi, isCheckinRequest, dumpFullDetails,
17067                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17068                                tp.go(fd);
17069                            } finally {
17070                                tp.kill();
17071                            }
17072                        } catch (IOException e) {
17073                            if (!isCheckinRequest) {
17074                                pw.println("Got IoException!");
17075                                pw.flush();
17076                            }
17077                        } catch (RemoteException e) {
17078                            if (!isCheckinRequest) {
17079                                pw.println("Got RemoteException!");
17080                                pw.flush();
17081                            }
17082                        }
17083                    }
17084                }
17085
17086                final long myTotalPss = mi.getTotalPss();
17087                final long myTotalUss = mi.getTotalUss();
17088                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17089
17090                synchronized (this) {
17091                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17092                        // Record this for posterity if the process has been stable.
17093                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17094                    }
17095                }
17096
17097                if (!isCheckinRequest && mi != null) {
17098                    totalPss += myTotalPss;
17099                    totalSwapPss += myTotalSwapPss;
17100                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17101                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17102                            myTotalSwapPss, pid, hasActivities);
17103                    procMems.add(pssItem);
17104                    procMemsMap.put(pid, 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
17126                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17127                        cachedPss += myTotalPss;
17128                        cachedSwapPss += myTotalSwapPss;
17129                    }
17130
17131                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17132                        if (oomIndex == (oomPss.length - 1)
17133                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17134                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17135                            oomPss[oomIndex] += myTotalPss;
17136                            oomSwapPss[oomIndex] += myTotalSwapPss;
17137                            if (oomProcs[oomIndex] == null) {
17138                                oomProcs[oomIndex] = new ArrayList<MemItem>();
17139                            }
17140                            oomProcs[oomIndex].add(pssItem);
17141                            break;
17142                        }
17143                    }
17144                }
17145            }
17146        }
17147
17148        long nativeProcTotalPss = 0;
17149
17150        if (!isCheckinRequest && procs.size() > 1 && !packages) {
17151            // If we are showing aggregations, also look for native processes to
17152            // include so that our aggregations are more accurate.
17153            updateCpuStatsNow();
17154            mi = null;
17155            synchronized (mProcessCpuTracker) {
17156                final int N = mProcessCpuTracker.countStats();
17157                for (int i=0; i<N; i++) {
17158                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17159                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17160                        if (mi == null) {
17161                            mi = new Debug.MemoryInfo();
17162                        }
17163                        if (!brief && !oomOnly) {
17164                            Debug.getMemoryInfo(st.pid, mi);
17165                        } else {
17166                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17167                            mi.nativePrivateDirty = (int)tmpLong[0];
17168                        }
17169
17170                        final long myTotalPss = mi.getTotalPss();
17171                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17172                        totalPss += myTotalPss;
17173                        nativeProcTotalPss += myTotalPss;
17174
17175                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17176                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17177                        procMems.add(pssItem);
17178
17179                        nativePss += mi.nativePss;
17180                        nativeSwapPss += mi.nativeSwappedOutPss;
17181                        dalvikPss += mi.dalvikPss;
17182                        dalvikSwapPss += mi.dalvikSwappedOutPss;
17183                        for (int j=0; j<dalvikSubitemPss.length; j++) {
17184                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17185                            dalvikSubitemSwapPss[j] +=
17186                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17187                        }
17188                        otherPss += mi.otherPss;
17189                        otherSwapPss += mi.otherSwappedOutPss;
17190                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17191                            long mem = mi.getOtherPss(j);
17192                            miscPss[j] += mem;
17193                            otherPss -= mem;
17194                            mem = mi.getOtherSwappedOutPss(j);
17195                            miscSwapPss[j] += mem;
17196                            otherSwapPss -= mem;
17197                        }
17198                        oomPss[0] += myTotalPss;
17199                        oomSwapPss[0] += myTotalSwapPss;
17200                        if (oomProcs[0] == null) {
17201                            oomProcs[0] = new ArrayList<MemItem>();
17202                        }
17203                        oomProcs[0].add(pssItem);
17204                    }
17205                }
17206            }
17207
17208            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17209
17210            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17211            final MemItem dalvikItem =
17212                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17213            if (dalvikSubitemPss.length > 0) {
17214                dalvikItem.subitems = new ArrayList<MemItem>();
17215                for (int j=0; j<dalvikSubitemPss.length; j++) {
17216                    final String name = Debug.MemoryInfo.getOtherLabel(
17217                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
17218                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17219                                    dalvikSubitemSwapPss[j], j));
17220                }
17221            }
17222            catMems.add(dalvikItem);
17223            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17224            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17225                String label = Debug.MemoryInfo.getOtherLabel(j);
17226                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17227            }
17228
17229            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17230            for (int j=0; j<oomPss.length; j++) {
17231                if (oomPss[j] != 0) {
17232                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17233                            : DUMP_MEM_OOM_LABEL[j];
17234                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17235                            DUMP_MEM_OOM_ADJ[j]);
17236                    item.subitems = oomProcs[j];
17237                    oomMems.add(item);
17238                }
17239            }
17240
17241            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17242            if (!brief && !oomOnly && !isCompact) {
17243                pw.println();
17244                pw.println("Total PSS by process:");
17245                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17246                pw.println();
17247            }
17248            if (!isCompact) {
17249                pw.println("Total PSS by OOM adjustment:");
17250            }
17251            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17252            if (!brief && !oomOnly) {
17253                PrintWriter out = categoryPw != null ? categoryPw : pw;
17254                if (!isCompact) {
17255                    out.println();
17256                    out.println("Total PSS by category:");
17257                }
17258                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17259            }
17260            if (!isCompact) {
17261                pw.println();
17262            }
17263            MemInfoReader memInfo = new MemInfoReader();
17264            memInfo.readMemInfo();
17265            if (nativeProcTotalPss > 0) {
17266                synchronized (this) {
17267                    final long cachedKb = memInfo.getCachedSizeKb();
17268                    final long freeKb = memInfo.getFreeSizeKb();
17269                    final long zramKb = memInfo.getZramTotalSizeKb();
17270                    final long kernelKb = memInfo.getKernelUsedSizeKb();
17271                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17272                            kernelKb*1024, nativeProcTotalPss*1024);
17273                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17274                            nativeProcTotalPss);
17275                }
17276            }
17277            if (!brief) {
17278                if (!isCompact) {
17279                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17280                    pw.print(" (status ");
17281                    switch (mLastMemoryLevel) {
17282                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17283                            pw.println("normal)");
17284                            break;
17285                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17286                            pw.println("moderate)");
17287                            break;
17288                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
17289                            pw.println("low)");
17290                            break;
17291                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17292                            pw.println("critical)");
17293                            break;
17294                        default:
17295                            pw.print(mLastMemoryLevel);
17296                            pw.println(")");
17297                            break;
17298                    }
17299                    pw.print(" Free RAM: ");
17300                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17301                            + memInfo.getFreeSizeKb()));
17302                    pw.print(" (");
17303                    pw.print(stringifyKBSize(cachedPss));
17304                    pw.print(" cached pss + ");
17305                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17306                    pw.print(" cached kernel + ");
17307                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17308                    pw.println(" free)");
17309                } else {
17310                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17311                    pw.print(cachedPss + memInfo.getCachedSizeKb()
17312                            + memInfo.getFreeSizeKb()); pw.print(",");
17313                    pw.println(totalPss - cachedPss);
17314                }
17315            }
17316            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17317                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17318                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17319            if (!isCompact) {
17320                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17321                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17322                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17323                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17324                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17325            } else {
17326                pw.print("lostram,"); pw.println(lostRAM);
17327            }
17328            if (!brief) {
17329                if (memInfo.getZramTotalSizeKb() != 0) {
17330                    if (!isCompact) {
17331                        pw.print("     ZRAM: ");
17332                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17333                                pw.print(" physical used for ");
17334                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17335                                        - memInfo.getSwapFreeSizeKb()));
17336                                pw.print(" in swap (");
17337                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17338                                pw.println(" total swap)");
17339                    } else {
17340                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17341                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17342                                pw.println(memInfo.getSwapFreeSizeKb());
17343                    }
17344                }
17345                final long[] ksm = getKsmInfo();
17346                if (!isCompact) {
17347                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17348                            || ksm[KSM_VOLATILE] != 0) {
17349                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17350                                pw.print(" saved from shared ");
17351                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17352                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17353                                pw.print(" unshared; ");
17354                                pw.print(stringifyKBSize(
17355                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
17356                    }
17357                    pw.print("   Tuning: ");
17358                    pw.print(ActivityManager.staticGetMemoryClass());
17359                    pw.print(" (large ");
17360                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17361                    pw.print("), oom ");
17362                    pw.print(stringifySize(
17363                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17364                    pw.print(", restore limit ");
17365                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17366                    if (ActivityManager.isLowRamDeviceStatic()) {
17367                        pw.print(" (low-ram)");
17368                    }
17369                    if (ActivityManager.isHighEndGfx()) {
17370                        pw.print(" (high-end-gfx)");
17371                    }
17372                    pw.println();
17373                } else {
17374                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17375                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17376                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17377                    pw.print("tuning,");
17378                    pw.print(ActivityManager.staticGetMemoryClass());
17379                    pw.print(',');
17380                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17381                    pw.print(',');
17382                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17383                    if (ActivityManager.isLowRamDeviceStatic()) {
17384                        pw.print(",low-ram");
17385                    }
17386                    if (ActivityManager.isHighEndGfx()) {
17387                        pw.print(",high-end-gfx");
17388                    }
17389                    pw.println();
17390                }
17391            }
17392        }
17393    }
17394
17395    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17396            long memtrack, String name) {
17397        sb.append("  ");
17398        sb.append(ProcessList.makeOomAdjString(oomAdj));
17399        sb.append(' ');
17400        sb.append(ProcessList.makeProcStateString(procState));
17401        sb.append(' ');
17402        ProcessList.appendRamKb(sb, pss);
17403        sb.append(": ");
17404        sb.append(name);
17405        if (memtrack > 0) {
17406            sb.append(" (");
17407            sb.append(stringifyKBSize(memtrack));
17408            sb.append(" memtrack)");
17409        }
17410    }
17411
17412    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17413        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17414        sb.append(" (pid ");
17415        sb.append(mi.pid);
17416        sb.append(") ");
17417        sb.append(mi.adjType);
17418        sb.append('\n');
17419        if (mi.adjReason != null) {
17420            sb.append("                      ");
17421            sb.append(mi.adjReason);
17422            sb.append('\n');
17423        }
17424    }
17425
17426    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17427        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17428        for (int i=0, N=memInfos.size(); i<N; i++) {
17429            ProcessMemInfo mi = memInfos.get(i);
17430            infoMap.put(mi.pid, mi);
17431        }
17432        updateCpuStatsNow();
17433        long[] memtrackTmp = new long[1];
17434        final List<ProcessCpuTracker.Stats> stats;
17435        // Get a list of Stats that have vsize > 0
17436        synchronized (mProcessCpuTracker) {
17437            stats = mProcessCpuTracker.getStats((st) -> {
17438                return st.vsize > 0;
17439            });
17440        }
17441        final int statsCount = stats.size();
17442        for (int i = 0; i < statsCount; i++) {
17443            ProcessCpuTracker.Stats st = stats.get(i);
17444            long pss = Debug.getPss(st.pid, null, memtrackTmp);
17445            if (pss > 0) {
17446                if (infoMap.indexOfKey(st.pid) < 0) {
17447                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17448                            ProcessList.NATIVE_ADJ, -1, "native", null);
17449                    mi.pss = pss;
17450                    mi.memtrack = memtrackTmp[0];
17451                    memInfos.add(mi);
17452                }
17453            }
17454        }
17455
17456        long totalPss = 0;
17457        long totalMemtrack = 0;
17458        for (int i=0, N=memInfos.size(); i<N; i++) {
17459            ProcessMemInfo mi = memInfos.get(i);
17460            if (mi.pss == 0) {
17461                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17462                mi.memtrack = memtrackTmp[0];
17463            }
17464            totalPss += mi.pss;
17465            totalMemtrack += mi.memtrack;
17466        }
17467        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17468            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17469                if (lhs.oomAdj != rhs.oomAdj) {
17470                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17471                }
17472                if (lhs.pss != rhs.pss) {
17473                    return lhs.pss < rhs.pss ? 1 : -1;
17474                }
17475                return 0;
17476            }
17477        });
17478
17479        StringBuilder tag = new StringBuilder(128);
17480        StringBuilder stack = new StringBuilder(128);
17481        tag.append("Low on memory -- ");
17482        appendMemBucket(tag, totalPss, "total", false);
17483        appendMemBucket(stack, totalPss, "total", true);
17484
17485        StringBuilder fullNativeBuilder = new StringBuilder(1024);
17486        StringBuilder shortNativeBuilder = new StringBuilder(1024);
17487        StringBuilder fullJavaBuilder = new StringBuilder(1024);
17488
17489        boolean firstLine = true;
17490        int lastOomAdj = Integer.MIN_VALUE;
17491        long extraNativeRam = 0;
17492        long extraNativeMemtrack = 0;
17493        long cachedPss = 0;
17494        for (int i=0, N=memInfos.size(); i<N; i++) {
17495            ProcessMemInfo mi = memInfos.get(i);
17496
17497            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17498                cachedPss += mi.pss;
17499            }
17500
17501            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17502                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17503                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17504                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17505                if (lastOomAdj != mi.oomAdj) {
17506                    lastOomAdj = mi.oomAdj;
17507                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17508                        tag.append(" / ");
17509                    }
17510                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17511                        if (firstLine) {
17512                            stack.append(":");
17513                            firstLine = false;
17514                        }
17515                        stack.append("\n\t at ");
17516                    } else {
17517                        stack.append("$");
17518                    }
17519                } else {
17520                    tag.append(" ");
17521                    stack.append("$");
17522                }
17523                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17524                    appendMemBucket(tag, mi.pss, mi.name, false);
17525                }
17526                appendMemBucket(stack, mi.pss, mi.name, true);
17527                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17528                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17529                    stack.append("(");
17530                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17531                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17532                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17533                            stack.append(":");
17534                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17535                        }
17536                    }
17537                    stack.append(")");
17538                }
17539            }
17540
17541            appendMemInfo(fullNativeBuilder, mi);
17542            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17543                // The short form only has native processes that are >= 512K.
17544                if (mi.pss >= 512) {
17545                    appendMemInfo(shortNativeBuilder, mi);
17546                } else {
17547                    extraNativeRam += mi.pss;
17548                    extraNativeMemtrack += mi.memtrack;
17549                }
17550            } else {
17551                // Short form has all other details, but if we have collected RAM
17552                // from smaller native processes let's dump a summary of that.
17553                if (extraNativeRam > 0) {
17554                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17555                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17556                    shortNativeBuilder.append('\n');
17557                    extraNativeRam = 0;
17558                }
17559                appendMemInfo(fullJavaBuilder, mi);
17560            }
17561        }
17562
17563        fullJavaBuilder.append("           ");
17564        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17565        fullJavaBuilder.append(": TOTAL");
17566        if (totalMemtrack > 0) {
17567            fullJavaBuilder.append(" (");
17568            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17569            fullJavaBuilder.append(" memtrack)");
17570        } else {
17571        }
17572        fullJavaBuilder.append("\n");
17573
17574        MemInfoReader memInfo = new MemInfoReader();
17575        memInfo.readMemInfo();
17576        final long[] infos = memInfo.getRawInfo();
17577
17578        StringBuilder memInfoBuilder = new StringBuilder(1024);
17579        Debug.getMemInfo(infos);
17580        memInfoBuilder.append("  MemInfo: ");
17581        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17582        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17583        memInfoBuilder.append(stringifyKBSize(
17584                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17585        memInfoBuilder.append(stringifyKBSize(
17586                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17587        memInfoBuilder.append(stringifyKBSize(
17588                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17589        memInfoBuilder.append("           ");
17590        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17591        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17592        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17593        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17594        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17595            memInfoBuilder.append("  ZRAM: ");
17596            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17597            memInfoBuilder.append(" RAM, ");
17598            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17599            memInfoBuilder.append(" swap total, ");
17600            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17601            memInfoBuilder.append(" swap free\n");
17602        }
17603        final long[] ksm = getKsmInfo();
17604        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17605                || ksm[KSM_VOLATILE] != 0) {
17606            memInfoBuilder.append("  KSM: ");
17607            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17608            memInfoBuilder.append(" saved from shared ");
17609            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17610            memInfoBuilder.append("\n       ");
17611            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17612            memInfoBuilder.append(" unshared; ");
17613            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17614            memInfoBuilder.append(" volatile\n");
17615        }
17616        memInfoBuilder.append("  Free RAM: ");
17617        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17618                + memInfo.getFreeSizeKb()));
17619        memInfoBuilder.append("\n");
17620        memInfoBuilder.append("  Used RAM: ");
17621        memInfoBuilder.append(stringifyKBSize(
17622                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17623        memInfoBuilder.append("\n");
17624        memInfoBuilder.append("  Lost RAM: ");
17625        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17626                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17627                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17628        memInfoBuilder.append("\n");
17629        Slog.i(TAG, "Low on memory:");
17630        Slog.i(TAG, shortNativeBuilder.toString());
17631        Slog.i(TAG, fullJavaBuilder.toString());
17632        Slog.i(TAG, memInfoBuilder.toString());
17633
17634        StringBuilder dropBuilder = new StringBuilder(1024);
17635        /*
17636        StringWriter oomSw = new StringWriter();
17637        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17638        StringWriter catSw = new StringWriter();
17639        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17640        String[] emptyArgs = new String[] { };
17641        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17642        oomPw.flush();
17643        String oomString = oomSw.toString();
17644        */
17645        dropBuilder.append("Low on memory:");
17646        dropBuilder.append(stack);
17647        dropBuilder.append('\n');
17648        dropBuilder.append(fullNativeBuilder);
17649        dropBuilder.append(fullJavaBuilder);
17650        dropBuilder.append('\n');
17651        dropBuilder.append(memInfoBuilder);
17652        dropBuilder.append('\n');
17653        /*
17654        dropBuilder.append(oomString);
17655        dropBuilder.append('\n');
17656        */
17657        StringWriter catSw = new StringWriter();
17658        synchronized (ActivityManagerService.this) {
17659            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17660            String[] emptyArgs = new String[] { };
17661            catPw.println();
17662            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17663            catPw.println();
17664            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17665                    false, null).dumpLocked();
17666            catPw.println();
17667            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17668            catPw.flush();
17669        }
17670        dropBuilder.append(catSw.toString());
17671        addErrorToDropBox("lowmem", null, "system_server", null,
17672                null, tag.toString(), dropBuilder.toString(), null, null);
17673        //Slog.i(TAG, "Sent to dropbox:");
17674        //Slog.i(TAG, dropBuilder.toString());
17675        synchronized (ActivityManagerService.this) {
17676            long now = SystemClock.uptimeMillis();
17677            if (mLastMemUsageReportTime < now) {
17678                mLastMemUsageReportTime = now;
17679            }
17680        }
17681    }
17682
17683    /**
17684     * Searches array of arguments for the specified string
17685     * @param args array of argument strings
17686     * @param value value to search for
17687     * @return true if the value is contained in the array
17688     */
17689    private static boolean scanArgs(String[] args, String value) {
17690        if (args != null) {
17691            for (String arg : args) {
17692                if (value.equals(arg)) {
17693                    return true;
17694                }
17695            }
17696        }
17697        return false;
17698    }
17699
17700    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17701            ContentProviderRecord cpr, boolean always) {
17702        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17703
17704        if (!inLaunching || always) {
17705            synchronized (cpr) {
17706                cpr.launchingApp = null;
17707                cpr.notifyAll();
17708            }
17709            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17710            String names[] = cpr.info.authority.split(";");
17711            for (int j = 0; j < names.length; j++) {
17712                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17713            }
17714        }
17715
17716        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17717            ContentProviderConnection conn = cpr.connections.get(i);
17718            if (conn.waiting) {
17719                // If this connection is waiting for the provider, then we don't
17720                // need to mess with its process unless we are always removing
17721                // or for some reason the provider is not currently launching.
17722                if (inLaunching && !always) {
17723                    continue;
17724                }
17725            }
17726            ProcessRecord capp = conn.client;
17727            conn.dead = true;
17728            if (conn.stableCount > 0) {
17729                if (!capp.persistent && capp.thread != null
17730                        && capp.pid != 0
17731                        && capp.pid != MY_PID) {
17732                    capp.kill("depends on provider "
17733                            + cpr.name.flattenToShortString()
17734                            + " in dying proc " + (proc != null ? proc.processName : "??")
17735                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17736                }
17737            } else if (capp.thread != null && conn.provider.provider != null) {
17738                try {
17739                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17740                } catch (RemoteException e) {
17741                }
17742                // In the protocol here, we don't expect the client to correctly
17743                // clean up this connection, we'll just remove it.
17744                cpr.connections.remove(i);
17745                if (conn.client.conProviders.remove(conn)) {
17746                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17747                }
17748            }
17749        }
17750
17751        if (inLaunching && always) {
17752            mLaunchingProviders.remove(cpr);
17753        }
17754        return inLaunching;
17755    }
17756
17757    /**
17758     * Main code for cleaning up a process when it has gone away.  This is
17759     * called both as a result of the process dying, or directly when stopping
17760     * a process when running in single process mode.
17761     *
17762     * @return Returns true if the given process has been restarted, so the
17763     * app that was passed in must remain on the process lists.
17764     */
17765    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17766            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17767        if (index >= 0) {
17768            removeLruProcessLocked(app);
17769            ProcessList.remove(app.pid);
17770        }
17771
17772        mProcessesToGc.remove(app);
17773        mPendingPssProcesses.remove(app);
17774
17775        // Dismiss any open dialogs.
17776        if (app.crashDialog != null && !app.forceCrashReport) {
17777            app.crashDialog.dismiss();
17778            app.crashDialog = null;
17779        }
17780        if (app.anrDialog != null) {
17781            app.anrDialog.dismiss();
17782            app.anrDialog = null;
17783        }
17784        if (app.waitDialog != null) {
17785            app.waitDialog.dismiss();
17786            app.waitDialog = null;
17787        }
17788
17789        app.crashing = false;
17790        app.notResponding = false;
17791
17792        app.resetPackageList(mProcessStats);
17793        app.unlinkDeathRecipient();
17794        app.makeInactive(mProcessStats);
17795        app.waitingToKill = null;
17796        app.forcingToImportant = null;
17797        updateProcessForegroundLocked(app, false, false);
17798        app.foregroundActivities = false;
17799        app.hasShownUi = false;
17800        app.treatLikeActivity = false;
17801        app.hasAboveClient = false;
17802        app.hasClientActivities = false;
17803
17804        mServices.killServicesLocked(app, allowRestart);
17805
17806        boolean restart = false;
17807
17808        // Remove published content providers.
17809        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17810            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17811            final boolean always = app.bad || !allowRestart;
17812            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17813            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17814                // We left the provider in the launching list, need to
17815                // restart it.
17816                restart = true;
17817            }
17818
17819            cpr.provider = null;
17820            cpr.proc = null;
17821        }
17822        app.pubProviders.clear();
17823
17824        // Take care of any launching providers waiting for this process.
17825        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17826            restart = true;
17827        }
17828
17829        // Unregister from connected content providers.
17830        if (!app.conProviders.isEmpty()) {
17831            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17832                ContentProviderConnection conn = app.conProviders.get(i);
17833                conn.provider.connections.remove(conn);
17834                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17835                        conn.provider.name);
17836            }
17837            app.conProviders.clear();
17838        }
17839
17840        // At this point there may be remaining entries in mLaunchingProviders
17841        // where we were the only one waiting, so they are no longer of use.
17842        // Look for these and clean up if found.
17843        // XXX Commented out for now.  Trying to figure out a way to reproduce
17844        // the actual situation to identify what is actually going on.
17845        if (false) {
17846            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17847                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17848                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17849                    synchronized (cpr) {
17850                        cpr.launchingApp = null;
17851                        cpr.notifyAll();
17852                    }
17853                }
17854            }
17855        }
17856
17857        skipCurrentReceiverLocked(app);
17858
17859        // Unregister any receivers.
17860        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17861            removeReceiverLocked(app.receivers.valueAt(i));
17862        }
17863        app.receivers.clear();
17864
17865        // If the app is undergoing backup, tell the backup manager about it
17866        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17867            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17868                    + mBackupTarget.appInfo + " died during backup");
17869            mHandler.post(new Runnable() {
17870                @Override
17871                public void run(){
17872                    try {
17873                        IBackupManager bm = IBackupManager.Stub.asInterface(
17874                                ServiceManager.getService(Context.BACKUP_SERVICE));
17875                        bm.agentDisconnected(app.info.packageName);
17876                    } catch (RemoteException e) {
17877                        // can't happen; backup manager is local
17878                    }
17879                }
17880            });
17881        }
17882
17883        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17884            ProcessChangeItem item = mPendingProcessChanges.get(i);
17885            if (item.pid == app.pid) {
17886                mPendingProcessChanges.remove(i);
17887                mAvailProcessChanges.add(item);
17888            }
17889        }
17890        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17891                null).sendToTarget();
17892
17893        // If the caller is restarting this app, then leave it in its
17894        // current lists and let the caller take care of it.
17895        if (restarting) {
17896            return false;
17897        }
17898
17899        if (!app.persistent || app.isolated) {
17900            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17901                    "Removing non-persistent process during cleanup: " + app);
17902            if (!replacingPid) {
17903                removeProcessNameLocked(app.processName, app.uid, app);
17904            }
17905            if (mHeavyWeightProcess == app) {
17906                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17907                        mHeavyWeightProcess.userId, 0));
17908                mHeavyWeightProcess = null;
17909            }
17910        } else if (!app.removed) {
17911            // This app is persistent, so we need to keep its record around.
17912            // If it is not already on the pending app list, add it there
17913            // and start a new process for it.
17914            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17915                mPersistentStartingProcesses.add(app);
17916                restart = true;
17917            }
17918        }
17919        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17920                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17921        mProcessesOnHold.remove(app);
17922
17923        if (app == mHomeProcess) {
17924            mHomeProcess = null;
17925        }
17926        if (app == mPreviousProcess) {
17927            mPreviousProcess = null;
17928        }
17929
17930        if (restart && !app.isolated) {
17931            // We have components that still need to be running in the
17932            // process, so re-launch it.
17933            if (index < 0) {
17934                ProcessList.remove(app.pid);
17935            }
17936            addProcessNameLocked(app);
17937            startProcessLocked(app, "restart", app.processName);
17938            return true;
17939        } else if (app.pid > 0 && app.pid != MY_PID) {
17940            // Goodbye!
17941            boolean removed;
17942            synchronized (mPidsSelfLocked) {
17943                mPidsSelfLocked.remove(app.pid);
17944                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17945            }
17946            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17947            if (app.isolated) {
17948                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17949            }
17950            app.setPid(0);
17951        }
17952        return false;
17953    }
17954
17955    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17956        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17957            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17958            if (cpr.launchingApp == app) {
17959                return true;
17960            }
17961        }
17962        return false;
17963    }
17964
17965    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17966        // Look through the content providers we are waiting to have launched,
17967        // and if any run in this process then either schedule a restart of
17968        // the process or kill the client waiting for it if this process has
17969        // gone bad.
17970        boolean restart = false;
17971        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17972            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17973            if (cpr.launchingApp == app) {
17974                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17975                    restart = true;
17976                } else {
17977                    removeDyingProviderLocked(app, cpr, true);
17978                }
17979            }
17980        }
17981        return restart;
17982    }
17983
17984    // =========================================================
17985    // SERVICES
17986    // =========================================================
17987
17988    @Override
17989    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17990            int flags) {
17991        enforceNotIsolatedCaller("getServices");
17992
17993        final int callingUid = Binder.getCallingUid();
17994        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
17995            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
17996        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
17997            callingUid);
17998        synchronized (this) {
17999            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18000                allowed, canInteractAcrossUsers);
18001        }
18002    }
18003
18004    @Override
18005    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18006        enforceNotIsolatedCaller("getRunningServiceControlPanel");
18007        synchronized (this) {
18008            return mServices.getRunningServiceControlPanelLocked(name);
18009        }
18010    }
18011
18012    @Override
18013    public ComponentName startService(IApplicationThread caller, Intent service,
18014            String resolvedType, boolean requireForeground, String callingPackage, int userId)
18015            throws TransactionTooLargeException {
18016        enforceNotIsolatedCaller("startService");
18017        // Refuse possible leaked file descriptors
18018        if (service != null && service.hasFileDescriptors() == true) {
18019            throw new IllegalArgumentException("File descriptors passed in Intent");
18020        }
18021
18022        if (callingPackage == null) {
18023            throw new IllegalArgumentException("callingPackage cannot be null");
18024        }
18025
18026        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18027                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18028        synchronized(this) {
18029            final int callingPid = Binder.getCallingPid();
18030            final int callingUid = Binder.getCallingUid();
18031            final long origId = Binder.clearCallingIdentity();
18032            ComponentName res;
18033            try {
18034                res = mServices.startServiceLocked(caller, service,
18035                        resolvedType, callingPid, callingUid,
18036                        requireForeground, callingPackage, userId);
18037            } finally {
18038                Binder.restoreCallingIdentity(origId);
18039            }
18040            return res;
18041        }
18042    }
18043
18044    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18045            boolean fgRequired, String callingPackage, int userId)
18046            throws TransactionTooLargeException {
18047        synchronized(this) {
18048            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18049                    "startServiceInPackage: " + service + " type=" + resolvedType);
18050            final long origId = Binder.clearCallingIdentity();
18051            ComponentName res;
18052            try {
18053                res = mServices.startServiceLocked(null, service,
18054                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
18055            } finally {
18056                Binder.restoreCallingIdentity(origId);
18057            }
18058            return res;
18059        }
18060    }
18061
18062    @Override
18063    public int stopService(IApplicationThread caller, Intent service,
18064            String resolvedType, int userId) {
18065        enforceNotIsolatedCaller("stopService");
18066        // Refuse possible leaked file descriptors
18067        if (service != null && service.hasFileDescriptors() == true) {
18068            throw new IllegalArgumentException("File descriptors passed in Intent");
18069        }
18070
18071        synchronized(this) {
18072            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18073        }
18074    }
18075
18076    @Override
18077    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18078        enforceNotIsolatedCaller("peekService");
18079        // Refuse possible leaked file descriptors
18080        if (service != null && service.hasFileDescriptors() == true) {
18081            throw new IllegalArgumentException("File descriptors passed in Intent");
18082        }
18083
18084        if (callingPackage == null) {
18085            throw new IllegalArgumentException("callingPackage cannot be null");
18086        }
18087
18088        synchronized(this) {
18089            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18090        }
18091    }
18092
18093    @Override
18094    public boolean stopServiceToken(ComponentName className, IBinder token,
18095            int startId) {
18096        synchronized(this) {
18097            return mServices.stopServiceTokenLocked(className, token, startId);
18098        }
18099    }
18100
18101    @Override
18102    public void setServiceForeground(ComponentName className, IBinder token,
18103            int id, Notification notification, int flags) {
18104        synchronized(this) {
18105            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18106        }
18107    }
18108
18109    @Override
18110    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18111            boolean requireFull, String name, String callerPackage) {
18112        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18113                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18114    }
18115
18116    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18117            String className, int flags) {
18118        boolean result = false;
18119        // For apps that don't have pre-defined UIDs, check for permission
18120        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18121            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18122                if (ActivityManager.checkUidPermission(
18123                        INTERACT_ACROSS_USERS,
18124                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18125                    ComponentName comp = new ComponentName(aInfo.packageName, className);
18126                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
18127                            + " requests FLAG_SINGLE_USER, but app does not hold "
18128                            + INTERACT_ACROSS_USERS;
18129                    Slog.w(TAG, msg);
18130                    throw new SecurityException(msg);
18131                }
18132                // Permission passed
18133                result = true;
18134            }
18135        } else if ("system".equals(componentProcessName)) {
18136            result = true;
18137        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18138            // Phone app and persistent apps are allowed to export singleuser providers.
18139            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18140                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18141        }
18142        if (DEBUG_MU) Slog.v(TAG_MU,
18143                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18144                + Integer.toHexString(flags) + ") = " + result);
18145        return result;
18146    }
18147
18148    /**
18149     * Checks to see if the caller is in the same app as the singleton
18150     * component, or the component is in a special app. It allows special apps
18151     * to export singleton components but prevents exporting singleton
18152     * components for regular apps.
18153     */
18154    boolean isValidSingletonCall(int callingUid, int componentUid) {
18155        int componentAppId = UserHandle.getAppId(componentUid);
18156        return UserHandle.isSameApp(callingUid, componentUid)
18157                || componentAppId == SYSTEM_UID
18158                || componentAppId == PHONE_UID
18159                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18160                        == PackageManager.PERMISSION_GRANTED;
18161    }
18162
18163    public int bindService(IApplicationThread caller, IBinder token, Intent service,
18164            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18165            int userId) throws TransactionTooLargeException {
18166        enforceNotIsolatedCaller("bindService");
18167
18168        // Refuse possible leaked file descriptors
18169        if (service != null && service.hasFileDescriptors() == true) {
18170            throw new IllegalArgumentException("File descriptors passed in Intent");
18171        }
18172
18173        if (callingPackage == null) {
18174            throw new IllegalArgumentException("callingPackage cannot be null");
18175        }
18176
18177        synchronized(this) {
18178            return mServices.bindServiceLocked(caller, token, service,
18179                    resolvedType, connection, flags, callingPackage, userId);
18180        }
18181    }
18182
18183    public boolean unbindService(IServiceConnection connection) {
18184        synchronized (this) {
18185            return mServices.unbindServiceLocked(connection);
18186        }
18187    }
18188
18189    public void publishService(IBinder token, Intent intent, IBinder service) {
18190        // Refuse possible leaked file descriptors
18191        if (intent != null && intent.hasFileDescriptors() == true) {
18192            throw new IllegalArgumentException("File descriptors passed in Intent");
18193        }
18194
18195        synchronized(this) {
18196            if (!(token instanceof ServiceRecord)) {
18197                throw new IllegalArgumentException("Invalid service token");
18198            }
18199            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18200        }
18201    }
18202
18203    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18204        // Refuse possible leaked file descriptors
18205        if (intent != null && intent.hasFileDescriptors() == true) {
18206            throw new IllegalArgumentException("File descriptors passed in Intent");
18207        }
18208
18209        synchronized(this) {
18210            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18211        }
18212    }
18213
18214    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18215        synchronized(this) {
18216            if (!(token instanceof ServiceRecord)) {
18217                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18218                throw new IllegalArgumentException("Invalid service token");
18219            }
18220            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18221        }
18222    }
18223
18224    // =========================================================
18225    // BACKUP AND RESTORE
18226    // =========================================================
18227
18228    // Cause the target app to be launched if necessary and its backup agent
18229    // instantiated.  The backup agent will invoke backupAgentCreated() on the
18230    // activity manager to announce its creation.
18231    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18232        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18233        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18234
18235        IPackageManager pm = AppGlobals.getPackageManager();
18236        ApplicationInfo app = null;
18237        try {
18238            app = pm.getApplicationInfo(packageName, 0, userId);
18239        } catch (RemoteException e) {
18240            // can't happen; package manager is process-local
18241        }
18242        if (app == null) {
18243            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18244            return false;
18245        }
18246
18247        int oldBackupUid;
18248        int newBackupUid;
18249
18250        synchronized(this) {
18251            // !!! TODO: currently no check here that we're already bound
18252            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18253            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18254            synchronized (stats) {
18255                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18256            }
18257
18258            // Backup agent is now in use, its package can't be stopped.
18259            try {
18260                AppGlobals.getPackageManager().setPackageStoppedState(
18261                        app.packageName, false, UserHandle.getUserId(app.uid));
18262            } catch (RemoteException e) {
18263            } catch (IllegalArgumentException e) {
18264                Slog.w(TAG, "Failed trying to unstop package "
18265                        + app.packageName + ": " + e);
18266            }
18267
18268            BackupRecord r = new BackupRecord(ss, app, backupMode);
18269            ComponentName hostingName =
18270                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18271                            ? new ComponentName(app.packageName, app.backupAgentName)
18272                            : new ComponentName("android", "FullBackupAgent");
18273            // startProcessLocked() returns existing proc's record if it's already running
18274            ProcessRecord proc = startProcessLocked(app.processName, app,
18275                    false, 0, "backup", hostingName, false, false, false);
18276            if (proc == null) {
18277                Slog.e(TAG, "Unable to start backup agent process " + r);
18278                return false;
18279            }
18280
18281            // If the app is a regular app (uid >= 10000) and not the system server or phone
18282            // process, etc, then mark it as being in full backup so that certain calls to the
18283            // process can be blocked. This is not reset to false anywhere because we kill the
18284            // process after the full backup is done and the ProcessRecord will vaporize anyway.
18285            if (UserHandle.isApp(app.uid) &&
18286                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18287                proc.inFullBackup = true;
18288            }
18289            r.app = proc;
18290            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18291            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18292            mBackupTarget = r;
18293            mBackupAppName = app.packageName;
18294
18295            // Try not to kill the process during backup
18296            updateOomAdjLocked(proc, true);
18297
18298            // If the process is already attached, schedule the creation of the backup agent now.
18299            // If it is not yet live, this will be done when it attaches to the framework.
18300            if (proc.thread != null) {
18301                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18302                try {
18303                    proc.thread.scheduleCreateBackupAgent(app,
18304                            compatibilityInfoForPackageLocked(app), backupMode);
18305                } catch (RemoteException e) {
18306                    // Will time out on the backup manager side
18307                }
18308            } else {
18309                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18310            }
18311            // Invariants: at this point, the target app process exists and the application
18312            // is either already running or in the process of coming up.  mBackupTarget and
18313            // mBackupAppName describe the app, so that when it binds back to the AM we
18314            // know that it's scheduled for a backup-agent operation.
18315        }
18316
18317        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18318        if (oldBackupUid != -1) {
18319            js.removeBackingUpUid(oldBackupUid);
18320        }
18321        if (newBackupUid != -1) {
18322            js.addBackingUpUid(newBackupUid);
18323        }
18324
18325        return true;
18326    }
18327
18328    @Override
18329    public void clearPendingBackup() {
18330        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18331        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18332
18333        synchronized (this) {
18334            mBackupTarget = null;
18335            mBackupAppName = null;
18336        }
18337
18338        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18339        js.clearAllBackingUpUids();
18340    }
18341
18342    // A backup agent has just come up
18343    public void backupAgentCreated(String agentPackageName, IBinder agent) {
18344        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18345                + " = " + agent);
18346
18347        synchronized(this) {
18348            if (!agentPackageName.equals(mBackupAppName)) {
18349                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18350                return;
18351            }
18352        }
18353
18354        long oldIdent = Binder.clearCallingIdentity();
18355        try {
18356            IBackupManager bm = IBackupManager.Stub.asInterface(
18357                    ServiceManager.getService(Context.BACKUP_SERVICE));
18358            bm.agentConnected(agentPackageName, agent);
18359        } catch (RemoteException e) {
18360            // can't happen; the backup manager service is local
18361        } catch (Exception e) {
18362            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18363            e.printStackTrace();
18364        } finally {
18365            Binder.restoreCallingIdentity(oldIdent);
18366        }
18367    }
18368
18369    // done with this agent
18370    public void unbindBackupAgent(ApplicationInfo appInfo) {
18371        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18372        if (appInfo == null) {
18373            Slog.w(TAG, "unbind backup agent for null app");
18374            return;
18375        }
18376
18377        int oldBackupUid;
18378
18379        synchronized(this) {
18380            try {
18381                if (mBackupAppName == null) {
18382                    Slog.w(TAG, "Unbinding backup agent with no active backup");
18383                    return;
18384                }
18385
18386                if (!mBackupAppName.equals(appInfo.packageName)) {
18387                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18388                    return;
18389                }
18390
18391                // Not backing this app up any more; reset its OOM adjustment
18392                final ProcessRecord proc = mBackupTarget.app;
18393                updateOomAdjLocked(proc, true);
18394                proc.inFullBackup = false;
18395
18396                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18397
18398                // If the app crashed during backup, 'thread' will be null here
18399                if (proc.thread != null) {
18400                    try {
18401                        proc.thread.scheduleDestroyBackupAgent(appInfo,
18402                                compatibilityInfoForPackageLocked(appInfo));
18403                    } catch (Exception e) {
18404                        Slog.e(TAG, "Exception when unbinding backup agent:");
18405                        e.printStackTrace();
18406                    }
18407                }
18408            } finally {
18409                mBackupTarget = null;
18410                mBackupAppName = null;
18411            }
18412        }
18413
18414        if (oldBackupUid != -1) {
18415            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18416            js.removeBackingUpUid(oldBackupUid);
18417        }
18418    }
18419
18420    // =========================================================
18421    // BROADCASTS
18422    // =========================================================
18423
18424    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18425        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18426            return false;
18427        }
18428        // Easy case -- we have the app's ProcessRecord.
18429        if (record != null) {
18430            return record.info.isInstantApp();
18431        }
18432        // Otherwise check with PackageManager.
18433        if (callerPackage == null) {
18434            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18435            throw new IllegalArgumentException("Calling application did not provide package name");
18436        }
18437        mAppOpsService.checkPackage(uid, callerPackage);
18438        try {
18439            IPackageManager pm = AppGlobals.getPackageManager();
18440            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18441        } catch (RemoteException e) {
18442            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18443            return true;
18444        }
18445    }
18446
18447    boolean isPendingBroadcastProcessLocked(int pid) {
18448        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18449                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18450    }
18451
18452    void skipPendingBroadcastLocked(int pid) {
18453            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18454            for (BroadcastQueue queue : mBroadcastQueues) {
18455                queue.skipPendingBroadcastLocked(pid);
18456            }
18457    }
18458
18459    // The app just attached; send any pending broadcasts that it should receive
18460    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18461        boolean didSomething = false;
18462        for (BroadcastQueue queue : mBroadcastQueues) {
18463            didSomething |= queue.sendPendingBroadcastsLocked(app);
18464        }
18465        return didSomething;
18466    }
18467
18468    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18469            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18470            int flags) {
18471        enforceNotIsolatedCaller("registerReceiver");
18472        ArrayList<Intent> stickyIntents = null;
18473        ProcessRecord callerApp = null;
18474        final boolean visibleToInstantApps
18475                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18476        int callingUid;
18477        int callingPid;
18478        boolean instantApp;
18479        synchronized(this) {
18480            if (caller != null) {
18481                callerApp = getRecordForAppLocked(caller);
18482                if (callerApp == null) {
18483                    throw new SecurityException(
18484                            "Unable to find app for caller " + caller
18485                            + " (pid=" + Binder.getCallingPid()
18486                            + ") when registering receiver " + receiver);
18487                }
18488                if (callerApp.info.uid != SYSTEM_UID &&
18489                        !callerApp.pkgList.containsKey(callerPackage) &&
18490                        !"android".equals(callerPackage)) {
18491                    throw new SecurityException("Given caller package " + callerPackage
18492                            + " is not running in process " + callerApp);
18493                }
18494                callingUid = callerApp.info.uid;
18495                callingPid = callerApp.pid;
18496            } else {
18497                callerPackage = null;
18498                callingUid = Binder.getCallingUid();
18499                callingPid = Binder.getCallingPid();
18500            }
18501
18502            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18503            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18504                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18505
18506            Iterator<String> actions = filter.actionsIterator();
18507            if (actions == null) {
18508                ArrayList<String> noAction = new ArrayList<String>(1);
18509                noAction.add(null);
18510                actions = noAction.iterator();
18511            }
18512
18513            // Collect stickies of users
18514            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18515            while (actions.hasNext()) {
18516                String action = actions.next();
18517                for (int id : userIds) {
18518                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18519                    if (stickies != null) {
18520                        ArrayList<Intent> intents = stickies.get(action);
18521                        if (intents != null) {
18522                            if (stickyIntents == null) {
18523                                stickyIntents = new ArrayList<Intent>();
18524                            }
18525                            stickyIntents.addAll(intents);
18526                        }
18527                    }
18528                }
18529            }
18530        }
18531
18532        ArrayList<Intent> allSticky = null;
18533        if (stickyIntents != null) {
18534            final ContentResolver resolver = mContext.getContentResolver();
18535            // Look for any matching sticky broadcasts...
18536            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18537                Intent intent = stickyIntents.get(i);
18538                // Don't provided intents that aren't available to instant apps.
18539                if (instantApp &&
18540                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18541                    continue;
18542                }
18543                // If intent has scheme "content", it will need to acccess
18544                // provider that needs to lock mProviderMap in ActivityThread
18545                // and also it may need to wait application response, so we
18546                // cannot lock ActivityManagerService here.
18547                if (filter.match(resolver, intent, true, TAG) >= 0) {
18548                    if (allSticky == null) {
18549                        allSticky = new ArrayList<Intent>();
18550                    }
18551                    allSticky.add(intent);
18552                }
18553            }
18554        }
18555
18556        // The first sticky in the list is returned directly back to the client.
18557        Intent sticky = allSticky != null ? allSticky.get(0) : null;
18558        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18559        if (receiver == null) {
18560            return sticky;
18561        }
18562
18563        synchronized (this) {
18564            if (callerApp != null && (callerApp.thread == null
18565                    || callerApp.thread.asBinder() != caller.asBinder())) {
18566                // Original caller already died
18567                return null;
18568            }
18569            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18570            if (rl == null) {
18571                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18572                        userId, receiver);
18573                if (rl.app != null) {
18574                    rl.app.receivers.add(rl);
18575                } else {
18576                    try {
18577                        receiver.asBinder().linkToDeath(rl, 0);
18578                    } catch (RemoteException e) {
18579                        return sticky;
18580                    }
18581                    rl.linkedToDeath = true;
18582                }
18583                mRegisteredReceivers.put(receiver.asBinder(), rl);
18584            } else if (rl.uid != callingUid) {
18585                throw new IllegalArgumentException(
18586                        "Receiver requested to register for uid " + callingUid
18587                        + " was previously registered for uid " + rl.uid
18588                        + " callerPackage is " + callerPackage);
18589            } else if (rl.pid != callingPid) {
18590                throw new IllegalArgumentException(
18591                        "Receiver requested to register for pid " + callingPid
18592                        + " was previously registered for pid " + rl.pid
18593                        + " callerPackage is " + callerPackage);
18594            } else if (rl.userId != userId) {
18595                throw new IllegalArgumentException(
18596                        "Receiver requested to register for user " + userId
18597                        + " was previously registered for user " + rl.userId
18598                        + " callerPackage is " + callerPackage);
18599            }
18600            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18601                    permission, callingUid, userId, instantApp, visibleToInstantApps);
18602            rl.add(bf);
18603            if (!bf.debugCheck()) {
18604                Slog.w(TAG, "==> For Dynamic broadcast");
18605            }
18606            mReceiverResolver.addFilter(bf);
18607
18608            // Enqueue broadcasts for all existing stickies that match
18609            // this filter.
18610            if (allSticky != null) {
18611                ArrayList receivers = new ArrayList();
18612                receivers.add(bf);
18613
18614                final int stickyCount = allSticky.size();
18615                for (int i = 0; i < stickyCount; i++) {
18616                    Intent intent = allSticky.get(i);
18617                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18618                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18619                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18620                            null, 0, null, null, false, true, true, -1);
18621                    queue.enqueueParallelBroadcastLocked(r);
18622                    queue.scheduleBroadcastsLocked();
18623                }
18624            }
18625
18626            return sticky;
18627        }
18628    }
18629
18630    public void unregisterReceiver(IIntentReceiver receiver) {
18631        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18632
18633        final long origId = Binder.clearCallingIdentity();
18634        try {
18635            boolean doTrim = false;
18636
18637            synchronized(this) {
18638                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18639                if (rl != null) {
18640                    final BroadcastRecord r = rl.curBroadcast;
18641                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18642                        final boolean doNext = r.queue.finishReceiverLocked(
18643                                r, r.resultCode, r.resultData, r.resultExtras,
18644                                r.resultAbort, false);
18645                        if (doNext) {
18646                            doTrim = true;
18647                            r.queue.processNextBroadcast(false);
18648                        }
18649                    }
18650
18651                    if (rl.app != null) {
18652                        rl.app.receivers.remove(rl);
18653                    }
18654                    removeReceiverLocked(rl);
18655                    if (rl.linkedToDeath) {
18656                        rl.linkedToDeath = false;
18657                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18658                    }
18659                }
18660            }
18661
18662            // If we actually concluded any broadcasts, we might now be able
18663            // to trim the recipients' apps from our working set
18664            if (doTrim) {
18665                trimApplications();
18666                return;
18667            }
18668
18669        } finally {
18670            Binder.restoreCallingIdentity(origId);
18671        }
18672    }
18673
18674    void removeReceiverLocked(ReceiverList rl) {
18675        mRegisteredReceivers.remove(rl.receiver.asBinder());
18676        for (int i = rl.size() - 1; i >= 0; i--) {
18677            mReceiverResolver.removeFilter(rl.get(i));
18678        }
18679    }
18680
18681    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18682        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18683            ProcessRecord r = mLruProcesses.get(i);
18684            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18685                try {
18686                    r.thread.dispatchPackageBroadcast(cmd, packages);
18687                } catch (RemoteException ex) {
18688                }
18689            }
18690        }
18691    }
18692
18693    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18694            int callingUid, int[] users) {
18695        // TODO: come back and remove this assumption to triage all broadcasts
18696        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18697
18698        List<ResolveInfo> receivers = null;
18699        try {
18700            HashSet<ComponentName> singleUserReceivers = null;
18701            boolean scannedFirstReceivers = false;
18702            for (int user : users) {
18703                // Skip users that have Shell restrictions, with exception of always permitted
18704                // Shell broadcasts
18705                if (callingUid == SHELL_UID
18706                        && mUserController.hasUserRestriction(
18707                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18708                        && !isPermittedShellBroadcast(intent)) {
18709                    continue;
18710                }
18711                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18712                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18713                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18714                    // If this is not the system user, we need to check for
18715                    // any receivers that should be filtered out.
18716                    for (int i=0; i<newReceivers.size(); i++) {
18717                        ResolveInfo ri = newReceivers.get(i);
18718                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18719                            newReceivers.remove(i);
18720                            i--;
18721                        }
18722                    }
18723                }
18724                if (newReceivers != null && newReceivers.size() == 0) {
18725                    newReceivers = null;
18726                }
18727                if (receivers == null) {
18728                    receivers = newReceivers;
18729                } else if (newReceivers != null) {
18730                    // We need to concatenate the additional receivers
18731                    // found with what we have do far.  This would be easy,
18732                    // but we also need to de-dup any receivers that are
18733                    // singleUser.
18734                    if (!scannedFirstReceivers) {
18735                        // Collect any single user receivers we had already retrieved.
18736                        scannedFirstReceivers = true;
18737                        for (int i=0; i<receivers.size(); i++) {
18738                            ResolveInfo ri = receivers.get(i);
18739                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18740                                ComponentName cn = new ComponentName(
18741                                        ri.activityInfo.packageName, ri.activityInfo.name);
18742                                if (singleUserReceivers == null) {
18743                                    singleUserReceivers = new HashSet<ComponentName>();
18744                                }
18745                                singleUserReceivers.add(cn);
18746                            }
18747                        }
18748                    }
18749                    // Add the new results to the existing results, tracking
18750                    // and de-dupping single user receivers.
18751                    for (int i=0; i<newReceivers.size(); i++) {
18752                        ResolveInfo ri = newReceivers.get(i);
18753                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18754                            ComponentName cn = new ComponentName(
18755                                    ri.activityInfo.packageName, ri.activityInfo.name);
18756                            if (singleUserReceivers == null) {
18757                                singleUserReceivers = new HashSet<ComponentName>();
18758                            }
18759                            if (!singleUserReceivers.contains(cn)) {
18760                                singleUserReceivers.add(cn);
18761                                receivers.add(ri);
18762                            }
18763                        } else {
18764                            receivers.add(ri);
18765                        }
18766                    }
18767                }
18768            }
18769        } catch (RemoteException ex) {
18770            // pm is in same process, this will never happen.
18771        }
18772        return receivers;
18773    }
18774
18775    private boolean isPermittedShellBroadcast(Intent intent) {
18776        // remote bugreport should always be allowed to be taken
18777        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18778    }
18779
18780    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18781            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18782        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18783            // Don't yell about broadcasts sent via shell
18784            return;
18785        }
18786
18787        final String action = intent.getAction();
18788        if (isProtectedBroadcast
18789                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18790                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18791                || Intent.ACTION_MEDIA_BUTTON.equals(action)
18792                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18793                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18794                || Intent.ACTION_MASTER_CLEAR.equals(action)
18795                || Intent.ACTION_FACTORY_RESET.equals(action)
18796                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18797                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18798                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18799                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18800                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18801                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18802                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18803            // Broadcast is either protected, or it's a public action that
18804            // we've relaxed, so it's fine for system internals to send.
18805            return;
18806        }
18807
18808        // This broadcast may be a problem...  but there are often system components that
18809        // want to send an internal broadcast to themselves, which is annoying to have to
18810        // explicitly list each action as a protected broadcast, so we will check for that
18811        // one safe case and allow it: an explicit broadcast, only being received by something
18812        // that has protected itself.
18813        if (receivers != null && receivers.size() > 0
18814                && (intent.getPackage() != null || intent.getComponent() != null)) {
18815            boolean allProtected = true;
18816            for (int i = receivers.size()-1; i >= 0; i--) {
18817                Object target = receivers.get(i);
18818                if (target instanceof ResolveInfo) {
18819                    ResolveInfo ri = (ResolveInfo)target;
18820                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18821                        allProtected = false;
18822                        break;
18823                    }
18824                } else {
18825                    BroadcastFilter bf = (BroadcastFilter)target;
18826                    if (bf.requiredPermission == null) {
18827                        allProtected = false;
18828                        break;
18829                    }
18830                }
18831            }
18832            if (allProtected) {
18833                // All safe!
18834                return;
18835            }
18836        }
18837
18838        // The vast majority of broadcasts sent from system internals
18839        // should be protected to avoid security holes, so yell loudly
18840        // to ensure we examine these cases.
18841        if (callerApp != null) {
18842            Log.wtf(TAG, "Sending non-protected broadcast " + action
18843                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
18844                    new Throwable());
18845        } else {
18846            Log.wtf(TAG, "Sending non-protected broadcast " + action
18847                            + " from system uid " + UserHandle.formatUid(callingUid)
18848                            + " pkg " + callerPackage,
18849                    new Throwable());
18850        }
18851    }
18852
18853    final int broadcastIntentLocked(ProcessRecord callerApp,
18854            String callerPackage, Intent intent, String resolvedType,
18855            IIntentReceiver resultTo, int resultCode, String resultData,
18856            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
18857            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
18858        intent = new Intent(intent);
18859
18860        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
18861        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
18862        if (callerInstantApp) {
18863            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
18864        }
18865
18866        // By default broadcasts do not go to stopped apps.
18867        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
18868
18869        // If we have not finished booting, don't allow this to launch new processes.
18870        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
18871            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18872        }
18873
18874        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
18875                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
18876                + " ordered=" + ordered + " userid=" + userId);
18877        if ((resultTo != null) && !ordered) {
18878            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
18879        }
18880
18881        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18882                ALLOW_NON_FULL, "broadcast", callerPackage);
18883
18884        // Make sure that the user who is receiving this broadcast is running.
18885        // If not, we will just skip it. Make an exception for shutdown broadcasts
18886        // and upgrade steps.
18887
18888        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
18889            if ((callingUid != SYSTEM_UID
18890                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
18891                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
18892                Slog.w(TAG, "Skipping broadcast of " + intent
18893                        + ": user " + userId + " is stopped");
18894                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
18895            }
18896        }
18897
18898        BroadcastOptions brOptions = null;
18899        if (bOptions != null) {
18900            brOptions = new BroadcastOptions(bOptions);
18901            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
18902                // See if the caller is allowed to do this.  Note we are checking against
18903                // the actual real caller (not whoever provided the operation as say a
18904                // PendingIntent), because that who is actually supplied the arguments.
18905                if (checkComponentPermission(
18906                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
18907                        Binder.getCallingPid(), Binder.getCallingUid(), -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.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
18914                    Slog.w(TAG, msg);
18915                    throw new SecurityException(msg);
18916                }
18917            }
18918        }
18919
18920        // Verify that protected broadcasts are only being sent by system code,
18921        // and that system code is only sending protected broadcasts.
18922        final String action = intent.getAction();
18923        final boolean isProtectedBroadcast;
18924        try {
18925            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18926        } catch (RemoteException e) {
18927            Slog.w(TAG, "Remote exception", e);
18928            return ActivityManager.BROADCAST_SUCCESS;
18929        }
18930
18931        final boolean isCallerSystem;
18932        switch (UserHandle.getAppId(callingUid)) {
18933            case ROOT_UID:
18934            case SYSTEM_UID:
18935            case PHONE_UID:
18936            case BLUETOOTH_UID:
18937            case NFC_UID:
18938                isCallerSystem = true;
18939                break;
18940            default:
18941                isCallerSystem = (callerApp != null) && callerApp.persistent;
18942                break;
18943        }
18944
18945        // First line security check before anything else: stop non-system apps from
18946        // sending protected broadcasts.
18947        if (!isCallerSystem) {
18948            if (isProtectedBroadcast) {
18949                String msg = "Permission Denial: not allowed to send broadcast "
18950                        + action + " from pid="
18951                        + callingPid + ", uid=" + callingUid;
18952                Slog.w(TAG, msg);
18953                throw new SecurityException(msg);
18954
18955            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18956                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18957                // Special case for compatibility: we don't want apps to send this,
18958                // but historically it has not been protected and apps may be using it
18959                // to poke their own app widget.  So, instead of making it protected,
18960                // just limit it to the caller.
18961                if (callerPackage == null) {
18962                    String msg = "Permission Denial: not allowed to send broadcast "
18963                            + action + " from unknown caller.";
18964                    Slog.w(TAG, msg);
18965                    throw new SecurityException(msg);
18966                } else if (intent.getComponent() != null) {
18967                    // They are good enough to send to an explicit component...  verify
18968                    // it is being sent to the calling app.
18969                    if (!intent.getComponent().getPackageName().equals(
18970                            callerPackage)) {
18971                        String msg = "Permission Denial: not allowed to send broadcast "
18972                                + action + " to "
18973                                + intent.getComponent().getPackageName() + " from "
18974                                + callerPackage;
18975                        Slog.w(TAG, msg);
18976                        throw new SecurityException(msg);
18977                    }
18978                } else {
18979                    // Limit broadcast to their own package.
18980                    intent.setPackage(callerPackage);
18981                }
18982            }
18983        }
18984
18985        if (action != null) {
18986            if (getBackgroundLaunchBroadcasts().contains(action)) {
18987                if (DEBUG_BACKGROUND_CHECK) {
18988                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
18989                }
18990                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
18991            }
18992
18993            switch (action) {
18994                case Intent.ACTION_UID_REMOVED:
18995                case Intent.ACTION_PACKAGE_REMOVED:
18996                case Intent.ACTION_PACKAGE_CHANGED:
18997                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18998                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18999                case Intent.ACTION_PACKAGES_SUSPENDED:
19000                case Intent.ACTION_PACKAGES_UNSUSPENDED:
19001                    // Handle special intents: if this broadcast is from the package
19002                    // manager about a package being removed, we need to remove all of
19003                    // its activities from the history stack.
19004                    if (checkComponentPermission(
19005                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19006                            callingPid, callingUid, -1, true)
19007                            != PackageManager.PERMISSION_GRANTED) {
19008                        String msg = "Permission Denial: " + intent.getAction()
19009                                + " broadcast from " + callerPackage + " (pid=" + callingPid
19010                                + ", uid=" + callingUid + ")"
19011                                + " requires "
19012                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19013                        Slog.w(TAG, msg);
19014                        throw new SecurityException(msg);
19015                    }
19016                    switch (action) {
19017                        case Intent.ACTION_UID_REMOVED:
19018                            final int uid = getUidFromIntent(intent);
19019                            if (uid >= 0) {
19020                                mBatteryStatsService.removeUid(uid);
19021                                mAppOpsService.uidRemoved(uid);
19022                            }
19023                            break;
19024                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19025                            // If resources are unavailable just force stop all those packages
19026                            // and flush the attribute cache as well.
19027                            String list[] =
19028                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19029                            if (list != null && list.length > 0) {
19030                                for (int i = 0; i < list.length; i++) {
19031                                    forceStopPackageLocked(list[i], -1, false, true, true,
19032                                            false, false, userId, "storage unmount");
19033                                }
19034                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19035                                sendPackageBroadcastLocked(
19036                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19037                                        list, userId);
19038                            }
19039                            break;
19040                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19041                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19042                            break;
19043                        case Intent.ACTION_PACKAGE_REMOVED:
19044                        case Intent.ACTION_PACKAGE_CHANGED:
19045                            Uri data = intent.getData();
19046                            String ssp;
19047                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19048                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19049                                final boolean replacing =
19050                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19051                                final boolean killProcess =
19052                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19053                                final boolean fullUninstall = removed && !replacing;
19054                                if (removed) {
19055                                    if (killProcess) {
19056                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
19057                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19058                                                false, true, true, false, fullUninstall, userId,
19059                                                removed ? "pkg removed" : "pkg changed");
19060                                    }
19061                                    final int cmd = killProcess
19062                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
19063                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19064                                    sendPackageBroadcastLocked(cmd,
19065                                            new String[] {ssp}, userId);
19066                                    if (fullUninstall) {
19067                                        mAppOpsService.packageRemoved(
19068                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19069
19070                                        // Remove all permissions granted from/to this package
19071                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
19072
19073                                        removeTasksByPackageNameLocked(ssp, userId);
19074
19075                                        mServices.forceStopPackageLocked(ssp, userId);
19076
19077                                        // Hide the "unsupported display" dialog if necessary.
19078                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19079                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19080                                            mUnsupportedDisplaySizeDialog.dismiss();
19081                                            mUnsupportedDisplaySizeDialog = null;
19082                                        }
19083                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
19084                                        mBatteryStatsService.notePackageUninstalled(ssp);
19085                                    }
19086                                } else {
19087                                    if (killProcess) {
19088                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
19089                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19090                                                userId, ProcessList.INVALID_ADJ,
19091                                                false, true, true, false, "change " + ssp);
19092                                    }
19093                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19094                                            intent.getStringArrayExtra(
19095                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19096                                }
19097                            }
19098                            break;
19099                        case Intent.ACTION_PACKAGES_SUSPENDED:
19100                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
19101                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19102                                    intent.getAction());
19103                            final String[] packageNames = intent.getStringArrayExtra(
19104                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
19105                            final int userHandle = intent.getIntExtra(
19106                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19107
19108                            synchronized(ActivityManagerService.this) {
19109                                mRecentTasks.onPackagesSuspendedChanged(
19110                                        packageNames, suspended, userHandle);
19111                            }
19112                            break;
19113                    }
19114                    break;
19115                case Intent.ACTION_PACKAGE_REPLACED:
19116                {
19117                    final Uri data = intent.getData();
19118                    final String ssp;
19119                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19120                        final ApplicationInfo aInfo =
19121                                getPackageManagerInternalLocked().getApplicationInfo(
19122                                        ssp,
19123                                        userId);
19124                        if (aInfo == null) {
19125                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19126                                    + " ssp=" + ssp + " data=" + data);
19127                            return ActivityManager.BROADCAST_SUCCESS;
19128                        }
19129                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19130                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19131                                new String[] {ssp}, userId);
19132                    }
19133                    break;
19134                }
19135                case Intent.ACTION_PACKAGE_ADDED:
19136                {
19137                    // Special case for adding a package: by default turn on compatibility mode.
19138                    Uri data = intent.getData();
19139                    String ssp;
19140                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19141                        final boolean replacing =
19142                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19143                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19144
19145                        try {
19146                            ApplicationInfo ai = AppGlobals.getPackageManager().
19147                                    getApplicationInfo(ssp, 0, 0);
19148                            mBatteryStatsService.notePackageInstalled(ssp,
19149                                    ai != null ? ai.versionCode : 0);
19150                        } catch (RemoteException e) {
19151                        }
19152                    }
19153                    break;
19154                }
19155                case Intent.ACTION_PACKAGE_DATA_CLEARED:
19156                {
19157                    Uri data = intent.getData();
19158                    String ssp;
19159                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19160                        // Hide the "unsupported display" dialog if necessary.
19161                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19162                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19163                            mUnsupportedDisplaySizeDialog.dismiss();
19164                            mUnsupportedDisplaySizeDialog = null;
19165                        }
19166                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
19167                    }
19168                    break;
19169                }
19170                case Intent.ACTION_TIMEZONE_CHANGED:
19171                    // If this is the time zone changed action, queue up a message that will reset
19172                    // the timezone of all currently running processes. This message will get
19173                    // queued up before the broadcast happens.
19174                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19175                    break;
19176                case Intent.ACTION_TIME_CHANGED:
19177                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19178                    // the tri-state value it may contain and "unknown".
19179                    // For convenience we re-use the Intent extra values.
19180                    final int NO_EXTRA_VALUE_FOUND = -1;
19181                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19182                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19183                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
19184                    // Only send a message if the time preference is available.
19185                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19186                        Message updateTimePreferenceMsg =
19187                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19188                                        timeFormatPreferenceMsgValue, 0);
19189                        mHandler.sendMessage(updateTimePreferenceMsg);
19190                    }
19191                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19192                    synchronized (stats) {
19193                        stats.noteCurrentTimeChangedLocked();
19194                    }
19195                    break;
19196                case Intent.ACTION_CLEAR_DNS_CACHE:
19197                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19198                    break;
19199                case Proxy.PROXY_CHANGE_ACTION:
19200                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19201                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19202                    break;
19203                case android.hardware.Camera.ACTION_NEW_PICTURE:
19204                case android.hardware.Camera.ACTION_NEW_VIDEO:
19205                    // In N we just turned these off; in O we are turing them back on partly,
19206                    // only for registered receivers.  This will still address the main problem
19207                    // (a spam of apps waking up when a picture is taken putting significant
19208                    // memory pressure on the system at a bad point), while still allowing apps
19209                    // that are already actively running to know about this happening.
19210                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19211                    break;
19212                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19213                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19214                    break;
19215                case "com.android.launcher.action.INSTALL_SHORTCUT":
19216                    // As of O, we no longer support this broadcasts, even for pre-O apps.
19217                    // Apps should now be using ShortcutManager.pinRequestShortcut().
19218                    Log.w(TAG, "Broadcast " + action
19219                            + " no longer supported. It will not be delivered.");
19220                    return ActivityManager.BROADCAST_SUCCESS;
19221            }
19222
19223            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19224                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19225                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19226                final int uid = getUidFromIntent(intent);
19227                if (uid != -1) {
19228                    final UidRecord uidRec = mActiveUids.get(uid);
19229                    if (uidRec != null) {
19230                        uidRec.updateHasInternetPermission();
19231                    }
19232                }
19233            }
19234        }
19235
19236        // Add to the sticky list if requested.
19237        if (sticky) {
19238            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19239                    callingPid, callingUid)
19240                    != PackageManager.PERMISSION_GRANTED) {
19241                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19242                        + callingPid + ", uid=" + callingUid
19243                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19244                Slog.w(TAG, msg);
19245                throw new SecurityException(msg);
19246            }
19247            if (requiredPermissions != null && requiredPermissions.length > 0) {
19248                Slog.w(TAG, "Can't broadcast sticky intent " + intent
19249                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
19250                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19251            }
19252            if (intent.getComponent() != null) {
19253                throw new SecurityException(
19254                        "Sticky broadcasts can't target a specific component");
19255            }
19256            // We use userId directly here, since the "all" target is maintained
19257            // as a separate set of sticky broadcasts.
19258            if (userId != UserHandle.USER_ALL) {
19259                // But first, if this is not a broadcast to all users, then
19260                // make sure it doesn't conflict with an existing broadcast to
19261                // all users.
19262                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19263                        UserHandle.USER_ALL);
19264                if (stickies != null) {
19265                    ArrayList<Intent> list = stickies.get(intent.getAction());
19266                    if (list != null) {
19267                        int N = list.size();
19268                        int i;
19269                        for (i=0; i<N; i++) {
19270                            if (intent.filterEquals(list.get(i))) {
19271                                throw new IllegalArgumentException(
19272                                        "Sticky broadcast " + intent + " for user "
19273                                        + userId + " conflicts with existing global broadcast");
19274                            }
19275                        }
19276                    }
19277                }
19278            }
19279            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19280            if (stickies == null) {
19281                stickies = new ArrayMap<>();
19282                mStickyBroadcasts.put(userId, stickies);
19283            }
19284            ArrayList<Intent> list = stickies.get(intent.getAction());
19285            if (list == null) {
19286                list = new ArrayList<>();
19287                stickies.put(intent.getAction(), list);
19288            }
19289            final int stickiesCount = list.size();
19290            int i;
19291            for (i = 0; i < stickiesCount; i++) {
19292                if (intent.filterEquals(list.get(i))) {
19293                    // This sticky already exists, replace it.
19294                    list.set(i, new Intent(intent));
19295                    break;
19296                }
19297            }
19298            if (i >= stickiesCount) {
19299                list.add(new Intent(intent));
19300            }
19301        }
19302
19303        int[] users;
19304        if (userId == UserHandle.USER_ALL) {
19305            // Caller wants broadcast to go to all started users.
19306            users = mUserController.getStartedUserArrayLocked();
19307        } else {
19308            // Caller wants broadcast to go to one specific user.
19309            users = new int[] {userId};
19310        }
19311
19312        // Figure out who all will receive this broadcast.
19313        List receivers = null;
19314        List<BroadcastFilter> registeredReceivers = null;
19315        // Need to resolve the intent to interested receivers...
19316        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19317                 == 0) {
19318            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19319        }
19320        if (intent.getComponent() == null) {
19321            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19322                // Query one target user at a time, excluding shell-restricted users
19323                for (int i = 0; i < users.length; i++) {
19324                    if (mUserController.hasUserRestriction(
19325                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19326                        continue;
19327                    }
19328                    List<BroadcastFilter> registeredReceiversForUser =
19329                            mReceiverResolver.queryIntent(intent,
19330                                    resolvedType, false /*defaultOnly*/, users[i]);
19331                    if (registeredReceivers == null) {
19332                        registeredReceivers = registeredReceiversForUser;
19333                    } else if (registeredReceiversForUser != null) {
19334                        registeredReceivers.addAll(registeredReceiversForUser);
19335                    }
19336                }
19337            } else {
19338                registeredReceivers = mReceiverResolver.queryIntent(intent,
19339                        resolvedType, false /*defaultOnly*/, userId);
19340            }
19341        }
19342
19343        final boolean replacePending =
19344                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19345
19346        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19347                + " replacePending=" + replacePending);
19348
19349        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19350        if (!ordered && NR > 0) {
19351            // If we are not serializing this broadcast, then send the
19352            // registered receivers separately so they don't wait for the
19353            // components to be launched.
19354            if (isCallerSystem) {
19355                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19356                        isProtectedBroadcast, registeredReceivers);
19357            }
19358            final BroadcastQueue queue = broadcastQueueForIntent(intent);
19359            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19360                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19361                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19362                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19363            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19364            final boolean replaced = replacePending
19365                    && (queue.replaceParallelBroadcastLocked(r) != null);
19366            // Note: We assume resultTo is null for non-ordered broadcasts.
19367            if (!replaced) {
19368                queue.enqueueParallelBroadcastLocked(r);
19369                queue.scheduleBroadcastsLocked();
19370            }
19371            registeredReceivers = null;
19372            NR = 0;
19373        }
19374
19375        // Merge into one list.
19376        int ir = 0;
19377        if (receivers != null) {
19378            // A special case for PACKAGE_ADDED: do not allow the package
19379            // being added to see this broadcast.  This prevents them from
19380            // using this as a back door to get run as soon as they are
19381            // installed.  Maybe in the future we want to have a special install
19382            // broadcast or such for apps, but we'd like to deliberately make
19383            // this decision.
19384            String skipPackages[] = null;
19385            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19386                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19387                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19388                Uri data = intent.getData();
19389                if (data != null) {
19390                    String pkgName = data.getSchemeSpecificPart();
19391                    if (pkgName != null) {
19392                        skipPackages = new String[] { pkgName };
19393                    }
19394                }
19395            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19396                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19397            }
19398            if (skipPackages != null && (skipPackages.length > 0)) {
19399                for (String skipPackage : skipPackages) {
19400                    if (skipPackage != null) {
19401                        int NT = receivers.size();
19402                        for (int it=0; it<NT; it++) {
19403                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
19404                            if (curt.activityInfo.packageName.equals(skipPackage)) {
19405                                receivers.remove(it);
19406                                it--;
19407                                NT--;
19408                            }
19409                        }
19410                    }
19411                }
19412            }
19413
19414            int NT = receivers != null ? receivers.size() : 0;
19415            int it = 0;
19416            ResolveInfo curt = null;
19417            BroadcastFilter curr = null;
19418            while (it < NT && ir < NR) {
19419                if (curt == null) {
19420                    curt = (ResolveInfo)receivers.get(it);
19421                }
19422                if (curr == null) {
19423                    curr = registeredReceivers.get(ir);
19424                }
19425                if (curr.getPriority() >= curt.priority) {
19426                    // Insert this broadcast record into the final list.
19427                    receivers.add(it, curr);
19428                    ir++;
19429                    curr = null;
19430                    it++;
19431                    NT++;
19432                } else {
19433                    // Skip to the next ResolveInfo in the final list.
19434                    it++;
19435                    curt = null;
19436                }
19437            }
19438        }
19439        while (ir < NR) {
19440            if (receivers == null) {
19441                receivers = new ArrayList();
19442            }
19443            receivers.add(registeredReceivers.get(ir));
19444            ir++;
19445        }
19446
19447        if (isCallerSystem) {
19448            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19449                    isProtectedBroadcast, receivers);
19450        }
19451
19452        if ((receivers != null && receivers.size() > 0)
19453                || resultTo != null) {
19454            BroadcastQueue queue = broadcastQueueForIntent(intent);
19455            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19456                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19457                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19458                    resultData, resultExtras, ordered, sticky, false, userId);
19459
19460            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19461                    + ": prev had " + queue.mOrderedBroadcasts.size());
19462            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19463                    "Enqueueing broadcast " + r.intent.getAction());
19464
19465            final BroadcastRecord oldRecord =
19466                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19467            if (oldRecord != null) {
19468                // Replaced, fire the result-to receiver.
19469                if (oldRecord.resultTo != null) {
19470                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19471                    try {
19472                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19473                                oldRecord.intent,
19474                                Activity.RESULT_CANCELED, null, null,
19475                                false, false, oldRecord.userId);
19476                    } catch (RemoteException e) {
19477                        Slog.w(TAG, "Failure ["
19478                                + queue.mQueueName + "] sending broadcast result of "
19479                                + intent, e);
19480
19481                    }
19482                }
19483            } else {
19484                queue.enqueueOrderedBroadcastLocked(r);
19485                queue.scheduleBroadcastsLocked();
19486            }
19487        } else {
19488            // There was nobody interested in the broadcast, but we still want to record
19489            // that it happened.
19490            if (intent.getComponent() == null && intent.getPackage() == null
19491                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19492                // This was an implicit broadcast... let's record it for posterity.
19493                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19494            }
19495        }
19496
19497        return ActivityManager.BROADCAST_SUCCESS;
19498    }
19499
19500    /**
19501     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19502     */
19503    private int getUidFromIntent(Intent intent) {
19504        if (intent == null) {
19505            return -1;
19506        }
19507        final Bundle intentExtras = intent.getExtras();
19508        return intent.hasExtra(Intent.EXTRA_UID)
19509                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19510    }
19511
19512    final void rotateBroadcastStatsIfNeededLocked() {
19513        final long now = SystemClock.elapsedRealtime();
19514        if (mCurBroadcastStats == null ||
19515                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19516            mLastBroadcastStats = mCurBroadcastStats;
19517            if (mLastBroadcastStats != null) {
19518                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19519                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19520            }
19521            mCurBroadcastStats = new BroadcastStats();
19522        }
19523    }
19524
19525    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19526            int skipCount, long dispatchTime) {
19527        rotateBroadcastStatsIfNeededLocked();
19528        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19529    }
19530
19531    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19532        rotateBroadcastStatsIfNeededLocked();
19533        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19534    }
19535
19536    final Intent verifyBroadcastLocked(Intent intent) {
19537        // Refuse possible leaked file descriptors
19538        if (intent != null && intent.hasFileDescriptors() == true) {
19539            throw new IllegalArgumentException("File descriptors passed in Intent");
19540        }
19541
19542        int flags = intent.getFlags();
19543
19544        if (!mProcessesReady) {
19545            // if the caller really truly claims to know what they're doing, go
19546            // ahead and allow the broadcast without launching any receivers
19547            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19548                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19549            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19550                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19551                        + " before boot completion");
19552                throw new IllegalStateException("Cannot broadcast before boot completed");
19553            }
19554        }
19555
19556        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19557            throw new IllegalArgumentException(
19558                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19559        }
19560
19561        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19562            switch (Binder.getCallingUid()) {
19563                case ROOT_UID:
19564                case SHELL_UID:
19565                    break;
19566                default:
19567                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19568                            + Binder.getCallingUid());
19569                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19570                    break;
19571            }
19572        }
19573
19574        return intent;
19575    }
19576
19577    public final int broadcastIntent(IApplicationThread caller,
19578            Intent intent, String resolvedType, IIntentReceiver resultTo,
19579            int resultCode, String resultData, Bundle resultExtras,
19580            String[] requiredPermissions, int appOp, Bundle bOptions,
19581            boolean serialized, boolean sticky, int userId) {
19582        enforceNotIsolatedCaller("broadcastIntent");
19583        synchronized(this) {
19584            intent = verifyBroadcastLocked(intent);
19585
19586            final ProcessRecord callerApp = getRecordForAppLocked(caller);
19587            final int callingPid = Binder.getCallingPid();
19588            final int callingUid = Binder.getCallingUid();
19589            final long origId = Binder.clearCallingIdentity();
19590            int res = broadcastIntentLocked(callerApp,
19591                    callerApp != null ? callerApp.info.packageName : null,
19592                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19593                    requiredPermissions, appOp, bOptions, serialized, sticky,
19594                    callingPid, callingUid, userId);
19595            Binder.restoreCallingIdentity(origId);
19596            return res;
19597        }
19598    }
19599
19600
19601    int broadcastIntentInPackage(String packageName, int uid,
19602            Intent intent, String resolvedType, IIntentReceiver resultTo,
19603            int resultCode, String resultData, Bundle resultExtras,
19604            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19605            int userId) {
19606        synchronized(this) {
19607            intent = verifyBroadcastLocked(intent);
19608
19609            final long origId = Binder.clearCallingIdentity();
19610            String[] requiredPermissions = requiredPermission == null ? null
19611                    : new String[] {requiredPermission};
19612            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19613                    resultTo, resultCode, resultData, resultExtras,
19614                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19615                    sticky, -1, uid, userId);
19616            Binder.restoreCallingIdentity(origId);
19617            return res;
19618        }
19619    }
19620
19621    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19622        // Refuse possible leaked file descriptors
19623        if (intent != null && intent.hasFileDescriptors() == true) {
19624            throw new IllegalArgumentException("File descriptors passed in Intent");
19625        }
19626
19627        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19628                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19629
19630        synchronized(this) {
19631            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19632                    != PackageManager.PERMISSION_GRANTED) {
19633                String msg = "Permission Denial: unbroadcastIntent() from pid="
19634                        + Binder.getCallingPid()
19635                        + ", uid=" + Binder.getCallingUid()
19636                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19637                Slog.w(TAG, msg);
19638                throw new SecurityException(msg);
19639            }
19640            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19641            if (stickies != null) {
19642                ArrayList<Intent> list = stickies.get(intent.getAction());
19643                if (list != null) {
19644                    int N = list.size();
19645                    int i;
19646                    for (i=0; i<N; i++) {
19647                        if (intent.filterEquals(list.get(i))) {
19648                            list.remove(i);
19649                            break;
19650                        }
19651                    }
19652                    if (list.size() <= 0) {
19653                        stickies.remove(intent.getAction());
19654                    }
19655                }
19656                if (stickies.size() <= 0) {
19657                    mStickyBroadcasts.remove(userId);
19658                }
19659            }
19660        }
19661    }
19662
19663    void backgroundServicesFinishedLocked(int userId) {
19664        for (BroadcastQueue queue : mBroadcastQueues) {
19665            queue.backgroundServicesFinishedLocked(userId);
19666        }
19667    }
19668
19669    public void finishReceiver(IBinder who, int resultCode, String resultData,
19670            Bundle resultExtras, boolean resultAbort, int flags) {
19671        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19672
19673        // Refuse possible leaked file descriptors
19674        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19675            throw new IllegalArgumentException("File descriptors passed in Bundle");
19676        }
19677
19678        final long origId = Binder.clearCallingIdentity();
19679        try {
19680            boolean doNext = false;
19681            BroadcastRecord r;
19682
19683            synchronized(this) {
19684                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19685                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19686                r = queue.getMatchingOrderedReceiver(who);
19687                if (r != null) {
19688                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19689                        resultData, resultExtras, resultAbort, true);
19690                }
19691            }
19692
19693            if (doNext) {
19694                r.queue.processNextBroadcast(false);
19695            }
19696            trimApplications();
19697        } finally {
19698            Binder.restoreCallingIdentity(origId);
19699        }
19700    }
19701
19702    // =========================================================
19703    // INSTRUMENTATION
19704    // =========================================================
19705
19706    public boolean startInstrumentation(ComponentName className,
19707            String profileFile, int flags, Bundle arguments,
19708            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19709            int userId, String abiOverride) {
19710        enforceNotIsolatedCaller("startInstrumentation");
19711        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19712                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19713        // Refuse possible leaked file descriptors
19714        if (arguments != null && arguments.hasFileDescriptors()) {
19715            throw new IllegalArgumentException("File descriptors passed in Bundle");
19716        }
19717
19718        synchronized(this) {
19719            InstrumentationInfo ii = null;
19720            ApplicationInfo ai = null;
19721            try {
19722                ii = mContext.getPackageManager().getInstrumentationInfo(
19723                    className, STOCK_PM_FLAGS);
19724                ai = AppGlobals.getPackageManager().getApplicationInfo(
19725                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19726            } catch (PackageManager.NameNotFoundException e) {
19727            } catch (RemoteException e) {
19728            }
19729            if (ii == null) {
19730                reportStartInstrumentationFailureLocked(watcher, className,
19731                        "Unable to find instrumentation info for: " + className);
19732                return false;
19733            }
19734            if (ai == null) {
19735                reportStartInstrumentationFailureLocked(watcher, className,
19736                        "Unable to find instrumentation target package: " + ii.targetPackage);
19737                return false;
19738            }
19739            if (!ai.hasCode()) {
19740                reportStartInstrumentationFailureLocked(watcher, className,
19741                        "Instrumentation target has no code: " + ii.targetPackage);
19742                return false;
19743            }
19744
19745            int match = mContext.getPackageManager().checkSignatures(
19746                    ii.targetPackage, ii.packageName);
19747            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19748                String msg = "Permission Denial: starting instrumentation "
19749                        + className + " from pid="
19750                        + Binder.getCallingPid()
19751                        + ", uid=" + Binder.getCallingPid()
19752                        + " not allowed because package " + ii.packageName
19753                        + " does not have a signature matching the target "
19754                        + ii.targetPackage;
19755                reportStartInstrumentationFailureLocked(watcher, className, msg);
19756                throw new SecurityException(msg);
19757            }
19758
19759            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19760            activeInstr.mClass = className;
19761            String defProcess = ai.processName;;
19762            if (ii.targetProcesses == null) {
19763                activeInstr.mTargetProcesses = new String[]{ai.processName};
19764            } else if (ii.targetProcesses.equals("*")) {
19765                activeInstr.mTargetProcesses = new String[0];
19766            } else {
19767                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19768                defProcess = activeInstr.mTargetProcesses[0];
19769            }
19770            activeInstr.mTargetInfo = ai;
19771            activeInstr.mProfileFile = profileFile;
19772            activeInstr.mArguments = arguments;
19773            activeInstr.mWatcher = watcher;
19774            activeInstr.mUiAutomationConnection = uiAutomationConnection;
19775            activeInstr.mResultClass = className;
19776
19777            final long origId = Binder.clearCallingIdentity();
19778            // Instrumentation can kill and relaunch even persistent processes
19779            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19780                    "start instr");
19781            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19782            app.instr = activeInstr;
19783            activeInstr.mFinished = false;
19784            activeInstr.mRunningProcesses.add(app);
19785            if (!mActiveInstrumentation.contains(activeInstr)) {
19786                mActiveInstrumentation.add(activeInstr);
19787            }
19788            Binder.restoreCallingIdentity(origId);
19789        }
19790
19791        return true;
19792    }
19793
19794    /**
19795     * Report errors that occur while attempting to start Instrumentation.  Always writes the
19796     * error to the logs, but if somebody is watching, send the report there too.  This enables
19797     * the "am" command to report errors with more information.
19798     *
19799     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19800     * @param cn The component name of the instrumentation.
19801     * @param report The error report.
19802     */
19803    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19804            ComponentName cn, String report) {
19805        Slog.w(TAG, report);
19806        if (watcher != null) {
19807            Bundle results = new Bundle();
19808            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19809            results.putString("Error", report);
19810            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19811        }
19812    }
19813
19814    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19815        if (app.instr == null) {
19816            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19817            return;
19818        }
19819
19820        if (!app.instr.mFinished && results != null) {
19821            if (app.instr.mCurResults == null) {
19822                app.instr.mCurResults = new Bundle(results);
19823            } else {
19824                app.instr.mCurResults.putAll(results);
19825            }
19826        }
19827    }
19828
19829    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
19830        int userId = UserHandle.getCallingUserId();
19831        // Refuse possible leaked file descriptors
19832        if (results != null && results.hasFileDescriptors()) {
19833            throw new IllegalArgumentException("File descriptors passed in Intent");
19834        }
19835
19836        synchronized(this) {
19837            ProcessRecord app = getRecordForAppLocked(target);
19838            if (app == null) {
19839                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
19840                return;
19841            }
19842            final long origId = Binder.clearCallingIdentity();
19843            addInstrumentationResultsLocked(app, results);
19844            Binder.restoreCallingIdentity(origId);
19845        }
19846    }
19847
19848    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
19849        if (app.instr == null) {
19850            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19851            return;
19852        }
19853
19854        if (!app.instr.mFinished) {
19855            if (app.instr.mWatcher != null) {
19856                Bundle finalResults = app.instr.mCurResults;
19857                if (finalResults != null) {
19858                    if (app.instr.mCurResults != null && results != null) {
19859                        finalResults.putAll(results);
19860                    }
19861                } else {
19862                    finalResults = results;
19863                }
19864                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
19865                        app.instr.mClass, resultCode, finalResults);
19866            }
19867
19868            // Can't call out of the system process with a lock held, so post a message.
19869            if (app.instr.mUiAutomationConnection != null) {
19870                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
19871                        app.instr.mUiAutomationConnection).sendToTarget();
19872            }
19873            app.instr.mFinished = true;
19874        }
19875
19876        app.instr.removeProcess(app);
19877        app.instr = null;
19878
19879        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
19880                "finished inst");
19881    }
19882
19883    public void finishInstrumentation(IApplicationThread target,
19884            int resultCode, Bundle results) {
19885        int userId = UserHandle.getCallingUserId();
19886        // Refuse possible leaked file descriptors
19887        if (results != null && results.hasFileDescriptors()) {
19888            throw new IllegalArgumentException("File descriptors passed in Intent");
19889        }
19890
19891        synchronized(this) {
19892            ProcessRecord app = getRecordForAppLocked(target);
19893            if (app == null) {
19894                Slog.w(TAG, "finishInstrumentation: no app for " + target);
19895                return;
19896            }
19897            final long origId = Binder.clearCallingIdentity();
19898            finishInstrumentationLocked(app, resultCode, results);
19899            Binder.restoreCallingIdentity(origId);
19900        }
19901    }
19902
19903    // =========================================================
19904    // CONFIGURATION
19905    // =========================================================
19906
19907    public ConfigurationInfo getDeviceConfigurationInfo() {
19908        ConfigurationInfo config = new ConfigurationInfo();
19909        synchronized (this) {
19910            final Configuration globalConfig = getGlobalConfiguration();
19911            config.reqTouchScreen = globalConfig.touchscreen;
19912            config.reqKeyboardType = globalConfig.keyboard;
19913            config.reqNavigation = globalConfig.navigation;
19914            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
19915                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
19916                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
19917            }
19918            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
19919                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
19920                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
19921            }
19922            config.reqGlEsVersion = GL_ES_VERSION;
19923        }
19924        return config;
19925    }
19926
19927    ActivityStack getFocusedStack() {
19928        return mStackSupervisor.getFocusedStack();
19929    }
19930
19931    @Override
19932    public int getFocusedStackId() throws RemoteException {
19933        ActivityStack focusedStack = getFocusedStack();
19934        if (focusedStack != null) {
19935            return focusedStack.getStackId();
19936        }
19937        return -1;
19938    }
19939
19940    public Configuration getConfiguration() {
19941        Configuration ci;
19942        synchronized(this) {
19943            ci = new Configuration(getGlobalConfiguration());
19944            ci.userSetLocale = false;
19945        }
19946        return ci;
19947    }
19948
19949    @Override
19950    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
19951        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
19952        synchronized (this) {
19953            mSuppressResizeConfigChanges = suppress;
19954        }
19955    }
19956
19957    /**
19958     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
19959     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
19960     *       activity and clearing the task at the same time.
19961     */
19962    @Override
19963    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
19964        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
19965        if (StackId.isHomeOrRecentsStack(fromStackId)) {
19966            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
19967        }
19968        synchronized (this) {
19969            final long origId = Binder.clearCallingIdentity();
19970            try {
19971                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
19972            } finally {
19973                Binder.restoreCallingIdentity(origId);
19974            }
19975        }
19976    }
19977
19978    @Override
19979    public void updatePersistentConfiguration(Configuration values) {
19980        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
19981        enforceWriteSettingsPermission("updatePersistentConfiguration()");
19982        if (values == null) {
19983            throw new NullPointerException("Configuration must not be null");
19984        }
19985
19986        int userId = UserHandle.getCallingUserId();
19987
19988        synchronized(this) {
19989            updatePersistentConfigurationLocked(values, userId);
19990        }
19991    }
19992
19993    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
19994        final long origId = Binder.clearCallingIdentity();
19995        try {
19996            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
19997        } finally {
19998            Binder.restoreCallingIdentity(origId);
19999        }
20000    }
20001
20002    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20003        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20004                FONT_SCALE, 1.0f, userId);
20005
20006        synchronized (this) {
20007            if (getGlobalConfiguration().fontScale == scaleFactor) {
20008                return;
20009            }
20010
20011            final Configuration configuration
20012                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20013            configuration.fontScale = scaleFactor;
20014            updatePersistentConfigurationLocked(configuration, userId);
20015        }
20016    }
20017
20018    private void enforceWriteSettingsPermission(String func) {
20019        int uid = Binder.getCallingUid();
20020        if (uid == ROOT_UID) {
20021            return;
20022        }
20023
20024        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20025                Settings.getPackageNameForUid(mContext, uid), false)) {
20026            return;
20027        }
20028
20029        String msg = "Permission Denial: " + func + " from pid="
20030                + Binder.getCallingPid()
20031                + ", uid=" + uid
20032                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20033        Slog.w(TAG, msg);
20034        throw new SecurityException(msg);
20035    }
20036
20037    @Override
20038    public boolean updateConfiguration(Configuration values) {
20039        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20040
20041        synchronized(this) {
20042            if (values == null && mWindowManager != null) {
20043                // sentinel: fetch the current configuration from the window manager
20044                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20045            }
20046
20047            if (mWindowManager != null) {
20048                // Update OOM levels based on display size.
20049                mProcessList.applyDisplaySize(mWindowManager);
20050            }
20051
20052            final long origId = Binder.clearCallingIdentity();
20053            try {
20054                if (values != null) {
20055                    Settings.System.clearConfiguration(values);
20056                }
20057                updateConfigurationLocked(values, null, false, false /* persistent */,
20058                        UserHandle.USER_NULL, false /* deferResume */,
20059                        mTmpUpdateConfigurationResult);
20060                return mTmpUpdateConfigurationResult.changes != 0;
20061            } finally {
20062                Binder.restoreCallingIdentity(origId);
20063            }
20064        }
20065    }
20066
20067    void updateUserConfigurationLocked() {
20068        final Configuration configuration = new Configuration(getGlobalConfiguration());
20069        final int currentUserId = mUserController.getCurrentUserIdLocked();
20070        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20071                currentUserId, Settings.System.canWrite(mContext));
20072        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20073                false /* persistent */, currentUserId, false /* deferResume */);
20074    }
20075
20076    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20077            boolean initLocale) {
20078        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20079    }
20080
20081    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20082            boolean initLocale, boolean deferResume) {
20083        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20084        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20085                UserHandle.USER_NULL, deferResume);
20086    }
20087
20088    // To cache the list of supported system locales
20089    private String[] mSupportedSystemLocales = null;
20090
20091    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20092            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20093        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20094                deferResume, null /* result */);
20095    }
20096
20097    /**
20098     * Do either or both things: (1) change the current configuration, and (2)
20099     * make sure the given activity is running with the (now) current
20100     * configuration.  Returns true if the activity has been left running, or
20101     * false if <var>starting</var> is being destroyed to match the new
20102     * configuration.
20103     *
20104     * @param userId is only used when persistent parameter is set to true to persist configuration
20105     *               for that particular user
20106     */
20107    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20108            boolean initLocale, boolean persistent, int userId, boolean deferResume,
20109            UpdateConfigurationResult result) {
20110        int changes = 0;
20111        boolean kept = true;
20112
20113        if (mWindowManager != null) {
20114            mWindowManager.deferSurfaceLayout();
20115        }
20116        try {
20117            if (values != null) {
20118                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20119                        deferResume);
20120            }
20121
20122            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20123        } finally {
20124            if (mWindowManager != null) {
20125                mWindowManager.continueSurfaceLayout();
20126            }
20127        }
20128
20129        if (result != null) {
20130            result.changes = changes;
20131            result.activityRelaunched = !kept;
20132        }
20133        return kept;
20134    }
20135
20136    /** Update default (global) configuration and notify listeners about changes. */
20137    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20138            boolean persistent, int userId, boolean deferResume) {
20139        mTempConfig.setTo(getGlobalConfiguration());
20140        final int changes = mTempConfig.updateFrom(values);
20141        if (changes == 0) {
20142            return 0;
20143        }
20144
20145        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20146                "Updating global configuration to: " + values);
20147
20148        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20149
20150        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20151            final LocaleList locales = values.getLocales();
20152            int bestLocaleIndex = 0;
20153            if (locales.size() > 1) {
20154                if (mSupportedSystemLocales == null) {
20155                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20156                }
20157                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20158            }
20159            SystemProperties.set("persist.sys.locale",
20160                    locales.get(bestLocaleIndex).toLanguageTag());
20161            LocaleList.setDefault(locales, bestLocaleIndex);
20162            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20163                    locales.get(bestLocaleIndex)));
20164        }
20165
20166        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20167        mTempConfig.seq = mConfigurationSeq;
20168
20169        // Update stored global config and notify everyone about the change.
20170        mStackSupervisor.onConfigurationChanged(mTempConfig);
20171
20172        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20173        // TODO(multi-display): Update UsageEvents#Event to include displayId.
20174        mUsageStatsService.reportConfigurationChange(mTempConfig,
20175                mUserController.getCurrentUserIdLocked());
20176
20177        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20178        mShowDialogs = shouldShowDialogs(mTempConfig);
20179
20180        AttributeCache ac = AttributeCache.instance();
20181        if (ac != null) {
20182            ac.updateConfiguration(mTempConfig);
20183        }
20184
20185        // Make sure all resources in our process are updated right now, so that anyone who is going
20186        // to retrieve resource values after we return will be sure to get the new ones. This is
20187        // especially important during boot, where the first config change needs to guarantee all
20188        // resources have that config before following boot code is executed.
20189        mSystemThread.applyConfigurationToResources(mTempConfig);
20190
20191        // We need another copy of global config because we're scheduling some calls instead of
20192        // running them in place. We need to be sure that object we send will be handled unchanged.
20193        final Configuration configCopy = new Configuration(mTempConfig);
20194        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20195            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20196            msg.obj = configCopy;
20197            msg.arg1 = userId;
20198            mHandler.sendMessage(msg);
20199        }
20200
20201        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20202            ProcessRecord app = mLruProcesses.get(i);
20203            try {
20204                if (app.thread != null) {
20205                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20206                            + app.processName + " new config " + configCopy);
20207                    app.thread.scheduleConfigurationChanged(configCopy);
20208                }
20209            } catch (Exception e) {
20210            }
20211        }
20212
20213        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20214        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20215                | Intent.FLAG_RECEIVER_FOREGROUND
20216                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20217        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20218                AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20219                UserHandle.USER_ALL);
20220        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20221            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20222            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20223                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20224                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20225            if (initLocale || !mProcessesReady) {
20226                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20227            }
20228            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20229                    AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20230                    UserHandle.USER_ALL);
20231        }
20232
20233        // Override configuration of the default display duplicates global config, so we need to
20234        // update it also. This will also notify WindowManager about changes.
20235        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20236                DEFAULT_DISPLAY);
20237
20238        return changes;
20239    }
20240
20241    @Override
20242    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20243        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20244
20245        synchronized (this) {
20246            // Check if display is initialized in AM.
20247            if (!mStackSupervisor.isDisplayAdded(displayId)) {
20248                // Call might come when display is not yet added or has already been removed.
20249                if (DEBUG_CONFIGURATION) {
20250                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20251                            + displayId);
20252                }
20253                return false;
20254            }
20255
20256            if (values == null && mWindowManager != null) {
20257                // sentinel: fetch the current configuration from the window manager
20258                values = mWindowManager.computeNewConfiguration(displayId);
20259            }
20260
20261            if (mWindowManager != null) {
20262                // Update OOM levels based on display size.
20263                mProcessList.applyDisplaySize(mWindowManager);
20264            }
20265
20266            final long origId = Binder.clearCallingIdentity();
20267            try {
20268                if (values != null) {
20269                    Settings.System.clearConfiguration(values);
20270                }
20271                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20272                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20273                return mTmpUpdateConfigurationResult.changes != 0;
20274            } finally {
20275                Binder.restoreCallingIdentity(origId);
20276            }
20277        }
20278    }
20279
20280    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20281            boolean deferResume, int displayId) {
20282        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20283                displayId, null /* result */);
20284    }
20285
20286    /**
20287     * Updates override configuration specific for the selected display. If no config is provided,
20288     * new one will be computed in WM based on current display info.
20289     */
20290    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20291            ActivityRecord starting, boolean deferResume, int displayId,
20292            UpdateConfigurationResult result) {
20293        int changes = 0;
20294        boolean kept = true;
20295
20296        if (mWindowManager != null) {
20297            mWindowManager.deferSurfaceLayout();
20298        }
20299        try {
20300            if (values != null) {
20301                if (displayId == DEFAULT_DISPLAY) {
20302                    // Override configuration of the default display duplicates global config, so
20303                    // we're calling global config update instead for default display. It will also
20304                    // apply the correct override config.
20305                    changes = updateGlobalConfiguration(values, false /* initLocale */,
20306                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20307                } else {
20308                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20309                }
20310            }
20311
20312            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20313        } finally {
20314            if (mWindowManager != null) {
20315                mWindowManager.continueSurfaceLayout();
20316            }
20317        }
20318
20319        if (result != null) {
20320            result.changes = changes;
20321            result.activityRelaunched = !kept;
20322        }
20323        return kept;
20324    }
20325
20326    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20327            int displayId) {
20328        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20329        final int changes = mTempConfig.updateFrom(values);
20330        if (changes == 0) {
20331            return 0;
20332        }
20333
20334        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
20335                + " for displayId=" + displayId);
20336        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20337
20338        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20339        if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20340            // Reset the unsupported display size dialog.
20341            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20342
20343            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20344        }
20345
20346        // Update the configuration with WM first and check if any of the stacks need to be resized
20347        // due to the configuration change. If so, resize the stacks now and do any relaunches if
20348        // necessary. This way we don't need to relaunch again afterwards in
20349        // ensureActivityConfigurationLocked().
20350        if (mWindowManager != null) {
20351            final int[] resizedStacks =
20352                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20353            if (resizedStacks != null) {
20354                for (int stackId : resizedStacks) {
20355                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20356                }
20357            }
20358        }
20359
20360        return changes;
20361    }
20362
20363    /** Applies latest configuration and/or visibility updates if needed. */
20364    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20365        boolean kept = true;
20366        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20367        // mainStack is null during startup.
20368        if (mainStack != null) {
20369            if (changes != 0 && starting == null) {
20370                // If the configuration changed, and the caller is not already
20371                // in the process of starting an activity, then find the top
20372                // activity to check if its configuration needs to change.
20373                starting = mainStack.topRunningActivityLocked();
20374            }
20375
20376            if (starting != null) {
20377                kept = starting.ensureActivityConfigurationLocked(changes,
20378                        false /* preserveWindow */);
20379                // And we need to make sure at this point that all other activities
20380                // are made visible with the correct configuration.
20381                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20382                        !PRESERVE_WINDOWS);
20383            }
20384        }
20385
20386        return kept;
20387    }
20388
20389    /** Helper method that requests bounds from WM and applies them to stack. */
20390    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20391        final Rect newStackBounds = new Rect();
20392        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20393        mStackSupervisor.resizeStackLocked(
20394                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20395                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20396                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20397    }
20398
20399    /**
20400     * Decide based on the configuration whether we should show the ANR,
20401     * crash, etc dialogs.  The idea is that if there is no affordance to
20402     * press the on-screen buttons, or the user experience would be more
20403     * greatly impacted than the crash itself, we shouldn't show the dialog.
20404     *
20405     * A thought: SystemUI might also want to get told about this, the Power
20406     * dialog / global actions also might want different behaviors.
20407     */
20408    private static boolean shouldShowDialogs(Configuration config) {
20409        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20410                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20411                                   && config.navigation == Configuration.NAVIGATION_NONAV);
20412        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20413        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20414                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20415                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20416                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20417        return inputMethodExists && uiModeSupportsDialogs;
20418    }
20419
20420    @Override
20421    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20422        synchronized (this) {
20423            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20424            if (srec != null) {
20425                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20426            }
20427        }
20428        return false;
20429    }
20430
20431    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20432            Intent resultData) {
20433
20434        synchronized (this) {
20435            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20436            if (r != null) {
20437                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20438            }
20439            return false;
20440        }
20441    }
20442
20443    public int getLaunchedFromUid(IBinder activityToken) {
20444        ActivityRecord srec;
20445        synchronized (this) {
20446            srec = ActivityRecord.forTokenLocked(activityToken);
20447        }
20448        if (srec == null) {
20449            return -1;
20450        }
20451        return srec.launchedFromUid;
20452    }
20453
20454    public String getLaunchedFromPackage(IBinder activityToken) {
20455        ActivityRecord srec;
20456        synchronized (this) {
20457            srec = ActivityRecord.forTokenLocked(activityToken);
20458        }
20459        if (srec == null) {
20460            return null;
20461        }
20462        return srec.launchedFromPackage;
20463    }
20464
20465    // =========================================================
20466    // LIFETIME MANAGEMENT
20467    // =========================================================
20468
20469    // Returns whether the app is receiving broadcast.
20470    // If receiving, fetch all broadcast queues which the app is
20471    // the current [or imminent] receiver on.
20472    private boolean isReceivingBroadcastLocked(ProcessRecord app,
20473            ArraySet<BroadcastQueue> receivingQueues) {
20474        if (!app.curReceivers.isEmpty()) {
20475            for (BroadcastRecord r : app.curReceivers) {
20476                receivingQueues.add(r.queue);
20477            }
20478            return true;
20479        }
20480
20481        // It's not the current receiver, but it might be starting up to become one
20482        for (BroadcastQueue queue : mBroadcastQueues) {
20483            final BroadcastRecord r = queue.mPendingBroadcast;
20484            if (r != null && r.curApp == app) {
20485                // found it; report which queue it's in
20486                receivingQueues.add(queue);
20487            }
20488        }
20489
20490        return !receivingQueues.isEmpty();
20491    }
20492
20493    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20494            int targetUid, ComponentName targetComponent, String targetProcess) {
20495        if (!mTrackingAssociations) {
20496            return null;
20497        }
20498        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20499                = mAssociations.get(targetUid);
20500        if (components == null) {
20501            components = new ArrayMap<>();
20502            mAssociations.put(targetUid, components);
20503        }
20504        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20505        if (sourceUids == null) {
20506            sourceUids = new SparseArray<>();
20507            components.put(targetComponent, sourceUids);
20508        }
20509        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20510        if (sourceProcesses == null) {
20511            sourceProcesses = new ArrayMap<>();
20512            sourceUids.put(sourceUid, sourceProcesses);
20513        }
20514        Association ass = sourceProcesses.get(sourceProcess);
20515        if (ass == null) {
20516            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20517                    targetProcess);
20518            sourceProcesses.put(sourceProcess, ass);
20519        }
20520        ass.mCount++;
20521        ass.mNesting++;
20522        if (ass.mNesting == 1) {
20523            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20524            ass.mLastState = sourceState;
20525        }
20526        return ass;
20527    }
20528
20529    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20530            ComponentName targetComponent) {
20531        if (!mTrackingAssociations) {
20532            return;
20533        }
20534        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20535                = mAssociations.get(targetUid);
20536        if (components == null) {
20537            return;
20538        }
20539        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20540        if (sourceUids == null) {
20541            return;
20542        }
20543        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20544        if (sourceProcesses == null) {
20545            return;
20546        }
20547        Association ass = sourceProcesses.get(sourceProcess);
20548        if (ass == null || ass.mNesting <= 0) {
20549            return;
20550        }
20551        ass.mNesting--;
20552        if (ass.mNesting == 0) {
20553            long uptime = SystemClock.uptimeMillis();
20554            ass.mTime += uptime - ass.mStartTime;
20555            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20556                    += uptime - ass.mLastStateUptime;
20557            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20558        }
20559    }
20560
20561    private void noteUidProcessState(final int uid, final int state) {
20562        mBatteryStatsService.noteUidProcessState(uid, state);
20563        if (mTrackingAssociations) {
20564            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20565                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20566                        = mAssociations.valueAt(i1);
20567                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20568                    SparseArray<ArrayMap<String, Association>> sourceUids
20569                            = targetComponents.valueAt(i2);
20570                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20571                    if (sourceProcesses != null) {
20572                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20573                            Association ass = sourceProcesses.valueAt(i4);
20574                            if (ass.mNesting >= 1) {
20575                                // currently associated
20576                                long uptime = SystemClock.uptimeMillis();
20577                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20578                                        += uptime - ass.mLastStateUptime;
20579                                ass.mLastState = state;
20580                                ass.mLastStateUptime = uptime;
20581                            }
20582                        }
20583                    }
20584                }
20585            }
20586        }
20587    }
20588
20589    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20590            boolean doingAll, long now) {
20591        if (mAdjSeq == app.adjSeq) {
20592            // This adjustment has already been computed.
20593            return app.curRawAdj;
20594        }
20595
20596        if (app.thread == null) {
20597            app.adjSeq = mAdjSeq;
20598            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20599            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20600            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20601        }
20602
20603        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20604        app.adjSource = null;
20605        app.adjTarget = null;
20606        app.empty = false;
20607        app.cached = false;
20608
20609        final int activitiesSize = app.activities.size();
20610
20611        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20612            // The max adjustment doesn't allow this app to be anything
20613            // below foreground, so it is not worth doing work for it.
20614            app.adjType = "fixed";
20615            app.adjSeq = mAdjSeq;
20616            app.curRawAdj = app.maxAdj;
20617            app.foregroundActivities = false;
20618            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20619            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20620            // System processes can do UI, and when they do we want to have
20621            // them trim their memory after the user leaves the UI.  To
20622            // facilitate this, here we need to determine whether or not it
20623            // is currently showing UI.
20624            app.systemNoUi = true;
20625            if (app == TOP_APP) {
20626                app.systemNoUi = false;
20627                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20628                app.adjType = "pers-top-activity";
20629            } else if (app.hasTopUi) {
20630                app.systemNoUi = false;
20631                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20632                app.adjType = "pers-top-ui";
20633            } else if (activitiesSize > 0) {
20634                for (int j = 0; j < activitiesSize; j++) {
20635                    final ActivityRecord r = app.activities.get(j);
20636                    if (r.visible) {
20637                        app.systemNoUi = false;
20638                    }
20639                }
20640            }
20641            if (!app.systemNoUi) {
20642                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20643            }
20644            return (app.curAdj=app.maxAdj);
20645        }
20646
20647        app.systemNoUi = false;
20648
20649        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20650
20651        // Determine the importance of the process, starting with most
20652        // important to least, and assign an appropriate OOM adjustment.
20653        int adj;
20654        int schedGroup;
20655        int procState;
20656        boolean foregroundActivities = false;
20657        mTmpBroadcastQueue.clear();
20658        if (app == TOP_APP) {
20659            // The last app on the list is the foreground app.
20660            adj = ProcessList.FOREGROUND_APP_ADJ;
20661            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20662            app.adjType = "top-activity";
20663            foregroundActivities = true;
20664            procState = PROCESS_STATE_CUR_TOP;
20665        } else if (app.instr != null) {
20666            // Don't want to kill running instrumentation.
20667            adj = ProcessList.FOREGROUND_APP_ADJ;
20668            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20669            app.adjType = "instrumentation";
20670            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20671        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20672            // An app that is currently receiving a broadcast also
20673            // counts as being in the foreground for OOM killer purposes.
20674            // It's placed in a sched group based on the nature of the
20675            // broadcast as reflected by which queue it's active in.
20676            adj = ProcessList.FOREGROUND_APP_ADJ;
20677            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20678                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20679            app.adjType = "broadcast";
20680            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20681        } else if (app.executingServices.size() > 0) {
20682            // An app that is currently executing a service callback also
20683            // counts as being in the foreground.
20684            adj = ProcessList.FOREGROUND_APP_ADJ;
20685            schedGroup = app.execServicesFg ?
20686                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20687            app.adjType = "exec-service";
20688            procState = ActivityManager.PROCESS_STATE_SERVICE;
20689            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20690        } else {
20691            // As far as we know the process is empty.  We may change our mind later.
20692            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20693            // At this point we don't actually know the adjustment.  Use the cached adj
20694            // value that the caller wants us to.
20695            adj = cachedAdj;
20696            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20697            app.cached = true;
20698            app.empty = true;
20699            app.adjType = "cch-empty";
20700        }
20701
20702        // Examine all activities if not already foreground.
20703        if (!foregroundActivities && activitiesSize > 0) {
20704            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20705            for (int j = 0; j < activitiesSize; j++) {
20706                final ActivityRecord r = app.activities.get(j);
20707                if (r.app != app) {
20708                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20709                            + " instead of expected " + app);
20710                    if (r.app == null || (r.app.uid == app.uid)) {
20711                        // Only fix things up when they look sane
20712                        r.app = app;
20713                    } else {
20714                        continue;
20715                    }
20716                }
20717                if (r.visible) {
20718                    // App has a visible activity; only upgrade adjustment.
20719                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20720                        adj = ProcessList.VISIBLE_APP_ADJ;
20721                        app.adjType = "visible";
20722                    }
20723                    if (procState > PROCESS_STATE_CUR_TOP) {
20724                        procState = PROCESS_STATE_CUR_TOP;
20725                    }
20726                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20727                    app.cached = false;
20728                    app.empty = false;
20729                    foregroundActivities = true;
20730                    final TaskRecord task = r.getTask();
20731                    if (task != null && minLayer > 0) {
20732                        final int layer = task.mLayerRank;
20733                        if (layer >= 0 && minLayer > layer) {
20734                            minLayer = layer;
20735                        }
20736                    }
20737                    break;
20738                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20739                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20740                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20741                        app.adjType = "pausing";
20742                    }
20743                    if (procState > PROCESS_STATE_CUR_TOP) {
20744                        procState = PROCESS_STATE_CUR_TOP;
20745                    }
20746                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20747                    app.cached = false;
20748                    app.empty = false;
20749                    foregroundActivities = true;
20750                } else if (r.state == ActivityState.STOPPING) {
20751                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20752                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20753                        app.adjType = "stopping";
20754                    }
20755                    // For the process state, we will at this point consider the
20756                    // process to be cached.  It will be cached either as an activity
20757                    // or empty depending on whether the activity is finishing.  We do
20758                    // this so that we can treat the process as cached for purposes of
20759                    // memory trimming (determing current memory level, trim command to
20760                    // send to process) since there can be an arbitrary number of stopping
20761                    // processes and they should soon all go into the cached state.
20762                    if (!r.finishing) {
20763                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20764                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20765                        }
20766                    }
20767                    app.cached = false;
20768                    app.empty = false;
20769                    foregroundActivities = true;
20770                } else {
20771                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20772                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20773                        app.adjType = "cch-act";
20774                    }
20775                }
20776            }
20777            if (adj == ProcessList.VISIBLE_APP_ADJ) {
20778                adj += minLayer;
20779            }
20780        }
20781
20782        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20783                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20784            if (app.foregroundServices) {
20785                // The user is aware of this app, so make it visible.
20786                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20787                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20788                app.cached = false;
20789                app.adjType = "fg-service";
20790                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20791            } else if (app.hasOverlayUi) {
20792                // The process is display an overlay UI.
20793                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20794                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20795                app.cached = false;
20796                app.adjType = "has-overlay-ui";
20797                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20798            }
20799        }
20800
20801        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20802                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
20803            if (app.forcingToImportant != null) {
20804                // This is currently used for toasts...  they are not interactive, and
20805                // we don't want them to cause the app to become fully foreground (and
20806                // thus out of background check), so we yes the best background level we can.
20807                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20808                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
20809                app.cached = false;
20810                app.adjType = "force-imp";
20811                app.adjSource = app.forcingToImportant;
20812                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20813            }
20814        }
20815
20816        if (app == mHeavyWeightProcess) {
20817            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
20818                // We don't want to kill the current heavy-weight process.
20819                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
20820                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20821                app.cached = false;
20822                app.adjType = "heavy";
20823            }
20824            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20825                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
20826            }
20827        }
20828
20829        if (app == mHomeProcess) {
20830            if (adj > ProcessList.HOME_APP_ADJ) {
20831                // This process is hosting what we currently consider to be the
20832                // home app, so we don't want to let it go into the background.
20833                adj = ProcessList.HOME_APP_ADJ;
20834                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20835                app.cached = false;
20836                app.adjType = "home";
20837            }
20838            if (procState > ActivityManager.PROCESS_STATE_HOME) {
20839                procState = ActivityManager.PROCESS_STATE_HOME;
20840            }
20841        }
20842
20843        if (app == mPreviousProcess && app.activities.size() > 0) {
20844            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20845                // This was the previous process that showed UI to the user.
20846                // We want to try to keep it around more aggressively, to give
20847                // a good experience around switching between two apps.
20848                adj = ProcessList.PREVIOUS_APP_ADJ;
20849                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20850                app.cached = false;
20851                app.adjType = "previous";
20852            }
20853            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20854                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20855            }
20856        }
20857
20858        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
20859                + " reason=" + app.adjType);
20860
20861        // By default, we use the computed adjustment.  It may be changed if
20862        // there are applications dependent on our services or providers, but
20863        // this gives us a baseline and makes sure we don't get into an
20864        // infinite recursion.
20865        app.adjSeq = mAdjSeq;
20866        app.curRawAdj = adj;
20867        app.hasStartedServices = false;
20868
20869        if (mBackupTarget != null && app == mBackupTarget.app) {
20870            // If possible we want to avoid killing apps while they're being backed up
20871            if (adj > ProcessList.BACKUP_APP_ADJ) {
20872                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
20873                adj = ProcessList.BACKUP_APP_ADJ;
20874                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
20875                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
20876                }
20877                app.adjType = "backup";
20878                app.cached = false;
20879            }
20880            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
20881                procState = ActivityManager.PROCESS_STATE_BACKUP;
20882            }
20883        }
20884
20885        boolean mayBeTop = false;
20886
20887        for (int is = app.services.size()-1;
20888                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20889                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20890                        || procState > ActivityManager.PROCESS_STATE_TOP);
20891                is--) {
20892            ServiceRecord s = app.services.valueAt(is);
20893            if (s.startRequested) {
20894                app.hasStartedServices = true;
20895                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
20896                    procState = ActivityManager.PROCESS_STATE_SERVICE;
20897                }
20898                if (app.hasShownUi && app != mHomeProcess) {
20899                    // If this process has shown some UI, let it immediately
20900                    // go to the LRU list because it may be pretty heavy with
20901                    // UI stuff.  We'll tag it with a label just to help
20902                    // debug and understand what is going on.
20903                    if (adj > ProcessList.SERVICE_ADJ) {
20904                        app.adjType = "cch-started-ui-services";
20905                    }
20906                } else {
20907                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
20908                        // This service has seen some activity within
20909                        // recent memory, so we will keep its process ahead
20910                        // of the background processes.
20911                        if (adj > ProcessList.SERVICE_ADJ) {
20912                            adj = ProcessList.SERVICE_ADJ;
20913                            app.adjType = "started-services";
20914                            app.cached = false;
20915                        }
20916                    }
20917                    // If we have let the service slide into the background
20918                    // state, still have some text describing what it is doing
20919                    // even though the service no longer has an impact.
20920                    if (adj > ProcessList.SERVICE_ADJ) {
20921                        app.adjType = "cch-started-services";
20922                    }
20923                }
20924            }
20925
20926            for (int conni = s.connections.size()-1;
20927                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20928                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20929                            || procState > ActivityManager.PROCESS_STATE_TOP);
20930                    conni--) {
20931                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
20932                for (int i = 0;
20933                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
20934                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20935                                || procState > ActivityManager.PROCESS_STATE_TOP);
20936                        i++) {
20937                    // XXX should compute this based on the max of
20938                    // all connected clients.
20939                    ConnectionRecord cr = clist.get(i);
20940                    if (cr.binding.client == app) {
20941                        // Binding to ourself is not interesting.
20942                        continue;
20943                    }
20944
20945                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
20946                        ProcessRecord client = cr.binding.client;
20947                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
20948                                TOP_APP, doingAll, now);
20949                        int clientProcState = client.curProcState;
20950                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20951                            // If the other app is cached for any reason, for purposes here
20952                            // we are going to consider it empty.  The specific cached state
20953                            // doesn't propagate except under certain conditions.
20954                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20955                        }
20956                        String adjType = null;
20957                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
20958                            // Not doing bind OOM management, so treat
20959                            // this guy more like a started service.
20960                            if (app.hasShownUi && app != mHomeProcess) {
20961                                // If this process has shown some UI, let it immediately
20962                                // go to the LRU list because it may be pretty heavy with
20963                                // UI stuff.  We'll tag it with a label just to help
20964                                // debug and understand what is going on.
20965                                if (adj > clientAdj) {
20966                                    adjType = "cch-bound-ui-services";
20967                                }
20968                                app.cached = false;
20969                                clientAdj = adj;
20970                                clientProcState = procState;
20971                            } else {
20972                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
20973                                    // This service has not seen activity within
20974                                    // recent memory, so allow it to drop to the
20975                                    // LRU list if there is no other reason to keep
20976                                    // it around.  We'll also tag it with a label just
20977                                    // to help debug and undertand what is going on.
20978                                    if (adj > clientAdj) {
20979                                        adjType = "cch-bound-services";
20980                                    }
20981                                    clientAdj = adj;
20982                                }
20983                            }
20984                        }
20985                        if (adj > clientAdj) {
20986                            // If this process has recently shown UI, and
20987                            // the process that is binding to it is less
20988                            // important than being visible, then we don't
20989                            // care about the binding as much as we care
20990                            // about letting this process get into the LRU
20991                            // list to be killed and restarted if needed for
20992                            // memory.
20993                            if (app.hasShownUi && app != mHomeProcess
20994                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20995                                adjType = "cch-bound-ui-services";
20996                            } else {
20997                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
20998                                        |Context.BIND_IMPORTANT)) != 0) {
20999                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21000                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21001                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21002                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21003                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21004                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21005                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21006                                    adj = clientAdj;
21007                                } else {
21008                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
21009                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21010                                    }
21011                                }
21012                                if (!client.cached) {
21013                                    app.cached = false;
21014                                }
21015                                adjType = "service";
21016                            }
21017                        }
21018                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21019                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21020                            // This will treat important bound services identically to
21021                            // the top app, which may behave differently than generic
21022                            // foreground work.
21023                            if (client.curSchedGroup > schedGroup) {
21024                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21025                                    schedGroup = client.curSchedGroup;
21026                                } else {
21027                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21028                                }
21029                            }
21030                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21031                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21032                                    // Special handling of clients who are in the top state.
21033                                    // We *may* want to consider this process to be in the
21034                                    // top state as well, but only if there is not another
21035                                    // reason for it to be running.  Being on the top is a
21036                                    // special state, meaning you are specifically running
21037                                    // for the current top app.  If the process is already
21038                                    // running in the background for some other reason, it
21039                                    // is more important to continue considering it to be
21040                                    // in the background state.
21041                                    mayBeTop = true;
21042                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21043                                } else {
21044                                    // Special handling for above-top states (persistent
21045                                    // processes).  These should not bring the current process
21046                                    // into the top state, since they are not on top.  Instead
21047                                    // give them the best state after that.
21048                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21049                                        clientProcState =
21050                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21051                                    } else if (mWakefulness
21052                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21053                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21054                                                    != 0) {
21055                                        clientProcState =
21056                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21057                                    } else {
21058                                        clientProcState =
21059                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21060                                    }
21061                                }
21062                            }
21063                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21064                            if (clientProcState <
21065                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21066                                clientProcState =
21067                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21068                            }
21069                        } else {
21070                            if (clientProcState <
21071                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21072                                clientProcState =
21073                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21074                            }
21075                        }
21076                        if (procState > clientProcState) {
21077                            procState = clientProcState;
21078                        }
21079                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21080                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21081                            app.pendingUiClean = true;
21082                        }
21083                        if (adjType != null) {
21084                            app.adjType = adjType;
21085                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21086                                    .REASON_SERVICE_IN_USE;
21087                            app.adjSource = cr.binding.client;
21088                            app.adjSourceProcState = clientProcState;
21089                            app.adjTarget = s.name;
21090                        }
21091                    }
21092                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21093                        app.treatLikeActivity = true;
21094                    }
21095                    final ActivityRecord a = cr.activity;
21096                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21097                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21098                            (a.visible || a.state == ActivityState.RESUMED ||
21099                             a.state == ActivityState.PAUSING)) {
21100                            adj = ProcessList.FOREGROUND_APP_ADJ;
21101                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21102                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21103                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21104                                } else {
21105                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21106                                }
21107                            }
21108                            app.cached = false;
21109                            app.adjType = "service";
21110                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21111                                    .REASON_SERVICE_IN_USE;
21112                            app.adjSource = a;
21113                            app.adjSourceProcState = procState;
21114                            app.adjTarget = s.name;
21115                        }
21116                    }
21117                }
21118            }
21119        }
21120
21121        for (int provi = app.pubProviders.size()-1;
21122                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21123                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21124                        || procState > ActivityManager.PROCESS_STATE_TOP);
21125                provi--) {
21126            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21127            for (int i = cpr.connections.size()-1;
21128                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21129                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21130                            || procState > ActivityManager.PROCESS_STATE_TOP);
21131                    i--) {
21132                ContentProviderConnection conn = cpr.connections.get(i);
21133                ProcessRecord client = conn.client;
21134                if (client == app) {
21135                    // Being our own client is not interesting.
21136                    continue;
21137                }
21138                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21139                int clientProcState = client.curProcState;
21140                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21141                    // If the other app is cached for any reason, for purposes here
21142                    // we are going to consider it empty.
21143                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21144                }
21145                if (adj > clientAdj) {
21146                    if (app.hasShownUi && app != mHomeProcess
21147                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21148                        app.adjType = "cch-ui-provider";
21149                    } else {
21150                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21151                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21152                        app.adjType = "provider";
21153                    }
21154                    app.cached &= client.cached;
21155                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21156                            .REASON_PROVIDER_IN_USE;
21157                    app.adjSource = client;
21158                    app.adjSourceProcState = clientProcState;
21159                    app.adjTarget = cpr.name;
21160                }
21161                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21162                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21163                        // Special handling of clients who are in the top state.
21164                        // We *may* want to consider this process to be in the
21165                        // top state as well, but only if there is not another
21166                        // reason for it to be running.  Being on the top is a
21167                        // special state, meaning you are specifically running
21168                        // for the current top app.  If the process is already
21169                        // running in the background for some other reason, it
21170                        // is more important to continue considering it to be
21171                        // in the background state.
21172                        mayBeTop = true;
21173                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21174                    } else {
21175                        // Special handling for above-top states (persistent
21176                        // processes).  These should not bring the current process
21177                        // into the top state, since they are not on top.  Instead
21178                        // give them the best state after that.
21179                        clientProcState =
21180                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21181                    }
21182                }
21183                if (procState > clientProcState) {
21184                    procState = clientProcState;
21185                }
21186                if (client.curSchedGroup > schedGroup) {
21187                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21188                }
21189            }
21190            // If the provider has external (non-framework) process
21191            // dependencies, ensure that its adjustment is at least
21192            // FOREGROUND_APP_ADJ.
21193            if (cpr.hasExternalProcessHandles()) {
21194                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21195                    adj = ProcessList.FOREGROUND_APP_ADJ;
21196                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21197                    app.cached = false;
21198                    app.adjType = "provider";
21199                    app.adjTarget = cpr.name;
21200                }
21201                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21202                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21203                }
21204            }
21205        }
21206
21207        if (app.lastProviderTime > 0 &&
21208                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21209            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21210                adj = ProcessList.PREVIOUS_APP_ADJ;
21211                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21212                app.cached = false;
21213                app.adjType = "provider";
21214            }
21215            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21216                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21217            }
21218        }
21219
21220        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21221            // A client of one of our services or providers is in the top state.  We
21222            // *may* want to be in the top state, but not if we are already running in
21223            // the background for some other reason.  For the decision here, we are going
21224            // to pick out a few specific states that we want to remain in when a client
21225            // is top (states that tend to be longer-term) and otherwise allow it to go
21226            // to the top state.
21227            switch (procState) {
21228                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21229                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21230                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21231                case ActivityManager.PROCESS_STATE_SERVICE:
21232                    // These all are longer-term states, so pull them up to the top
21233                    // of the background states, but not all the way to the top state.
21234                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21235                    break;
21236                default:
21237                    // Otherwise, top is a better choice, so take it.
21238                    procState = ActivityManager.PROCESS_STATE_TOP;
21239                    break;
21240            }
21241        }
21242
21243        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21244            if (app.hasClientActivities) {
21245                // This is a cached process, but with client activities.  Mark it so.
21246                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21247                app.adjType = "cch-client-act";
21248            } else if (app.treatLikeActivity) {
21249                // This is a cached process, but somebody wants us to treat it like it has
21250                // an activity, okay!
21251                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21252                app.adjType = "cch-as-act";
21253            }
21254        }
21255
21256        if (adj == ProcessList.SERVICE_ADJ) {
21257            if (doingAll) {
21258                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21259                mNewNumServiceProcs++;
21260                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21261                if (!app.serviceb) {
21262                    // This service isn't far enough down on the LRU list to
21263                    // normally be a B service, but if we are low on RAM and it
21264                    // is large we want to force it down since we would prefer to
21265                    // keep launcher over it.
21266                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21267                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21268                        app.serviceHighRam = true;
21269                        app.serviceb = true;
21270                        //Slog.i(TAG, "ADJ " + app + " high ram!");
21271                    } else {
21272                        mNewNumAServiceProcs++;
21273                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
21274                    }
21275                } else {
21276                    app.serviceHighRam = false;
21277                }
21278            }
21279            if (app.serviceb) {
21280                adj = ProcessList.SERVICE_B_ADJ;
21281            }
21282        }
21283
21284        app.curRawAdj = adj;
21285
21286        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21287        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21288        if (adj > app.maxAdj) {
21289            adj = app.maxAdj;
21290            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21291                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21292            }
21293        }
21294
21295        // Do final modification to adj.  Everything we do between here and applying
21296        // the final setAdj must be done in this function, because we will also use
21297        // it when computing the final cached adj later.  Note that we don't need to
21298        // worry about this for max adj above, since max adj will always be used to
21299        // keep it out of the cached vaues.
21300        app.curAdj = app.modifyRawOomAdj(adj);
21301        app.curSchedGroup = schedGroup;
21302        app.curProcState = procState;
21303        app.foregroundActivities = foregroundActivities;
21304
21305        return app.curRawAdj;
21306    }
21307
21308    /**
21309     * Record new PSS sample for a process.
21310     */
21311    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21312            long now) {
21313        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21314                swapPss * 1024);
21315        proc.lastPssTime = now;
21316        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21317        if (DEBUG_PSS) Slog.d(TAG_PSS,
21318                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21319                + " state=" + ProcessList.makeProcStateString(procState));
21320        if (proc.initialIdlePss == 0) {
21321            proc.initialIdlePss = pss;
21322        }
21323        proc.lastPss = pss;
21324        proc.lastSwapPss = swapPss;
21325        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21326            proc.lastCachedPss = pss;
21327            proc.lastCachedSwapPss = swapPss;
21328        }
21329
21330        final SparseArray<Pair<Long, String>> watchUids
21331                = mMemWatchProcesses.getMap().get(proc.processName);
21332        Long check = null;
21333        if (watchUids != null) {
21334            Pair<Long, String> val = watchUids.get(proc.uid);
21335            if (val == null) {
21336                val = watchUids.get(0);
21337            }
21338            if (val != null) {
21339                check = val.first;
21340            }
21341        }
21342        if (check != null) {
21343            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21344                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21345                if (!isDebuggable) {
21346                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21347                        isDebuggable = true;
21348                    }
21349                }
21350                if (isDebuggable) {
21351                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21352                    final ProcessRecord myProc = proc;
21353                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
21354                    mMemWatchDumpProcName = proc.processName;
21355                    mMemWatchDumpFile = heapdumpFile.toString();
21356                    mMemWatchDumpPid = proc.pid;
21357                    mMemWatchDumpUid = proc.uid;
21358                    BackgroundThread.getHandler().post(new Runnable() {
21359                        @Override
21360                        public void run() {
21361                            revokeUriPermission(ActivityThread.currentActivityThread()
21362                                            .getApplicationThread(),
21363                                    null, DumpHeapActivity.JAVA_URI,
21364                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
21365                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21366                                    UserHandle.myUserId());
21367                            ParcelFileDescriptor fd = null;
21368                            try {
21369                                heapdumpFile.delete();
21370                                fd = ParcelFileDescriptor.open(heapdumpFile,
21371                                        ParcelFileDescriptor.MODE_CREATE |
21372                                                ParcelFileDescriptor.MODE_TRUNCATE |
21373                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
21374                                                ParcelFileDescriptor.MODE_APPEND);
21375                                IApplicationThread thread = myProc.thread;
21376                                if (thread != null) {
21377                                    try {
21378                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
21379                                                "Requesting dump heap from "
21380                                                + myProc + " to " + heapdumpFile);
21381                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
21382                                    } catch (RemoteException e) {
21383                                    }
21384                                }
21385                            } catch (FileNotFoundException e) {
21386                                e.printStackTrace();
21387                            } finally {
21388                                if (fd != null) {
21389                                    try {
21390                                        fd.close();
21391                                    } catch (IOException e) {
21392                                    }
21393                                }
21394                            }
21395                        }
21396                    });
21397                } else {
21398                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21399                            + ", but debugging not enabled");
21400                }
21401            }
21402        }
21403    }
21404
21405    /**
21406     * Schedule PSS collection of a process.
21407     */
21408    void requestPssLocked(ProcessRecord proc, int procState) {
21409        if (mPendingPssProcesses.contains(proc)) {
21410            return;
21411        }
21412        if (mPendingPssProcesses.size() == 0) {
21413            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21414        }
21415        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21416        proc.pssProcState = procState;
21417        mPendingPssProcesses.add(proc);
21418    }
21419
21420    /**
21421     * Schedule PSS collection of all processes.
21422     */
21423    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21424        if (!always) {
21425            if (now < (mLastFullPssTime +
21426                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21427                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
21428                return;
21429            }
21430        }
21431        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21432        mLastFullPssTime = now;
21433        mFullPssPending = true;
21434        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21435        mPendingPssProcesses.clear();
21436        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21437            ProcessRecord app = mLruProcesses.get(i);
21438            if (app.thread == null
21439                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21440                continue;
21441            }
21442            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21443                app.pssProcState = app.setProcState;
21444                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21445                        mTestPssMode, isSleepingLocked(), now);
21446                mPendingPssProcesses.add(app);
21447            }
21448        }
21449        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21450    }
21451
21452    public void setTestPssMode(boolean enabled) {
21453        synchronized (this) {
21454            mTestPssMode = enabled;
21455            if (enabled) {
21456                // Whenever we enable the mode, we want to take a snapshot all of current
21457                // process mem use.
21458                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21459            }
21460        }
21461    }
21462
21463    /**
21464     * Ask a given process to GC right now.
21465     */
21466    final void performAppGcLocked(ProcessRecord app) {
21467        try {
21468            app.lastRequestedGc = SystemClock.uptimeMillis();
21469            if (app.thread != null) {
21470                if (app.reportLowMemory) {
21471                    app.reportLowMemory = false;
21472                    app.thread.scheduleLowMemory();
21473                } else {
21474                    app.thread.processInBackground();
21475                }
21476            }
21477        } catch (Exception e) {
21478            // whatever.
21479        }
21480    }
21481
21482    /**
21483     * Returns true if things are idle enough to perform GCs.
21484     */
21485    private final boolean canGcNowLocked() {
21486        boolean processingBroadcasts = false;
21487        for (BroadcastQueue q : mBroadcastQueues) {
21488            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21489                processingBroadcasts = true;
21490            }
21491        }
21492        return !processingBroadcasts
21493                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21494    }
21495
21496    /**
21497     * Perform GCs on all processes that are waiting for it, but only
21498     * if things are idle.
21499     */
21500    final void performAppGcsLocked() {
21501        final int N = mProcessesToGc.size();
21502        if (N <= 0) {
21503            return;
21504        }
21505        if (canGcNowLocked()) {
21506            while (mProcessesToGc.size() > 0) {
21507                ProcessRecord proc = mProcessesToGc.remove(0);
21508                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21509                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21510                            <= SystemClock.uptimeMillis()) {
21511                        // To avoid spamming the system, we will GC processes one
21512                        // at a time, waiting a few seconds between each.
21513                        performAppGcLocked(proc);
21514                        scheduleAppGcsLocked();
21515                        return;
21516                    } else {
21517                        // It hasn't been long enough since we last GCed this
21518                        // process...  put it in the list to wait for its time.
21519                        addProcessToGcListLocked(proc);
21520                        break;
21521                    }
21522                }
21523            }
21524
21525            scheduleAppGcsLocked();
21526        }
21527    }
21528
21529    /**
21530     * If all looks good, perform GCs on all processes waiting for them.
21531     */
21532    final void performAppGcsIfAppropriateLocked() {
21533        if (canGcNowLocked()) {
21534            performAppGcsLocked();
21535            return;
21536        }
21537        // Still not idle, wait some more.
21538        scheduleAppGcsLocked();
21539    }
21540
21541    /**
21542     * Schedule the execution of all pending app GCs.
21543     */
21544    final void scheduleAppGcsLocked() {
21545        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21546
21547        if (mProcessesToGc.size() > 0) {
21548            // Schedule a GC for the time to the next process.
21549            ProcessRecord proc = mProcessesToGc.get(0);
21550            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21551
21552            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21553            long now = SystemClock.uptimeMillis();
21554            if (when < (now+mConstants.GC_TIMEOUT)) {
21555                when = now + mConstants.GC_TIMEOUT;
21556            }
21557            mHandler.sendMessageAtTime(msg, when);
21558        }
21559    }
21560
21561    /**
21562     * Add a process to the array of processes waiting to be GCed.  Keeps the
21563     * list in sorted order by the last GC time.  The process can't already be
21564     * on the list.
21565     */
21566    final void addProcessToGcListLocked(ProcessRecord proc) {
21567        boolean added = false;
21568        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21569            if (mProcessesToGc.get(i).lastRequestedGc <
21570                    proc.lastRequestedGc) {
21571                added = true;
21572                mProcessesToGc.add(i+1, proc);
21573                break;
21574            }
21575        }
21576        if (!added) {
21577            mProcessesToGc.add(0, proc);
21578        }
21579    }
21580
21581    /**
21582     * Set up to ask a process to GC itself.  This will either do it
21583     * immediately, or put it on the list of processes to gc the next
21584     * time things are idle.
21585     */
21586    final void scheduleAppGcLocked(ProcessRecord app) {
21587        long now = SystemClock.uptimeMillis();
21588        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21589            return;
21590        }
21591        if (!mProcessesToGc.contains(app)) {
21592            addProcessToGcListLocked(app);
21593            scheduleAppGcsLocked();
21594        }
21595    }
21596
21597    final void checkExcessivePowerUsageLocked(boolean doKills) {
21598        updateCpuStatsNow();
21599
21600        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21601        boolean doWakeKills = doKills;
21602        boolean doCpuKills = doKills;
21603        if (mLastPowerCheckRealtime == 0) {
21604            doWakeKills = false;
21605        }
21606        if (mLastPowerCheckUptime == 0) {
21607            doCpuKills = false;
21608        }
21609        if (stats.isScreenOn()) {
21610            doWakeKills = false;
21611        }
21612        final long curRealtime = SystemClock.elapsedRealtime();
21613        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21614        final long curUptime = SystemClock.uptimeMillis();
21615        final long uptimeSince = curUptime - mLastPowerCheckUptime;
21616        mLastPowerCheckRealtime = curRealtime;
21617        mLastPowerCheckUptime = curUptime;
21618        if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) {
21619            doWakeKills = false;
21620        }
21621        if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) {
21622            doCpuKills = false;
21623        }
21624        int i = mLruProcesses.size();
21625        while (i > 0) {
21626            i--;
21627            ProcessRecord app = mLruProcesses.get(i);
21628            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21629                long wtime;
21630                synchronized (stats) {
21631                    wtime = stats.getProcessWakeTime(app.info.uid,
21632                            app.pid, curRealtime);
21633                }
21634                long wtimeUsed = wtime - app.lastWakeTime;
21635                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21636                if (DEBUG_POWER) {
21637                    StringBuilder sb = new StringBuilder(128);
21638                    sb.append("Wake for ");
21639                    app.toShortString(sb);
21640                    sb.append(": over ");
21641                    TimeUtils.formatDuration(realtimeSince, sb);
21642                    sb.append(" used ");
21643                    TimeUtils.formatDuration(wtimeUsed, sb);
21644                    sb.append(" (");
21645                    sb.append((wtimeUsed*100)/realtimeSince);
21646                    sb.append("%)");
21647                    Slog.i(TAG_POWER, sb.toString());
21648                    sb.setLength(0);
21649                    sb.append("CPU for ");
21650                    app.toShortString(sb);
21651                    sb.append(": over ");
21652                    TimeUtils.formatDuration(uptimeSince, sb);
21653                    sb.append(" used ");
21654                    TimeUtils.formatDuration(cputimeUsed, sb);
21655                    sb.append(" (");
21656                    sb.append((cputimeUsed*100)/uptimeSince);
21657                    sb.append("%)");
21658                    Slog.i(TAG_POWER, sb.toString());
21659                }
21660                // If a process has held a wake lock for more
21661                // than 50% of the time during this period,
21662                // that sounds bad.  Kill!
21663                if (doWakeKills && realtimeSince > 0
21664                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
21665                    synchronized (stats) {
21666                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21667                                realtimeSince, wtimeUsed);
21668                    }
21669                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21670                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21671                } else if (doCpuKills && uptimeSince > 0
21672                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
21673                    synchronized (stats) {
21674                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21675                                uptimeSince, cputimeUsed);
21676                    }
21677                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21678                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21679                } else {
21680                    app.lastWakeTime = wtime;
21681                    app.lastCpuTime = app.curCpuTime;
21682                }
21683            }
21684        }
21685    }
21686
21687    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21688            long nowElapsed) {
21689        boolean success = true;
21690
21691        if (app.curRawAdj != app.setRawAdj) {
21692            app.setRawAdj = app.curRawAdj;
21693        }
21694
21695        int changes = 0;
21696
21697        if (app.curAdj != app.setAdj) {
21698            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21699            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21700                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21701                    + app.adjType);
21702            app.setAdj = app.curAdj;
21703            app.verifiedAdj = ProcessList.INVALID_ADJ;
21704        }
21705
21706        if (app.setSchedGroup != app.curSchedGroup) {
21707            int oldSchedGroup = app.setSchedGroup;
21708            app.setSchedGroup = app.curSchedGroup;
21709            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21710                    "Setting sched group of " + app.processName
21711                    + " to " + app.curSchedGroup);
21712            if (app.waitingToKill != null && app.curReceivers.isEmpty()
21713                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21714                app.kill(app.waitingToKill, true);
21715                success = false;
21716            } else {
21717                int processGroup;
21718                switch (app.curSchedGroup) {
21719                    case ProcessList.SCHED_GROUP_BACKGROUND:
21720                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21721                        break;
21722                    case ProcessList.SCHED_GROUP_TOP_APP:
21723                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21724                        processGroup = THREAD_GROUP_TOP_APP;
21725                        break;
21726                    default:
21727                        processGroup = THREAD_GROUP_DEFAULT;
21728                        break;
21729                }
21730                long oldId = Binder.clearCallingIdentity();
21731                try {
21732                    setProcessGroup(app.pid, processGroup);
21733                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21734                        // do nothing if we already switched to RT
21735                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21736                            mVrController.onTopProcChangedLocked(app);
21737                            if (mUseFifoUiScheduling) {
21738                                // Switch UI pipeline for app to SCHED_FIFO
21739                                app.savedPriority = Process.getThreadPriority(app.pid);
21740                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
21741                                if (app.renderThreadTid != 0) {
21742                                    scheduleAsFifoPriority(app.renderThreadTid,
21743                                        /* suppressLogs */true);
21744                                    if (DEBUG_OOM_ADJ) {
21745                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
21746                                            app.renderThreadTid + ") to FIFO");
21747                                    }
21748                                } else {
21749                                    if (DEBUG_OOM_ADJ) {
21750                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
21751                                    }
21752                                }
21753                            } else {
21754                                // Boost priority for top app UI and render threads
21755                                setThreadPriority(app.pid, -10);
21756                                if (app.renderThreadTid != 0) {
21757                                    try {
21758                                        setThreadPriority(app.renderThreadTid, -10);
21759                                    } catch (IllegalArgumentException e) {
21760                                        // thread died, ignore
21761                                    }
21762                                }
21763                            }
21764                        }
21765                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
21766                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21767                        mVrController.onTopProcChangedLocked(app);
21768                        if (mUseFifoUiScheduling) {
21769                            // Reset UI pipeline to SCHED_OTHER
21770                            setThreadScheduler(app.pid, SCHED_OTHER, 0);
21771                            setThreadPriority(app.pid, app.savedPriority);
21772                            if (app.renderThreadTid != 0) {
21773                                setThreadScheduler(app.renderThreadTid,
21774                                    SCHED_OTHER, 0);
21775                                setThreadPriority(app.renderThreadTid, -4);
21776                            }
21777                        } else {
21778                            // Reset priority for top app UI and render threads
21779                            setThreadPriority(app.pid, 0);
21780                            if (app.renderThreadTid != 0) {
21781                                setThreadPriority(app.renderThreadTid, 0);
21782                            }
21783                        }
21784                    }
21785                } catch (Exception e) {
21786                    if (false) {
21787                        Slog.w(TAG, "Failed setting process group of " + app.pid
21788                                + " to " + app.curSchedGroup);
21789                        Slog.w(TAG, "at location", e);
21790                    }
21791                } finally {
21792                    Binder.restoreCallingIdentity(oldId);
21793                }
21794            }
21795        }
21796        if (app.repForegroundActivities != app.foregroundActivities) {
21797            app.repForegroundActivities = app.foregroundActivities;
21798            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
21799        }
21800        if (app.repProcState != app.curProcState) {
21801            app.repProcState = app.curProcState;
21802            if (app.thread != null) {
21803                try {
21804                    if (false) {
21805                        //RuntimeException h = new RuntimeException("here");
21806                        Slog.i(TAG, "Sending new process state " + app.repProcState
21807                                + " to " + app /*, h*/);
21808                    }
21809                    app.thread.setProcessState(app.repProcState);
21810                } catch (RemoteException e) {
21811                }
21812            }
21813        }
21814        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
21815                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
21816            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
21817                // Experimental code to more aggressively collect pss while
21818                // running test...  the problem is that this tends to collect
21819                // the data right when a process is transitioning between process
21820                // states, which well tend to give noisy data.
21821                long start = SystemClock.uptimeMillis();
21822                long pss = Debug.getPss(app.pid, mTmpLong, null);
21823                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
21824                mPendingPssProcesses.remove(app);
21825                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
21826                        + " to " + app.curProcState + ": "
21827                        + (SystemClock.uptimeMillis()-start) + "ms");
21828            }
21829            app.lastStateTime = now;
21830            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21831                    mTestPssMode, isSleepingLocked(), now);
21832            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
21833                    + ProcessList.makeProcStateString(app.setProcState) + " to "
21834                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
21835                    + (app.nextPssTime-now) + ": " + app);
21836        } else {
21837            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
21838                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
21839                    mTestPssMode)))) {
21840                requestPssLocked(app, app.setProcState);
21841                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
21842                        mTestPssMode, isSleepingLocked(), now);
21843            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
21844                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
21845        }
21846        if (app.setProcState != app.curProcState) {
21847            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21848                    "Proc state change of " + app.processName
21849                            + " to " + app.curProcState);
21850            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
21851            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
21852            if (setImportant && !curImportant) {
21853                // This app is no longer something we consider important enough to allow to
21854                // use arbitrary amounts of battery power.  Note
21855                // its current wake lock time to later know to kill it if
21856                // it is not behaving well.
21857                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21858                synchronized (stats) {
21859                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
21860                            app.pid, nowElapsed);
21861                }
21862                app.lastCpuTime = app.curCpuTime;
21863
21864            }
21865            // Inform UsageStats of important process state change
21866            // Must be called before updating setProcState
21867            maybeUpdateUsageStatsLocked(app, nowElapsed);
21868
21869            app.setProcState = app.curProcState;
21870            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21871                app.notCachedSinceIdle = false;
21872            }
21873            if (!doingAll) {
21874                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
21875            } else {
21876                app.procStateChanged = true;
21877            }
21878        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
21879                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
21880            // For apps that sit around for a long time in the interactive state, we need
21881            // to report this at least once a day so they don't go idle.
21882            maybeUpdateUsageStatsLocked(app, nowElapsed);
21883        }
21884
21885        if (changes != 0) {
21886            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21887                    "Changes in " + app + ": " + changes);
21888            int i = mPendingProcessChanges.size()-1;
21889            ProcessChangeItem item = null;
21890            while (i >= 0) {
21891                item = mPendingProcessChanges.get(i);
21892                if (item.pid == app.pid) {
21893                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21894                            "Re-using existing item: " + item);
21895                    break;
21896                }
21897                i--;
21898            }
21899            if (i < 0) {
21900                // No existing item in pending changes; need a new one.
21901                final int NA = mAvailProcessChanges.size();
21902                if (NA > 0) {
21903                    item = mAvailProcessChanges.remove(NA-1);
21904                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21905                            "Retrieving available item: " + item);
21906                } else {
21907                    item = new ProcessChangeItem();
21908                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21909                            "Allocating new item: " + item);
21910                }
21911                item.changes = 0;
21912                item.pid = app.pid;
21913                item.uid = app.info.uid;
21914                if (mPendingProcessChanges.size() == 0) {
21915                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21916                            "*** Enqueueing dispatch processes changed!");
21917                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
21918                }
21919                mPendingProcessChanges.add(item);
21920            }
21921            item.changes |= changes;
21922            item.foregroundActivities = app.repForegroundActivities;
21923            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21924                    "Item " + Integer.toHexString(System.identityHashCode(item))
21925                    + " " + app.toShortString() + ": changes=" + item.changes
21926                    + " foreground=" + item.foregroundActivities
21927                    + " type=" + app.adjType + " source=" + app.adjSource
21928                    + " target=" + app.adjTarget);
21929        }
21930
21931        return success;
21932    }
21933
21934    private boolean isEphemeralLocked(int uid) {
21935        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
21936        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
21937            return false;
21938        }
21939        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
21940                packages[0]);
21941    }
21942
21943    @VisibleForTesting
21944    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
21945        final UidRecord.ChangeItem pendingChange;
21946        if (uidRec == null || uidRec.pendingChange == null) {
21947            if (mPendingUidChanges.size() == 0) {
21948                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21949                        "*** Enqueueing dispatch uid changed!");
21950                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
21951            }
21952            final int NA = mAvailUidChanges.size();
21953            if (NA > 0) {
21954                pendingChange = mAvailUidChanges.remove(NA-1);
21955                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21956                        "Retrieving available item: " + pendingChange);
21957            } else {
21958                pendingChange = new UidRecord.ChangeItem();
21959                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21960                        "Allocating new item: " + pendingChange);
21961            }
21962            if (uidRec != null) {
21963                uidRec.pendingChange = pendingChange;
21964                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
21965                    // If this uid is going away, and we haven't yet reported it is gone,
21966                    // then do so now.
21967                    change = UidRecord.CHANGE_GONE_IDLE;
21968                }
21969            } else if (uid < 0) {
21970                throw new IllegalArgumentException("No UidRecord or uid");
21971            }
21972            pendingChange.uidRecord = uidRec;
21973            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
21974            mPendingUidChanges.add(pendingChange);
21975        } else {
21976            pendingChange = uidRec.pendingChange;
21977            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
21978                change = UidRecord.CHANGE_GONE_IDLE;
21979            }
21980        }
21981        pendingChange.change = change;
21982        pendingChange.processState = uidRec != null
21983                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
21984        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
21985        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
21986        if (uidRec != null) {
21987            uidRec.updateLastDispatchedProcStateSeq(change);
21988        }
21989
21990        // Directly update the power manager, since we sit on top of it and it is critical
21991        // it be kept in sync (so wake locks will be held as soon as appropriate).
21992        if (mLocalPowerManager != null) {
21993            switch (change) {
21994                case UidRecord.CHANGE_GONE:
21995                case UidRecord.CHANGE_GONE_IDLE:
21996                    mLocalPowerManager.uidGone(pendingChange.uid);
21997                    break;
21998                case UidRecord.CHANGE_IDLE:
21999                    mLocalPowerManager.uidIdle(pendingChange.uid);
22000                    break;
22001                case UidRecord.CHANGE_ACTIVE:
22002                    mLocalPowerManager.uidActive(pendingChange.uid);
22003                    break;
22004                default:
22005                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
22006                            pendingChange.processState);
22007                    break;
22008            }
22009        }
22010    }
22011
22012    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22013            String authority) {
22014        if (app == null) return;
22015        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22016            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22017            if (userState == null) return;
22018            final long now = SystemClock.elapsedRealtime();
22019            Long lastReported = userState.mProviderLastReportedFg.get(authority);
22020            if (lastReported == null || lastReported < now - 60 * 1000L) {
22021                if (mSystemReady) {
22022                    // Cannot touch the user stats if not system ready
22023                    mUsageStatsService.reportContentProviderUsage(
22024                            authority, providerPkgName, app.userId);
22025                }
22026                userState.mProviderLastReportedFg.put(authority, now);
22027            }
22028        }
22029    }
22030
22031    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22032        if (DEBUG_USAGE_STATS) {
22033            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22034                    + "] state changes: old = " + app.setProcState + ", new = "
22035                    + app.curProcState);
22036        }
22037        if (mUsageStatsService == null) {
22038            return;
22039        }
22040        boolean isInteraction;
22041        // To avoid some abuse patterns, we are going to be careful about what we consider
22042        // to be an app interaction.  Being the top activity doesn't count while the display
22043        // is sleeping, nor do short foreground services.
22044        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22045            isInteraction = true;
22046            app.fgInteractionTime = 0;
22047        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22048            if (app.fgInteractionTime == 0) {
22049                app.fgInteractionTime = nowElapsed;
22050                isInteraction = false;
22051            } else {
22052                isInteraction = nowElapsed > app.fgInteractionTime
22053                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22054            }
22055        } else {
22056            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22057            app.fgInteractionTime = 0;
22058        }
22059        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22060                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22061            app.interactionEventTime = nowElapsed;
22062            String[] packages = app.getPackageList();
22063            if (packages != null) {
22064                for (int i = 0; i < packages.length; i++) {
22065                    mUsageStatsService.reportEvent(packages[i], app.userId,
22066                            UsageEvents.Event.SYSTEM_INTERACTION);
22067                }
22068            }
22069        }
22070        app.reportedInteraction = isInteraction;
22071        if (!isInteraction) {
22072            app.interactionEventTime = 0;
22073        }
22074    }
22075
22076    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22077        if (proc.thread != null) {
22078            if (proc.baseProcessTracker != null) {
22079                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22080            }
22081        }
22082    }
22083
22084    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22085            ProcessRecord TOP_APP, boolean doingAll, long now) {
22086        if (app.thread == null) {
22087            return false;
22088        }
22089
22090        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22091
22092        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22093    }
22094
22095    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22096            boolean oomAdj) {
22097        if (isForeground != proc.foregroundServices) {
22098            proc.foregroundServices = isForeground;
22099            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22100                    proc.info.uid);
22101            if (isForeground) {
22102                if (curProcs == null) {
22103                    curProcs = new ArrayList<ProcessRecord>();
22104                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22105                }
22106                if (!curProcs.contains(proc)) {
22107                    curProcs.add(proc);
22108                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22109                            proc.info.packageName, proc.info.uid);
22110                }
22111            } else {
22112                if (curProcs != null) {
22113                    if (curProcs.remove(proc)) {
22114                        mBatteryStatsService.noteEvent(
22115                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22116                                proc.info.packageName, proc.info.uid);
22117                        if (curProcs.size() <= 0) {
22118                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22119                        }
22120                    }
22121                }
22122            }
22123            if (oomAdj) {
22124                updateOomAdjLocked();
22125            }
22126        }
22127    }
22128
22129    private final ActivityRecord resumedAppLocked() {
22130        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22131        String pkg;
22132        int uid;
22133        if (act != null) {
22134            pkg = act.packageName;
22135            uid = act.info.applicationInfo.uid;
22136        } else {
22137            pkg = null;
22138            uid = -1;
22139        }
22140        // Has the UID or resumed package name changed?
22141        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22142                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22143            if (mCurResumedPackage != null) {
22144                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22145                        mCurResumedPackage, mCurResumedUid);
22146            }
22147            mCurResumedPackage = pkg;
22148            mCurResumedUid = uid;
22149            if (mCurResumedPackage != null) {
22150                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22151                        mCurResumedPackage, mCurResumedUid);
22152            }
22153        }
22154        return act;
22155    }
22156
22157    /**
22158     * Update OomAdj for a specific process.
22159     * @param app The process to update
22160     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22161     *                  if necessary, or skip.
22162     * @return whether updateOomAdjLocked(app) was successful.
22163     */
22164    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22165        final ActivityRecord TOP_ACT = resumedAppLocked();
22166        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22167        final boolean wasCached = app.cached;
22168
22169        mAdjSeq++;
22170
22171        // This is the desired cached adjusment we want to tell it to use.
22172        // If our app is currently cached, we know it, and that is it.  Otherwise,
22173        // we don't know it yet, and it needs to now be cached we will then
22174        // need to do a complete oom adj.
22175        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22176                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22177        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22178                SystemClock.uptimeMillis());
22179        if (oomAdjAll
22180                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22181            // Changed to/from cached state, so apps after it in the LRU
22182            // list may also be changed.
22183            updateOomAdjLocked();
22184        }
22185        return success;
22186    }
22187
22188    final void updateOomAdjLocked() {
22189        final ActivityRecord TOP_ACT = resumedAppLocked();
22190        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22191        final long now = SystemClock.uptimeMillis();
22192        final long nowElapsed = SystemClock.elapsedRealtime();
22193        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22194        final int N = mLruProcesses.size();
22195
22196        if (false) {
22197            RuntimeException e = new RuntimeException();
22198            e.fillInStackTrace();
22199            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22200        }
22201
22202        // Reset state in all uid records.
22203        for (int i=mActiveUids.size()-1; i>=0; i--) {
22204            final UidRecord uidRec = mActiveUids.valueAt(i);
22205            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22206                    "Starting update of " + uidRec);
22207            uidRec.reset();
22208        }
22209
22210        mStackSupervisor.rankTaskLayersIfNeeded();
22211
22212        mAdjSeq++;
22213        mNewNumServiceProcs = 0;
22214        mNewNumAServiceProcs = 0;
22215
22216        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22217        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22218
22219        // Let's determine how many processes we have running vs.
22220        // how many slots we have for background processes; we may want
22221        // to put multiple processes in a slot of there are enough of
22222        // them.
22223        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22224                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22225        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22226        if (numEmptyProcs > cachedProcessLimit) {
22227            // If there are more empty processes than our limit on cached
22228            // processes, then use the cached process limit for the factor.
22229            // This ensures that the really old empty processes get pushed
22230            // down to the bottom, so if we are running low on memory we will
22231            // have a better chance at keeping around more cached processes
22232            // instead of a gazillion empty processes.
22233            numEmptyProcs = cachedProcessLimit;
22234        }
22235        int emptyFactor = numEmptyProcs/numSlots;
22236        if (emptyFactor < 1) emptyFactor = 1;
22237        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22238        if (cachedFactor < 1) cachedFactor = 1;
22239        int stepCached = 0;
22240        int stepEmpty = 0;
22241        int numCached = 0;
22242        int numEmpty = 0;
22243        int numTrimming = 0;
22244
22245        mNumNonCachedProcs = 0;
22246        mNumCachedHiddenProcs = 0;
22247
22248        // First update the OOM adjustment for each of the
22249        // application processes based on their current state.
22250        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22251        int nextCachedAdj = curCachedAdj+1;
22252        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22253        int nextEmptyAdj = curEmptyAdj+2;
22254        for (int i=N-1; i>=0; i--) {
22255            ProcessRecord app = mLruProcesses.get(i);
22256            if (!app.killedByAm && app.thread != null) {
22257                app.procStateChanged = false;
22258                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22259
22260                // If we haven't yet assigned the final cached adj
22261                // to the process, do that now.
22262                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22263                    switch (app.curProcState) {
22264                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22265                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22266                            // This process is a cached process holding activities...
22267                            // assign it the next cached value for that type, and then
22268                            // step that cached level.
22269                            app.curRawAdj = curCachedAdj;
22270                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22271                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22272                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22273                                    + ")");
22274                            if (curCachedAdj != nextCachedAdj) {
22275                                stepCached++;
22276                                if (stepCached >= cachedFactor) {
22277                                    stepCached = 0;
22278                                    curCachedAdj = nextCachedAdj;
22279                                    nextCachedAdj += 2;
22280                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22281                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22282                                    }
22283                                }
22284                            }
22285                            break;
22286                        default:
22287                            // For everything else, assign next empty cached process
22288                            // level and bump that up.  Note that this means that
22289                            // long-running services that have dropped down to the
22290                            // cached level will be treated as empty (since their process
22291                            // state is still as a service), which is what we want.
22292                            app.curRawAdj = curEmptyAdj;
22293                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22294                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22295                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22296                                    + ")");
22297                            if (curEmptyAdj != nextEmptyAdj) {
22298                                stepEmpty++;
22299                                if (stepEmpty >= emptyFactor) {
22300                                    stepEmpty = 0;
22301                                    curEmptyAdj = nextEmptyAdj;
22302                                    nextEmptyAdj += 2;
22303                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22304                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22305                                    }
22306                                }
22307                            }
22308                            break;
22309                    }
22310                }
22311
22312                applyOomAdjLocked(app, true, now, nowElapsed);
22313
22314                // Count the number of process types.
22315                switch (app.curProcState) {
22316                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22317                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22318                        mNumCachedHiddenProcs++;
22319                        numCached++;
22320                        if (numCached > cachedProcessLimit) {
22321                            app.kill("cached #" + numCached, true);
22322                        }
22323                        break;
22324                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22325                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22326                                && app.lastActivityTime < oldTime) {
22327                            app.kill("empty for "
22328                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22329                                    / 1000) + "s", true);
22330                        } else {
22331                            numEmpty++;
22332                            if (numEmpty > emptyProcessLimit) {
22333                                app.kill("empty #" + numEmpty, true);
22334                            }
22335                        }
22336                        break;
22337                    default:
22338                        mNumNonCachedProcs++;
22339                        break;
22340                }
22341
22342                if (app.isolated && app.services.size() <= 0) {
22343                    // If this is an isolated process, and there are no
22344                    // services running in it, then the process is no longer
22345                    // needed.  We agressively kill these because we can by
22346                    // definition not re-use the same process again, and it is
22347                    // good to avoid having whatever code was running in them
22348                    // left sitting around after no longer needed.
22349                    app.kill("isolated not needed", true);
22350                } else {
22351                    // Keeping this process, update its uid.
22352                    final UidRecord uidRec = app.uidRecord;
22353                    if (uidRec != null) {
22354                        uidRec.ephemeral = app.info.isInstantApp();
22355                        if (uidRec.curProcState > app.curProcState) {
22356                            uidRec.curProcState = app.curProcState;
22357                        }
22358                        if (app.foregroundServices) {
22359                            uidRec.foregroundServices = true;
22360                        }
22361                    }
22362                }
22363
22364                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22365                        && !app.killedByAm) {
22366                    numTrimming++;
22367                }
22368            }
22369        }
22370
22371        incrementProcStateSeqAndNotifyAppsLocked();
22372
22373        mNumServiceProcs = mNewNumServiceProcs;
22374
22375        // Now determine the memory trimming level of background processes.
22376        // Unfortunately we need to start at the back of the list to do this
22377        // properly.  We only do this if the number of background apps we
22378        // are managing to keep around is less than half the maximum we desire;
22379        // if we are keeping a good number around, we'll let them use whatever
22380        // memory they want.
22381        final int numCachedAndEmpty = numCached + numEmpty;
22382        int memFactor;
22383        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22384                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22385            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22386                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22387            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22388                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22389            } else {
22390                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22391            }
22392        } else {
22393            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22394        }
22395        // We always allow the memory level to go up (better).  We only allow it to go
22396        // down if we are in a state where that is allowed, *and* the total number of processes
22397        // has gone down since last time.
22398        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22399                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22400                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22401        if (memFactor > mLastMemoryLevel) {
22402            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22403                memFactor = mLastMemoryLevel;
22404                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22405            }
22406        }
22407        if (memFactor != mLastMemoryLevel) {
22408            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22409        }
22410        mLastMemoryLevel = memFactor;
22411        mLastNumProcesses = mLruProcesses.size();
22412        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22413        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22414        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22415            if (mLowRamStartTime == 0) {
22416                mLowRamStartTime = now;
22417            }
22418            int step = 0;
22419            int fgTrimLevel;
22420            switch (memFactor) {
22421                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22422                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22423                    break;
22424                case ProcessStats.ADJ_MEM_FACTOR_LOW:
22425                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22426                    break;
22427                default:
22428                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22429                    break;
22430            }
22431            int factor = numTrimming/3;
22432            int minFactor = 2;
22433            if (mHomeProcess != null) minFactor++;
22434            if (mPreviousProcess != null) minFactor++;
22435            if (factor < minFactor) factor = minFactor;
22436            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22437            for (int i=N-1; i>=0; i--) {
22438                ProcessRecord app = mLruProcesses.get(i);
22439                if (allChanged || app.procStateChanged) {
22440                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22441                    app.procStateChanged = false;
22442                }
22443                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22444                        && !app.killedByAm) {
22445                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
22446                        try {
22447                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22448                                    "Trimming memory of " + app.processName + " to " + curLevel);
22449                            app.thread.scheduleTrimMemory(curLevel);
22450                        } catch (RemoteException e) {
22451                        }
22452                        if (false) {
22453                            // For now we won't do this; our memory trimming seems
22454                            // to be good enough at this point that destroying
22455                            // activities causes more harm than good.
22456                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22457                                    && app != mHomeProcess && app != mPreviousProcess) {
22458                                // Need to do this on its own message because the stack may not
22459                                // be in a consistent state at this point.
22460                                // For these apps we will also finish their activities
22461                                // to help them free memory.
22462                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22463                            }
22464                        }
22465                    }
22466                    app.trimMemoryLevel = curLevel;
22467                    step++;
22468                    if (step >= factor) {
22469                        step = 0;
22470                        switch (curLevel) {
22471                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22472                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22473                                break;
22474                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22475                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22476                                break;
22477                        }
22478                    }
22479                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22480                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22481                            && app.thread != null) {
22482                        try {
22483                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22484                                    "Trimming memory of heavy-weight " + app.processName
22485                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22486                            app.thread.scheduleTrimMemory(
22487                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22488                        } catch (RemoteException e) {
22489                        }
22490                    }
22491                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22492                } else {
22493                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22494                            || app.systemNoUi) && app.pendingUiClean) {
22495                        // If this application is now in the background and it
22496                        // had done UI, then give it the special trim level to
22497                        // have it free UI resources.
22498                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22499                        if (app.trimMemoryLevel < level && app.thread != null) {
22500                            try {
22501                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22502                                        "Trimming memory of bg-ui " + app.processName
22503                                        + " to " + level);
22504                                app.thread.scheduleTrimMemory(level);
22505                            } catch (RemoteException e) {
22506                            }
22507                        }
22508                        app.pendingUiClean = false;
22509                    }
22510                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22511                        try {
22512                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22513                                    "Trimming memory of fg " + app.processName
22514                                    + " to " + fgTrimLevel);
22515                            app.thread.scheduleTrimMemory(fgTrimLevel);
22516                        } catch (RemoteException e) {
22517                        }
22518                    }
22519                    app.trimMemoryLevel = fgTrimLevel;
22520                }
22521            }
22522        } else {
22523            if (mLowRamStartTime != 0) {
22524                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22525                mLowRamStartTime = 0;
22526            }
22527            for (int i=N-1; i>=0; i--) {
22528                ProcessRecord app = mLruProcesses.get(i);
22529                if (allChanged || app.procStateChanged) {
22530                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22531                    app.procStateChanged = false;
22532                }
22533                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22534                        || app.systemNoUi) && app.pendingUiClean) {
22535                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22536                            && app.thread != null) {
22537                        try {
22538                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22539                                    "Trimming memory of ui hidden " + app.processName
22540                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22541                            app.thread.scheduleTrimMemory(
22542                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22543                        } catch (RemoteException e) {
22544                        }
22545                    }
22546                    app.pendingUiClean = false;
22547                }
22548                app.trimMemoryLevel = 0;
22549            }
22550        }
22551
22552        if (mAlwaysFinishActivities) {
22553            // Need to do this on its own message because the stack may not
22554            // be in a consistent state at this point.
22555            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22556        }
22557
22558        if (allChanged) {
22559            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22560        }
22561
22562        // Update from any uid changes.
22563        if (mLocalPowerManager != null) {
22564            mLocalPowerManager.startUidChanges();
22565        }
22566        for (int i=mActiveUids.size()-1; i>=0; i--) {
22567            final UidRecord uidRec = mActiveUids.valueAt(i);
22568            int uidChange = UidRecord.CHANGE_PROCSTATE;
22569            if (uidRec.setProcState != uidRec.curProcState
22570                    || uidRec.setWhitelist != uidRec.curWhitelist) {
22571                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22572                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22573                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22574                        + " to " + uidRec.curWhitelist);
22575                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22576                        && !uidRec.curWhitelist) {
22577                    // UID is now in the background (and not on the temp whitelist).  Was it
22578                    // previously in the foreground (or on the temp whitelist)?
22579                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22580                            || uidRec.setWhitelist) {
22581                        uidRec.lastBackgroundTime = nowElapsed;
22582                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22583                            // Note: the background settle time is in elapsed realtime, while
22584                            // the handler time base is uptime.  All this means is that we may
22585                            // stop background uids later than we had intended, but that only
22586                            // happens because the device was sleeping so we are okay anyway.
22587                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22588                                    mConstants.BACKGROUND_SETTLE_TIME);
22589                        }
22590                    }
22591                } else {
22592                    if (uidRec.idle) {
22593                        uidChange = UidRecord.CHANGE_ACTIVE;
22594                        EventLogTags.writeAmUidActive(uidRec.uid);
22595                        uidRec.idle = false;
22596                    }
22597                    uidRec.lastBackgroundTime = 0;
22598                }
22599                uidRec.setProcState = uidRec.curProcState;
22600                uidRec.setWhitelist = uidRec.curWhitelist;
22601                enqueueUidChangeLocked(uidRec, -1, uidChange);
22602                noteUidProcessState(uidRec.uid, uidRec.curProcState);
22603                if (uidRec.foregroundServices) {
22604                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
22605                }
22606            }
22607        }
22608        if (mLocalPowerManager != null) {
22609            mLocalPowerManager.finishUidChanges();
22610        }
22611
22612        if (mProcessStats.shouldWriteNowLocked(now)) {
22613            mHandler.post(new Runnable() {
22614                @Override public void run() {
22615                    synchronized (ActivityManagerService.this) {
22616                        mProcessStats.writeStateAsyncLocked();
22617                    }
22618                }
22619            });
22620        }
22621
22622        if (DEBUG_OOM_ADJ) {
22623            final long duration = SystemClock.uptimeMillis() - now;
22624            if (false) {
22625                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22626                        new RuntimeException("here").fillInStackTrace());
22627            } else {
22628                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22629            }
22630        }
22631    }
22632
22633    @Override
22634    public void makePackageIdle(String packageName, int userId) {
22635        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22636                != PackageManager.PERMISSION_GRANTED) {
22637            String msg = "Permission Denial: makePackageIdle() from pid="
22638                    + Binder.getCallingPid()
22639                    + ", uid=" + Binder.getCallingUid()
22640                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22641            Slog.w(TAG, msg);
22642            throw new SecurityException(msg);
22643        }
22644        final int callingPid = Binder.getCallingPid();
22645        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22646                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22647        long callingId = Binder.clearCallingIdentity();
22648        synchronized(this) {
22649            try {
22650                IPackageManager pm = AppGlobals.getPackageManager();
22651                int pkgUid = -1;
22652                try {
22653                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22654                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22655                } catch (RemoteException e) {
22656                }
22657                if (pkgUid == -1) {
22658                    throw new IllegalArgumentException("Unknown package name " + packageName);
22659                }
22660
22661                if (mLocalPowerManager != null) {
22662                    mLocalPowerManager.startUidChanges();
22663                }
22664                final int appId = UserHandle.getAppId(pkgUid);
22665                final int N = mActiveUids.size();
22666                for (int i=N-1; i>=0; i--) {
22667                    final UidRecord uidRec = mActiveUids.valueAt(i);
22668                    final long bgTime = uidRec.lastBackgroundTime;
22669                    if (bgTime > 0 && !uidRec.idle) {
22670                        if (UserHandle.getAppId(uidRec.uid) == appId) {
22671                            if (userId == UserHandle.USER_ALL ||
22672                                    userId == UserHandle.getUserId(uidRec.uid)) {
22673                                EventLogTags.writeAmUidIdle(uidRec.uid);
22674                                uidRec.idle = true;
22675                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22676                                        + " from package " + packageName + " user " + userId);
22677                                doStopUidLocked(uidRec.uid, uidRec);
22678                            }
22679                        }
22680                    }
22681                }
22682            } finally {
22683                if (mLocalPowerManager != null) {
22684                    mLocalPowerManager.finishUidChanges();
22685                }
22686                Binder.restoreCallingIdentity(callingId);
22687            }
22688        }
22689    }
22690
22691    final void idleUids() {
22692        synchronized (this) {
22693            final int N = mActiveUids.size();
22694            if (N <= 0) {
22695                return;
22696            }
22697            final long nowElapsed = SystemClock.elapsedRealtime();
22698            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
22699            long nextTime = 0;
22700            if (mLocalPowerManager != null) {
22701                mLocalPowerManager.startUidChanges();
22702            }
22703            for (int i=N-1; i>=0; i--) {
22704                final UidRecord uidRec = mActiveUids.valueAt(i);
22705                final long bgTime = uidRec.lastBackgroundTime;
22706                if (bgTime > 0 && !uidRec.idle) {
22707                    if (bgTime <= maxBgTime) {
22708                        EventLogTags.writeAmUidIdle(uidRec.uid);
22709                        uidRec.idle = true;
22710                        doStopUidLocked(uidRec.uid, uidRec);
22711                    } else {
22712                        if (nextTime == 0 || nextTime > bgTime) {
22713                            nextTime = bgTime;
22714                        }
22715                    }
22716                }
22717            }
22718            if (mLocalPowerManager != null) {
22719                mLocalPowerManager.finishUidChanges();
22720            }
22721            if (nextTime > 0) {
22722                mHandler.removeMessages(IDLE_UIDS_MSG);
22723                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22724                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
22725            }
22726        }
22727    }
22728
22729    /**
22730     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
22731     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
22732     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
22733     */
22734    @VisibleForTesting
22735    @GuardedBy("this")
22736    void incrementProcStateSeqAndNotifyAppsLocked() {
22737        if (mWaitForNetworkTimeoutMs <= 0) {
22738            return;
22739        }
22740        // Used for identifying which uids need to block for network.
22741        ArrayList<Integer> blockingUids = null;
22742        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
22743            final UidRecord uidRec = mActiveUids.valueAt(i);
22744            // If the network is not restricted for uid, then nothing to do here.
22745            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
22746                continue;
22747            }
22748            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
22749                continue;
22750            }
22751            // If process state is not changed, then there's nothing to do.
22752            if (uidRec.setProcState == uidRec.curProcState) {
22753                continue;
22754            }
22755            final int blockState = getBlockStateForUid(uidRec);
22756            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
22757            // there's nothing the app needs to do in this scenario.
22758            if (blockState == NETWORK_STATE_NO_CHANGE) {
22759                continue;
22760            }
22761            synchronized (uidRec.networkStateLock) {
22762                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
22763                if (blockState == NETWORK_STATE_BLOCK) {
22764                    if (blockingUids == null) {
22765                        blockingUids = new ArrayList<>();
22766                    }
22767                    blockingUids.add(uidRec.uid);
22768                } else {
22769                    if (DEBUG_NETWORK) {
22770                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
22771                                + " threads for uid: " + uidRec);
22772                    }
22773                    if (uidRec.waitingForNetwork) {
22774                        uidRec.networkStateLock.notifyAll();
22775                    }
22776                }
22777            }
22778        }
22779
22780        // There are no uids that need to block, so nothing more to do.
22781        if (blockingUids == null) {
22782            return;
22783        }
22784
22785        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
22786            final ProcessRecord app = mLruProcesses.get(i);
22787            if (!blockingUids.contains(app.uid)) {
22788                continue;
22789            }
22790            if (!app.killedByAm && app.thread != null) {
22791                final UidRecord uidRec = mActiveUids.get(app.uid);
22792                try {
22793                    if (DEBUG_NETWORK) {
22794                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
22795                                + uidRec);
22796                    }
22797                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
22798                } catch (RemoteException ignored) {
22799                }
22800            }
22801        }
22802    }
22803
22804    /**
22805     * Checks if the uid is coming from background to foreground or vice versa and returns
22806     * appropriate block state based on this.
22807     *
22808     * @return blockState based on whether the uid is coming from background to foreground or
22809     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
22810     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
22811     *         {@link #NETWORK_STATE_NO_CHANGE}.
22812     */
22813    @VisibleForTesting
22814    int getBlockStateForUid(UidRecord uidRec) {
22815        // Denotes whether uid's process state is currently allowed network access.
22816        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
22817                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
22818        // Denotes whether uid's process state was previously allowed network access.
22819        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
22820                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
22821
22822        // When the uid is coming to foreground, AMS should inform the app thread that it should
22823        // block for the network rules to get updated before launching an activity.
22824        if (!wasAllowed && isAllowed) {
22825            return NETWORK_STATE_BLOCK;
22826        }
22827        // When the uid is going to background, AMS should inform the app thread that if an
22828        // activity launch is blocked for the network rules to get updated, it should be unblocked.
22829        if (wasAllowed && !isAllowed) {
22830            return NETWORK_STATE_UNBLOCK;
22831        }
22832        return NETWORK_STATE_NO_CHANGE;
22833    }
22834
22835    final void runInBackgroundDisabled(int uid) {
22836        synchronized (this) {
22837            UidRecord uidRec = mActiveUids.get(uid);
22838            if (uidRec != null) {
22839                // This uid is actually running...  should it be considered background now?
22840                if (uidRec.idle) {
22841                    doStopUidLocked(uidRec.uid, uidRec);
22842                }
22843            } else {
22844                // This uid isn't actually running...  still send a report about it being "stopped".
22845                doStopUidLocked(uid, null);
22846            }
22847        }
22848    }
22849
22850    final void doStopUidLocked(int uid, final UidRecord uidRec) {
22851        mServices.stopInBackgroundLocked(uid);
22852        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
22853    }
22854
22855    /**
22856     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
22857     */
22858    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
22859            long duration, String tag) {
22860        if (DEBUG_WHITELISTS) {
22861            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
22862                    + targetUid + ", " + duration + ")");
22863        }
22864
22865        synchronized (mPidsSelfLocked) {
22866            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
22867            if (pr == null) {
22868                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
22869                        + callerPid);
22870                return;
22871            }
22872            if (!pr.whitelistManager) {
22873                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
22874                        != PackageManager.PERMISSION_GRANTED) {
22875                    if (DEBUG_WHITELISTS) {
22876                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
22877                                + ": pid " + callerPid + " is not allowed");
22878                    }
22879                    return;
22880                }
22881            }
22882        }
22883
22884        tempWhitelistUidLocked(targetUid, duration, tag);
22885    }
22886
22887    /**
22888     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
22889     */
22890    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
22891        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
22892        setUidTempWhitelistStateLocked(targetUid, true);
22893        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
22894    }
22895
22896    void pushTempWhitelist() {
22897        final int N;
22898        final PendingTempWhitelist[] list;
22899
22900        // First copy out the pending changes...  we need to leave them in the map for now,
22901        // in case someone needs to check what is coming up while we don't have the lock held.
22902        synchronized(this) {
22903            N = mPendingTempWhitelist.size();
22904            list = new PendingTempWhitelist[N];
22905            for (int i = 0; i < N; i++) {
22906                list[i] = mPendingTempWhitelist.valueAt(i);
22907            }
22908        }
22909
22910        // Now safely dispatch changes to device idle controller.
22911        for (int i = 0; i < N; i++) {
22912            PendingTempWhitelist ptw = list[i];
22913            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
22914                    ptw.duration, true, ptw.tag);
22915        }
22916
22917        // And now we can safely remove them from the map.
22918        synchronized(this) {
22919            for (int i = 0; i < N; i++) {
22920                PendingTempWhitelist ptw = list[i];
22921                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
22922                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
22923                    mPendingTempWhitelist.removeAt(index);
22924                }
22925            }
22926        }
22927    }
22928
22929    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
22930        boolean changed = false;
22931        for (int i=mActiveUids.size()-1; i>=0; i--) {
22932            final UidRecord uidRec = mActiveUids.valueAt(i);
22933            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
22934                uidRec.curWhitelist = onWhitelist;
22935                changed = true;
22936            }
22937        }
22938        if (changed) {
22939            updateOomAdjLocked();
22940        }
22941    }
22942
22943    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
22944        boolean changed = false;
22945        final UidRecord uidRec = mActiveUids.get(uid);
22946        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
22947            uidRec.curWhitelist = onWhitelist;
22948            updateOomAdjLocked();
22949        }
22950    }
22951
22952    final void trimApplications() {
22953        synchronized (this) {
22954            int i;
22955
22956            // First remove any unused application processes whose package
22957            // has been removed.
22958            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
22959                final ProcessRecord app = mRemovedProcesses.get(i);
22960                if (app.activities.size() == 0
22961                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
22962                    Slog.i(
22963                        TAG, "Exiting empty application process "
22964                        + app.toShortString() + " ("
22965                        + (app.thread != null ? app.thread.asBinder() : null)
22966                        + ")\n");
22967                    if (app.pid > 0 && app.pid != MY_PID) {
22968                        app.kill("empty", false);
22969                    } else {
22970                        try {
22971                            app.thread.scheduleExit();
22972                        } catch (Exception e) {
22973                            // Ignore exceptions.
22974                        }
22975                    }
22976                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
22977                    mRemovedProcesses.remove(i);
22978
22979                    if (app.persistent) {
22980                        addAppLocked(app.info, null, false, null /* ABI override */);
22981                    }
22982                }
22983            }
22984
22985            // Now update the oom adj for all processes.
22986            updateOomAdjLocked();
22987        }
22988    }
22989
22990    /** This method sends the specified signal to each of the persistent apps */
22991    public void signalPersistentProcesses(int sig) throws RemoteException {
22992        if (sig != SIGNAL_USR1) {
22993            throw new SecurityException("Only SIGNAL_USR1 is allowed");
22994        }
22995
22996        synchronized (this) {
22997            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
22998                    != PackageManager.PERMISSION_GRANTED) {
22999                throw new SecurityException("Requires permission "
23000                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23001            }
23002
23003            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23004                ProcessRecord r = mLruProcesses.get(i);
23005                if (r.thread != null && r.persistent) {
23006                    sendSignal(r.pid, sig);
23007                }
23008            }
23009        }
23010    }
23011
23012    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23013        if (proc == null || proc == mProfileProc) {
23014            proc = mProfileProc;
23015            profileType = mProfileType;
23016            clearProfilerLocked();
23017        }
23018        if (proc == null) {
23019            return;
23020        }
23021        try {
23022            proc.thread.profilerControl(false, null, profileType);
23023        } catch (RemoteException e) {
23024            throw new IllegalStateException("Process disappeared");
23025        }
23026    }
23027
23028    private void clearProfilerLocked() {
23029        if (mProfileFd != null) {
23030            try {
23031                mProfileFd.close();
23032            } catch (IOException e) {
23033            }
23034        }
23035        mProfileApp = null;
23036        mProfileProc = null;
23037        mProfileFile = null;
23038        mProfileType = 0;
23039        mAutoStopProfiler = false;
23040        mStreamingOutput = false;
23041        mSamplingInterval = 0;
23042    }
23043
23044    public boolean profileControl(String process, int userId, boolean start,
23045            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23046
23047        try {
23048            synchronized (this) {
23049                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23050                // its own permission.
23051                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23052                        != PackageManager.PERMISSION_GRANTED) {
23053                    throw new SecurityException("Requires permission "
23054                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23055                }
23056
23057                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23058                    throw new IllegalArgumentException("null profile info or fd");
23059                }
23060
23061                ProcessRecord proc = null;
23062                if (process != null) {
23063                    proc = findProcessLocked(process, userId, "profileControl");
23064                }
23065
23066                if (start && (proc == null || proc.thread == null)) {
23067                    throw new IllegalArgumentException("Unknown process: " + process);
23068                }
23069
23070                if (start) {
23071                    stopProfilerLocked(null, 0);
23072                    setProfileApp(proc.info, proc.processName, profilerInfo);
23073                    mProfileProc = proc;
23074                    mProfileType = profileType;
23075                    ParcelFileDescriptor fd = profilerInfo.profileFd;
23076                    try {
23077                        fd = fd.dup();
23078                    } catch (IOException e) {
23079                        fd = null;
23080                    }
23081                    profilerInfo.profileFd = fd;
23082                    proc.thread.profilerControl(start, profilerInfo, profileType);
23083                    fd = null;
23084                    try {
23085                        mProfileFd.close();
23086                    } catch (IOException e) {
23087                    }
23088                    mProfileFd = null;
23089                } else {
23090                    stopProfilerLocked(proc, profileType);
23091                    if (profilerInfo != null && profilerInfo.profileFd != null) {
23092                        try {
23093                            profilerInfo.profileFd.close();
23094                        } catch (IOException e) {
23095                        }
23096                    }
23097                }
23098
23099                return true;
23100            }
23101        } catch (RemoteException e) {
23102            throw new IllegalStateException("Process disappeared");
23103        } finally {
23104            if (profilerInfo != null && profilerInfo.profileFd != null) {
23105                try {
23106                    profilerInfo.profileFd.close();
23107                } catch (IOException e) {
23108                }
23109            }
23110        }
23111    }
23112
23113    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23114        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23115                userId, true, ALLOW_FULL_ONLY, callName, null);
23116        ProcessRecord proc = null;
23117        try {
23118            int pid = Integer.parseInt(process);
23119            synchronized (mPidsSelfLocked) {
23120                proc = mPidsSelfLocked.get(pid);
23121            }
23122        } catch (NumberFormatException e) {
23123        }
23124
23125        if (proc == null) {
23126            ArrayMap<String, SparseArray<ProcessRecord>> all
23127                    = mProcessNames.getMap();
23128            SparseArray<ProcessRecord> procs = all.get(process);
23129            if (procs != null && procs.size() > 0) {
23130                proc = procs.valueAt(0);
23131                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23132                    for (int i=1; i<procs.size(); i++) {
23133                        ProcessRecord thisProc = procs.valueAt(i);
23134                        if (thisProc.userId == userId) {
23135                            proc = thisProc;
23136                            break;
23137                        }
23138                    }
23139                }
23140            }
23141        }
23142
23143        return proc;
23144    }
23145
23146    public boolean dumpHeap(String process, int userId, boolean managed,
23147            String path, ParcelFileDescriptor fd) throws RemoteException {
23148
23149        try {
23150            synchronized (this) {
23151                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23152                // its own permission (same as profileControl).
23153                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23154                        != PackageManager.PERMISSION_GRANTED) {
23155                    throw new SecurityException("Requires permission "
23156                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23157                }
23158
23159                if (fd == null) {
23160                    throw new IllegalArgumentException("null fd");
23161                }
23162
23163                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23164                if (proc == null || proc.thread == null) {
23165                    throw new IllegalArgumentException("Unknown process: " + process);
23166                }
23167
23168                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23169                if (!isDebuggable) {
23170                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23171                        throw new SecurityException("Process not debuggable: " + proc);
23172                    }
23173                }
23174
23175                proc.thread.dumpHeap(managed, path, fd);
23176                fd = null;
23177                return true;
23178            }
23179        } catch (RemoteException e) {
23180            throw new IllegalStateException("Process disappeared");
23181        } finally {
23182            if (fd != null) {
23183                try {
23184                    fd.close();
23185                } catch (IOException e) {
23186                }
23187            }
23188        }
23189    }
23190
23191    @Override
23192    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23193            String reportPackage) {
23194        if (processName != null) {
23195            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23196                    "setDumpHeapDebugLimit()");
23197        } else {
23198            synchronized (mPidsSelfLocked) {
23199                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23200                if (proc == null) {
23201                    throw new SecurityException("No process found for calling pid "
23202                            + Binder.getCallingPid());
23203                }
23204                if (!Build.IS_DEBUGGABLE
23205                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23206                    throw new SecurityException("Not running a debuggable build");
23207                }
23208                processName = proc.processName;
23209                uid = proc.uid;
23210                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23211                    throw new SecurityException("Package " + reportPackage + " is not running in "
23212                            + proc);
23213                }
23214            }
23215        }
23216        synchronized (this) {
23217            if (maxMemSize > 0) {
23218                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23219            } else {
23220                if (uid != 0) {
23221                    mMemWatchProcesses.remove(processName, uid);
23222                } else {
23223                    mMemWatchProcesses.getMap().remove(processName);
23224                }
23225            }
23226        }
23227    }
23228
23229    @Override
23230    public void dumpHeapFinished(String path) {
23231        synchronized (this) {
23232            if (Binder.getCallingPid() != mMemWatchDumpPid) {
23233                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23234                        + " does not match last pid " + mMemWatchDumpPid);
23235                return;
23236            }
23237            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23238                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23239                        + " does not match last path " + mMemWatchDumpFile);
23240                return;
23241            }
23242            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23243            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23244        }
23245    }
23246
23247    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23248    public void monitor() {
23249        synchronized (this) { }
23250    }
23251
23252    void onCoreSettingsChange(Bundle settings) {
23253        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23254            ProcessRecord processRecord = mLruProcesses.get(i);
23255            try {
23256                if (processRecord.thread != null) {
23257                    processRecord.thread.setCoreSettings(settings);
23258                }
23259            } catch (RemoteException re) {
23260                /* ignore */
23261            }
23262        }
23263    }
23264
23265    // Multi-user methods
23266
23267    /**
23268     * Start user, if its not already running, but don't bring it to foreground.
23269     */
23270    @Override
23271    public boolean startUserInBackground(final int userId) {
23272        return mUserController.startUser(userId, /* foreground */ false);
23273    }
23274
23275    @Override
23276    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23277        return mUserController.unlockUser(userId, token, secret, listener);
23278    }
23279
23280    @Override
23281    public boolean switchUser(final int targetUserId) {
23282        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23283        int currentUserId;
23284        UserInfo targetUserInfo;
23285        synchronized (this) {
23286            currentUserId = mUserController.getCurrentUserIdLocked();
23287            targetUserInfo = mUserController.getUserInfo(targetUserId);
23288            if (targetUserId == currentUserId) {
23289                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23290                return true;
23291            }
23292            if (targetUserInfo == null) {
23293                Slog.w(TAG, "No user info for user #" + targetUserId);
23294                return false;
23295            }
23296            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23297                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23298                        + " when device is in demo mode");
23299                return false;
23300            }
23301            if (!targetUserInfo.supportsSwitchTo()) {
23302                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23303                return false;
23304            }
23305            if (targetUserInfo.isManagedProfile()) {
23306                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23307                return false;
23308            }
23309            mUserController.setTargetUserIdLocked(targetUserId);
23310        }
23311        if (mUserController.mUserSwitchUiEnabled) {
23312            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23313            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23314            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23315            mUiHandler.sendMessage(mHandler.obtainMessage(
23316                    START_USER_SWITCH_UI_MSG, userNames));
23317        } else {
23318            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23319            mHandler.sendMessage(mHandler.obtainMessage(
23320                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
23321        }
23322        return true;
23323    }
23324
23325    void scheduleStartProfilesLocked() {
23326        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23327            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23328                    DateUtils.SECOND_IN_MILLIS);
23329        }
23330    }
23331
23332    @Override
23333    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23334        return mUserController.stopUser(userId, force, callback);
23335    }
23336
23337    @Override
23338    public UserInfo getCurrentUser() {
23339        return mUserController.getCurrentUser();
23340    }
23341
23342    String getStartedUserState(int userId) {
23343        synchronized (this) {
23344            final UserState userState = mUserController.getStartedUserStateLocked(userId);
23345            return UserState.stateToString(userState.state);
23346        }
23347    }
23348
23349    @Override
23350    public boolean isUserRunning(int userId, int flags) {
23351        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23352                && checkCallingPermission(INTERACT_ACROSS_USERS)
23353                    != PackageManager.PERMISSION_GRANTED) {
23354            String msg = "Permission Denial: isUserRunning() from pid="
23355                    + Binder.getCallingPid()
23356                    + ", uid=" + Binder.getCallingUid()
23357                    + " requires " + INTERACT_ACROSS_USERS;
23358            Slog.w(TAG, msg);
23359            throw new SecurityException(msg);
23360        }
23361        synchronized (this) {
23362            return mUserController.isUserRunningLocked(userId, flags);
23363        }
23364    }
23365
23366    @Override
23367    public int[] getRunningUserIds() {
23368        if (checkCallingPermission(INTERACT_ACROSS_USERS)
23369                != PackageManager.PERMISSION_GRANTED) {
23370            String msg = "Permission Denial: isUserRunning() from pid="
23371                    + Binder.getCallingPid()
23372                    + ", uid=" + Binder.getCallingUid()
23373                    + " requires " + INTERACT_ACROSS_USERS;
23374            Slog.w(TAG, msg);
23375            throw new SecurityException(msg);
23376        }
23377        synchronized (this) {
23378            return mUserController.getStartedUserArrayLocked();
23379        }
23380    }
23381
23382    @Override
23383    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23384        mUserController.registerUserSwitchObserver(observer, name);
23385    }
23386
23387    @Override
23388    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23389        mUserController.unregisterUserSwitchObserver(observer);
23390    }
23391
23392    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23393        if (info == null) return null;
23394        ApplicationInfo newInfo = new ApplicationInfo(info);
23395        newInfo.initForUser(userId);
23396        return newInfo;
23397    }
23398
23399    public boolean isUserStopped(int userId) {
23400        synchronized (this) {
23401            return mUserController.getStartedUserStateLocked(userId) == null;
23402        }
23403    }
23404
23405    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23406        if (aInfo == null
23407                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23408            return aInfo;
23409        }
23410
23411        ActivityInfo info = new ActivityInfo(aInfo);
23412        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23413        return info;
23414    }
23415
23416    private boolean processSanityChecksLocked(ProcessRecord process) {
23417        if (process == null || process.thread == null) {
23418            return false;
23419        }
23420
23421        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23422        if (!isDebuggable) {
23423            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23424                return false;
23425            }
23426        }
23427
23428        return true;
23429    }
23430
23431    public boolean startBinderTracking() throws RemoteException {
23432        synchronized (this) {
23433            mBinderTransactionTrackingEnabled = true;
23434            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23435            // permission (same as profileControl).
23436            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23437                    != PackageManager.PERMISSION_GRANTED) {
23438                throw new SecurityException("Requires permission "
23439                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23440            }
23441
23442            for (int i = 0; i < mLruProcesses.size(); i++) {
23443                ProcessRecord process = mLruProcesses.get(i);
23444                if (!processSanityChecksLocked(process)) {
23445                    continue;
23446                }
23447                try {
23448                    process.thread.startBinderTracking();
23449                } catch (RemoteException e) {
23450                    Log.v(TAG, "Process disappared");
23451                }
23452            }
23453            return true;
23454        }
23455    }
23456
23457    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23458        try {
23459            synchronized (this) {
23460                mBinderTransactionTrackingEnabled = false;
23461                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23462                // permission (same as profileControl).
23463                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23464                        != PackageManager.PERMISSION_GRANTED) {
23465                    throw new SecurityException("Requires permission "
23466                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23467                }
23468
23469                if (fd == null) {
23470                    throw new IllegalArgumentException("null fd");
23471                }
23472
23473                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23474                pw.println("Binder transaction traces for all processes.\n");
23475                for (ProcessRecord process : mLruProcesses) {
23476                    if (!processSanityChecksLocked(process)) {
23477                        continue;
23478                    }
23479
23480                    pw.println("Traces for process: " + process.processName);
23481                    pw.flush();
23482                    try {
23483                        TransferPipe tp = new TransferPipe();
23484                        try {
23485                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23486                            tp.go(fd.getFileDescriptor());
23487                        } finally {
23488                            tp.kill();
23489                        }
23490                    } catch (IOException e) {
23491                        pw.println("Failure while dumping IPC traces from " + process +
23492                                ".  Exception: " + e);
23493                        pw.flush();
23494                    } catch (RemoteException e) {
23495                        pw.println("Got a RemoteException while dumping IPC traces from " +
23496                                process + ".  Exception: " + e);
23497                        pw.flush();
23498                    }
23499                }
23500                fd = null;
23501                return true;
23502            }
23503        } finally {
23504            if (fd != null) {
23505                try {
23506                    fd.close();
23507                } catch (IOException e) {
23508                }
23509            }
23510        }
23511    }
23512
23513    @VisibleForTesting
23514    final class LocalService extends ActivityManagerInternal {
23515        @Override
23516        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23517                int targetUserId) {
23518            synchronized (ActivityManagerService.this) {
23519                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23520                        targetPkg, intent, null, targetUserId);
23521            }
23522        }
23523
23524        @Override
23525        public String checkContentProviderAccess(String authority, int userId) {
23526            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23527        }
23528
23529        @Override
23530        public void onWakefulnessChanged(int wakefulness) {
23531            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23532        }
23533
23534        @Override
23535        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23536                String processName, String abiOverride, int uid, Runnable crashHandler) {
23537            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23538                    processName, abiOverride, uid, crashHandler);
23539        }
23540
23541        @Override
23542        public SleepToken acquireSleepToken(String tag) {
23543            Preconditions.checkNotNull(tag);
23544
23545            synchronized (ActivityManagerService.this) {
23546                SleepTokenImpl token = new SleepTokenImpl(tag);
23547                mSleepTokens.add(token);
23548                updateSleepIfNeededLocked();
23549                return token;
23550            }
23551        }
23552
23553        @Override
23554        public ComponentName getHomeActivityForUser(int userId) {
23555            synchronized (ActivityManagerService.this) {
23556                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23557                return homeActivity == null ? null : homeActivity.realActivity;
23558            }
23559        }
23560
23561        @Override
23562        public void onUserRemoved(int userId) {
23563            synchronized (ActivityManagerService.this) {
23564                ActivityManagerService.this.onUserStoppedLocked(userId);
23565            }
23566        }
23567
23568        @Override
23569        public void onLocalVoiceInteractionStarted(IBinder activity,
23570                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23571            synchronized (ActivityManagerService.this) {
23572                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23573                        voiceSession, voiceInteractor);
23574            }
23575        }
23576
23577        @Override
23578        public void notifyAppTransitionStarting(SparseIntArray reasons) {
23579            synchronized (ActivityManagerService.this) {
23580                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reasons);
23581            }
23582        }
23583
23584        @Override
23585        public void notifyAppTransitionFinished() {
23586            synchronized (ActivityManagerService.this) {
23587                mStackSupervisor.notifyAppTransitionDone();
23588            }
23589        }
23590
23591        @Override
23592        public void notifyAppTransitionCancelled() {
23593            synchronized (ActivityManagerService.this) {
23594                mStackSupervisor.notifyAppTransitionDone();
23595            }
23596        }
23597
23598        @Override
23599        public List<IBinder> getTopVisibleActivities() {
23600            synchronized (ActivityManagerService.this) {
23601                return mStackSupervisor.getTopVisibleActivities();
23602            }
23603        }
23604
23605        @Override
23606        public void notifyDockedStackMinimizedChanged(boolean minimized) {
23607            synchronized (ActivityManagerService.this) {
23608                mStackSupervisor.setDockedStackMinimized(minimized);
23609            }
23610        }
23611
23612        @Override
23613        public void killForegroundAppsForUser(int userHandle) {
23614            synchronized (ActivityManagerService.this) {
23615                final ArrayList<ProcessRecord> procs = new ArrayList<>();
23616                final int NP = mProcessNames.getMap().size();
23617                for (int ip = 0; ip < NP; ip++) {
23618                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23619                    final int NA = apps.size();
23620                    for (int ia = 0; ia < NA; ia++) {
23621                        final ProcessRecord app = apps.valueAt(ia);
23622                        if (app.persistent) {
23623                            // We don't kill persistent processes.
23624                            continue;
23625                        }
23626                        if (app.removed) {
23627                            procs.add(app);
23628                        } else if (app.userId == userHandle && app.foregroundActivities) {
23629                            app.removed = true;
23630                            procs.add(app);
23631                        }
23632                    }
23633                }
23634
23635                final int N = procs.size();
23636                for (int i = 0; i < N; i++) {
23637                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
23638                }
23639            }
23640        }
23641
23642        @Override
23643        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
23644            if (!(target instanceof PendingIntentRecord)) {
23645                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23646                return;
23647            }
23648            ((PendingIntentRecord) target).setWhitelistDurationLocked(duration);
23649        }
23650
23651        @Override
23652        public void setDeviceIdleWhitelist(int[] appids) {
23653            synchronized (ActivityManagerService.this) {
23654                mDeviceIdleWhitelist = appids;
23655            }
23656        }
23657
23658        @Override
23659        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23660            synchronized (ActivityManagerService.this) {
23661                mDeviceIdleTempWhitelist = appids;
23662                setAppIdTempWhitelistStateLocked(changingAppId, adding);
23663            }
23664        }
23665
23666        @Override
23667        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23668                int userId) {
23669            Preconditions.checkNotNull(values, "Configuration must not be null");
23670            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23671            synchronized (ActivityManagerService.this) {
23672                updateConfigurationLocked(values, null, false, true, userId,
23673                        false /* deferResume */);
23674            }
23675        }
23676
23677        @Override
23678        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23679                Bundle bOptions) {
23680            Preconditions.checkNotNull(intents, "intents");
23681            final String[] resolvedTypes = new String[intents.length];
23682            for (int i = 0; i < intents.length; i++) {
23683                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23684            }
23685
23686            // UID of the package on user userId.
23687            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23688            // packageUid may not be initialized.
23689            int packageUid = 0;
23690            try {
23691                packageUid = AppGlobals.getPackageManager().getPackageUid(
23692                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23693            } catch (RemoteException e) {
23694                // Shouldn't happen.
23695            }
23696
23697            synchronized (ActivityManagerService.this) {
23698                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23699                        /*resultTo*/ null, bOptions, userId);
23700            }
23701        }
23702
23703        @Override
23704        public int getUidProcessState(int uid) {
23705            return getUidState(uid);
23706        }
23707
23708        @Override
23709        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23710            synchronized (ActivityManagerService.this) {
23711
23712                // We might change the visibilities here, so prepare an empty app transition which
23713                // might be overridden later if we actually change visibilities.
23714                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
23715                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23716                mWindowManager.executeAppTransition();
23717            }
23718            if (callback != null) {
23719                callback.run();
23720            }
23721        }
23722
23723        @Override
23724        public boolean isSystemReady() {
23725            // no need to synchronize(this) just to read & return the value
23726            return mSystemReady;
23727        }
23728
23729        @Override
23730        public void notifyKeyguardTrustedChanged() {
23731            synchronized (ActivityManagerService.this) {
23732                if (mKeyguardController.isKeyguardShowing()) {
23733                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23734                }
23735            }
23736        }
23737
23738        /**
23739         * Sets if the given pid has an overlay UI or not.
23740         *
23741         * @param pid The pid we are setting overlay UI for.
23742         * @param hasOverlayUi True if the process has overlay UI.
23743         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
23744         */
23745        @Override
23746        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
23747            synchronized (ActivityManagerService.this) {
23748                final ProcessRecord pr;
23749                synchronized (mPidsSelfLocked) {
23750                    pr = mPidsSelfLocked.get(pid);
23751                    if (pr == null) {
23752                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
23753                        return;
23754                    }
23755                }
23756                if (pr.hasOverlayUi == hasOverlayUi) {
23757                    return;
23758                }
23759                pr.hasOverlayUi = hasOverlayUi;
23760                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
23761                updateOomAdjLocked(pr, true);
23762            }
23763        }
23764
23765        /**
23766         * Called after the network policy rules are updated by
23767         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
23768         * and {@param procStateSeq}.
23769         */
23770        @Override
23771        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
23772            if (DEBUG_NETWORK) {
23773                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
23774                        + uid + " seq: " + procStateSeq);
23775            }
23776            UidRecord record;
23777            synchronized (ActivityManagerService.this) {
23778                record = mActiveUids.get(uid);
23779                if (record == null) {
23780                    if (DEBUG_NETWORK) {
23781                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
23782                                + " procStateSeq: " + procStateSeq);
23783                    }
23784                    return;
23785                }
23786            }
23787            synchronized (record.networkStateLock) {
23788                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23789                    if (DEBUG_NETWORK) {
23790                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
23791                                + " been handled for uid: " + uid);
23792                    }
23793                    return;
23794                }
23795                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
23796                if (record.curProcStateSeq > procStateSeq) {
23797                    if (DEBUG_NETWORK) {
23798                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
23799                                + ", curProcstateSeq: " + record.curProcStateSeq
23800                                + ", procStateSeq: " + procStateSeq);
23801                    }
23802                    return;
23803                }
23804                if (record.waitingForNetwork) {
23805                    if (DEBUG_NETWORK) {
23806                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
23807                                + ", procStateSeq: " + procStateSeq);
23808                    }
23809                    record.networkStateLock.notifyAll();
23810                }
23811            }
23812        }
23813
23814        /**
23815         * Called after virtual display Id is updated by
23816         * {@link com.android.server.vr.Vr2dDisplay} with a specific
23817         * {@param vrVr2dDisplayId}.
23818         */
23819        @Override
23820        public void setVr2dDisplayId(int vr2dDisplayId) {
23821            if (DEBUG_STACK) {
23822                Slog.d(TAG, "setVr2dDisplayId called for: " +
23823                        vr2dDisplayId);
23824            }
23825            synchronized (ActivityManagerService.this) {
23826                mVr2dDisplayId = vr2dDisplayId;
23827            }
23828        }
23829    }
23830
23831    /**
23832     * Called by app main thread to wait for the network policy rules to get udpated.
23833     *
23834     * @param procStateSeq The sequence number indicating the process state change that the main
23835     *                     thread is interested in.
23836     */
23837    @Override
23838    public void waitForNetworkStateUpdate(long procStateSeq) {
23839        final int callingUid = Binder.getCallingUid();
23840        if (DEBUG_NETWORK) {
23841            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
23842        }
23843        UidRecord record;
23844        synchronized (this) {
23845            record = mActiveUids.get(callingUid);
23846            if (record == null) {
23847                return;
23848            }
23849        }
23850        synchronized (record.networkStateLock) {
23851            if (record.lastDispatchedProcStateSeq < procStateSeq) {
23852                if (DEBUG_NETWORK) {
23853                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
23854                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
23855                            + " lastProcStateSeqDispatchedToObservers: "
23856                            + record.lastDispatchedProcStateSeq);
23857                }
23858                return;
23859            }
23860            if (record.curProcStateSeq > procStateSeq) {
23861                if (DEBUG_NETWORK) {
23862                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
23863                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
23864                            + ", procStateSeq: " + procStateSeq);
23865                }
23866                return;
23867            }
23868            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23869                if (DEBUG_NETWORK) {
23870                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
23871                            + procStateSeq + ", so no need to wait. Uid: "
23872                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
23873                            + record.lastNetworkUpdatedProcStateSeq);
23874                }
23875                return;
23876            }
23877            try {
23878                if (DEBUG_NETWORK) {
23879                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
23880                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
23881                }
23882                final long startTime = SystemClock.uptimeMillis();
23883                record.waitingForNetwork = true;
23884                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
23885                record.waitingForNetwork = false;
23886                final long totalTime = SystemClock.uptimeMillis() - startTime;
23887                if (totalTime >= mWaitForNetworkTimeoutMs) {
23888                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
23889                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
23890                            + procStateSeq + " UidRec: " + record
23891                            + " validateUidRec: " + mValidateUids.get(callingUid));
23892                }
23893            } catch (InterruptedException e) {
23894                Thread.currentThread().interrupt();
23895            }
23896        }
23897    }
23898
23899    public void waitForBroadcastIdle(PrintWriter pw) {
23900        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
23901        while (true) {
23902            boolean idle = true;
23903            synchronized (this) {
23904                for (BroadcastQueue queue : mBroadcastQueues) {
23905                    if (!queue.isIdle()) {
23906                        final String msg = "Waiting for queue " + queue + " to become idle...";
23907                        pw.println(msg);
23908                        pw.flush();
23909                        Slog.v(TAG, msg);
23910                        idle = false;
23911                    }
23912                }
23913            }
23914
23915            if (idle) {
23916                final String msg = "All broadcast queues are idle!";
23917                pw.println(msg);
23918                pw.flush();
23919                Slog.v(TAG, msg);
23920                return;
23921            } else {
23922                SystemClock.sleep(1000);
23923            }
23924        }
23925    }
23926
23927    /**
23928     * Return the user id of the last resumed activity.
23929     */
23930    @Override
23931    public @UserIdInt int getLastResumedActivityUserId() {
23932        enforceCallingPermission(
23933                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
23934        synchronized (this) {
23935            if (mLastResumedActivity == null) {
23936                return mUserController.getCurrentUserIdLocked();
23937            }
23938            return mLastResumedActivity.userId;
23939        }
23940    }
23941
23942    private final class SleepTokenImpl extends SleepToken {
23943        private final String mTag;
23944        private final long mAcquireTime;
23945
23946        public SleepTokenImpl(String tag) {
23947            mTag = tag;
23948            mAcquireTime = SystemClock.uptimeMillis();
23949        }
23950
23951        @Override
23952        public void release() {
23953            synchronized (ActivityManagerService.this) {
23954                if (mSleepTokens.remove(this)) {
23955                    updateSleepIfNeededLocked();
23956                }
23957            }
23958        }
23959
23960        @Override
23961        public String toString() {
23962            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
23963        }
23964    }
23965
23966    /**
23967     * An implementation of IAppTask, that allows an app to manage its own tasks via
23968     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
23969     * only the process that calls getAppTasks() can call the AppTask methods.
23970     */
23971    class AppTaskImpl extends IAppTask.Stub {
23972        private int mTaskId;
23973        private int mCallingUid;
23974
23975        public AppTaskImpl(int taskId, int callingUid) {
23976            mTaskId = taskId;
23977            mCallingUid = callingUid;
23978        }
23979
23980        private void checkCaller() {
23981            if (mCallingUid != Binder.getCallingUid()) {
23982                throw new SecurityException("Caller " + mCallingUid
23983                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
23984            }
23985        }
23986
23987        @Override
23988        public void finishAndRemoveTask() {
23989            checkCaller();
23990
23991            synchronized (ActivityManagerService.this) {
23992                long origId = Binder.clearCallingIdentity();
23993                try {
23994                    // We remove the task from recents to preserve backwards
23995                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
23996                            REMOVE_FROM_RECENTS)) {
23997                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23998                    }
23999                } finally {
24000                    Binder.restoreCallingIdentity(origId);
24001                }
24002            }
24003        }
24004
24005        @Override
24006        public ActivityManager.RecentTaskInfo getTaskInfo() {
24007            checkCaller();
24008
24009            synchronized (ActivityManagerService.this) {
24010                long origId = Binder.clearCallingIdentity();
24011                try {
24012                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24013                    if (tr == null) {
24014                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24015                    }
24016                    return createRecentTaskInfoFromTaskRecord(tr);
24017                } finally {
24018                    Binder.restoreCallingIdentity(origId);
24019                }
24020            }
24021        }
24022
24023        @Override
24024        public void moveToFront() {
24025            checkCaller();
24026            // Will bring task to front if it already has a root activity.
24027            final long origId = Binder.clearCallingIdentity();
24028            try {
24029                synchronized (this) {
24030                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24031                }
24032            } finally {
24033                Binder.restoreCallingIdentity(origId);
24034            }
24035        }
24036
24037        @Override
24038        public int startActivity(IBinder whoThread, String callingPackage,
24039                Intent intent, String resolvedType, Bundle bOptions) {
24040            checkCaller();
24041
24042            int callingUser = UserHandle.getCallingUserId();
24043            TaskRecord tr;
24044            IApplicationThread appThread;
24045            synchronized (ActivityManagerService.this) {
24046                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24047                if (tr == null) {
24048                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24049                }
24050                appThread = IApplicationThread.Stub.asInterface(whoThread);
24051                if (appThread == null) {
24052                    throw new IllegalArgumentException("Bad app thread " + appThread);
24053                }
24054            }
24055            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24056                    resolvedType, null, null, null, null, 0, 0, null, null,
24057                    null, bOptions, false, callingUser, null, tr);
24058        }
24059
24060        @Override
24061        public void setExcludeFromRecents(boolean exclude) {
24062            checkCaller();
24063
24064            synchronized (ActivityManagerService.this) {
24065                long origId = Binder.clearCallingIdentity();
24066                try {
24067                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24068                    if (tr == null) {
24069                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24070                    }
24071                    Intent intent = tr.getBaseIntent();
24072                    if (exclude) {
24073                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24074                    } else {
24075                        intent.setFlags(intent.getFlags()
24076                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24077                    }
24078                } finally {
24079                    Binder.restoreCallingIdentity(origId);
24080                }
24081            }
24082        }
24083    }
24084
24085    /**
24086     * Kill processes for the user with id userId and that depend on the package named packageName
24087     */
24088    @Override
24089    public void killPackageDependents(String packageName, int userId) {
24090        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24091        if (packageName == null) {
24092            throw new NullPointerException(
24093                    "Cannot kill the dependents of a package without its name.");
24094        }
24095
24096        long callingId = Binder.clearCallingIdentity();
24097        IPackageManager pm = AppGlobals.getPackageManager();
24098        int pkgUid = -1;
24099        try {
24100            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24101        } catch (RemoteException e) {
24102        }
24103        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24104            throw new IllegalArgumentException(
24105                    "Cannot kill dependents of non-existing package " + packageName);
24106        }
24107        try {
24108            synchronized(this) {
24109                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24110                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24111                        "dep: " + packageName);
24112            }
24113        } finally {
24114            Binder.restoreCallingIdentity(callingId);
24115        }
24116    }
24117
24118    @Override
24119    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24120            throws RemoteException {
24121        final long callingId = Binder.clearCallingIdentity();
24122        try {
24123            mKeyguardController.dismissKeyguard(token, callback);
24124        } finally {
24125            Binder.restoreCallingIdentity(callingId);
24126        }
24127    }
24128
24129    @Override
24130    public int restartUserInBackground(final int userId) {
24131        return mUserController.restartUser(userId, /* foreground */ false);
24132    }
24133
24134    @Override
24135    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24136        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24137                "scheduleApplicationInfoChanged()");
24138
24139        synchronized (this) {
24140            final long origId = Binder.clearCallingIdentity();
24141            try {
24142                updateApplicationInfoLocked(packageNames, userId);
24143            } finally {
24144                Binder.restoreCallingIdentity(origId);
24145            }
24146        }
24147    }
24148
24149    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24150        final PackageManagerInternal packageManager = getPackageManagerInternalLocked();
24151        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24152        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24153            final ProcessRecord app = mLruProcesses.get(i);
24154            if (app.thread == null) {
24155                continue;
24156            }
24157
24158            if (userId != UserHandle.USER_ALL && app.userId != userId) {
24159                continue;
24160            }
24161
24162            final int packageCount = app.pkgList.size();
24163            for (int j = 0; j < packageCount; j++) {
24164                final String packageName = app.pkgList.keyAt(j);
24165                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24166                    try {
24167                        final ApplicationInfo ai = packageManager.getApplicationInfo(
24168                                packageName, app.userId);
24169                        if (ai != null) {
24170                            app.thread.scheduleApplicationInfoChanged(ai);
24171                        }
24172                    } catch (RemoteException e) {
24173                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24174                                    packageName, app));
24175                    }
24176                }
24177            }
24178        }
24179    }
24180
24181    /**
24182     * Attach an agent to the specified process (proces name or PID)
24183     */
24184    public void attachAgent(String process, String path) {
24185        try {
24186            synchronized (this) {
24187                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24188                if (proc == null || proc.thread == null) {
24189                    throw new IllegalArgumentException("Unknown process: " + process);
24190                }
24191
24192                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24193                if (!isDebuggable) {
24194                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24195                        throw new SecurityException("Process not debuggable: " + proc);
24196                    }
24197                }
24198
24199                proc.thread.attachAgent(path);
24200            }
24201        } catch (RemoteException e) {
24202            throw new IllegalStateException("Process disappeared");
24203        }
24204    }
24205
24206    @VisibleForTesting
24207    public static class Injector {
24208        private NetworkManagementInternal mNmi;
24209
24210        public Context getContext() {
24211            return null;
24212        }
24213
24214        public AppOpsService getAppOpsService(File file, Handler handler) {
24215            return new AppOpsService(file, handler);
24216        }
24217
24218        public Handler getUiHandler(ActivityManagerService service) {
24219            return service.new UiHandler();
24220        }
24221
24222        public boolean isNetworkRestrictedForUid(int uid) {
24223            if (ensureHasNetworkManagementInternal()) {
24224                return mNmi.isNetworkRestrictedForUid(uid);
24225            }
24226            return false;
24227        }
24228
24229        private boolean ensureHasNetworkManagementInternal() {
24230            if (mNmi == null) {
24231                mNmi = LocalServices.getService(NetworkManagementInternal.class);
24232            }
24233            return mNmi != null;
24234        }
24235    }
24236}
24237