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.INTERNAL_SYSTEM_WINDOW;
24import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
25import static android.Manifest.permission.READ_FRAME_BUFFER;
26import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
27import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
28import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
29import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
30import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
31import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
32import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
33import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
34import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
35import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
36import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
37import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
38import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
39import static android.content.pm.PackageManager.GET_PROVIDERS;
40import static android.content.pm.PackageManager.MATCH_ANY_USER;
41import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
42import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
43import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
44import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
45import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
46import static android.content.pm.PackageManager.PERMISSION_GRANTED;
47import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
48import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
49import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
50import static android.os.Build.VERSION_CODES.N;
51import static android.os.Process.BLUETOOTH_UID;
52import static android.os.Process.FIRST_APPLICATION_UID;
53import static android.os.Process.FIRST_ISOLATED_UID;
54import static android.os.Process.LAST_ISOLATED_UID;
55import static android.os.Process.NFC_UID;
56import static android.os.Process.PHONE_UID;
57import static android.os.Process.PROC_CHAR;
58import static android.os.Process.PROC_OUT_LONG;
59import static android.os.Process.PROC_PARENS;
60import static android.os.Process.PROC_SPACE_TERM;
61import static android.os.Process.ProcessStartResult;
62import static android.os.Process.ROOT_UID;
63import static android.os.Process.SCHED_FIFO;
64import static android.os.Process.SCHED_OTHER;
65import static android.os.Process.SCHED_RESET_ON_FORK;
66import static android.os.Process.SHELL_UID;
67import static android.os.Process.SIGNAL_QUIT;
68import static android.os.Process.SIGNAL_USR1;
69import static android.os.Process.SYSTEM_UID;
70import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
71import static android.os.Process.THREAD_GROUP_DEFAULT;
72import static android.os.Process.THREAD_GROUP_TOP_APP;
73import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
74import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
75import static android.os.Process.getFreeMemory;
76import static android.os.Process.getTotalMemory;
77import static android.os.Process.isThreadInProcess;
78import static android.os.Process.killProcess;
79import static android.os.Process.killProcessQuiet;
80import static android.os.Process.myPid;
81import static android.os.Process.myUid;
82import static android.os.Process.readProcFile;
83import static android.os.Process.removeAllProcessGroups;
84import static android.os.Process.sendSignal;
85import static android.os.Process.setProcessGroup;
86import static android.os.Process.setThreadPriority;
87import static android.os.Process.setThreadScheduler;
88import static android.os.Process.startWebView;
89import static android.os.Process.zygoteProcess;
90import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
91import static android.provider.Settings.Global.DEBUG_APP;
92import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
93import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
94import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
95import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
96import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
97import static android.provider.Settings.System.FONT_SCALE;
98import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
99import static android.text.format.DateUtils.DAY_IN_MILLIS;
100import static android.view.Display.DEFAULT_DISPLAY;
101import static android.view.Display.INVALID_DISPLAY;
102import static com.android.internal.util.XmlUtils.readBooleanAttribute;
103import static com.android.internal.util.XmlUtils.readIntAttribute;
104import static com.android.internal.util.XmlUtils.readLongAttribute;
105import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
106import static com.android.internal.util.XmlUtils.writeIntAttribute;
107import static com.android.internal.util.XmlUtils.writeLongAttribute;
108import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
109import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
110import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
111import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
112import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
113import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
114import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
115import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
116import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
117import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
118import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
119import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
120import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
121import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
122import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
123import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
124import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
125import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
126import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
127import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
128import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
141import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
142import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
143import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
144import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
145import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
146import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
147import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
148import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
152import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
153import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
154import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
155import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
156import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
157import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
158import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
159import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
160import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
161import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
162import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
163import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
164import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
165import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
166import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
167import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
168import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
169import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
170import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
171import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
172import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
173import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
174import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
175import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
176import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
177import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
178import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
179import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
180import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
181import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
182import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
183import static com.android.server.wm.AppTransition.TRANSIT_NONE;
184import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
185import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
186import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
187import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
188import static org.xmlpull.v1.XmlPullParser.START_TAG;
189
190import android.Manifest;
191import android.Manifest.permission;
192import android.annotation.NonNull;
193import android.annotation.Nullable;
194import android.annotation.UserIdInt;
195import android.app.Activity;
196import android.app.ActivityManager;
197import android.app.ActivityManager.RunningTaskInfo;
198import android.app.ActivityManager.StackId;
199import android.app.ActivityManager.StackInfo;
200import android.app.ActivityManager.TaskSnapshot;
201import android.app.ActivityManager.TaskThumbnailInfo;
202import android.app.ActivityManagerInternal;
203import android.app.ActivityManagerInternal.SleepToken;
204import android.app.ActivityOptions;
205import android.app.ActivityThread;
206import android.app.AlertDialog;
207import android.app.AppGlobals;
208import android.app.AppOpsManager;
209import android.app.ApplicationErrorReport;
210import android.app.ApplicationThreadConstants;
211import android.app.BroadcastOptions;
212import android.app.ContentProviderHolder;
213import android.app.Dialog;
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.pm.ActivityInfo;
257import android.content.pm.ApplicationInfo;
258import android.content.pm.ConfigurationInfo;
259import android.content.pm.IPackageDataObserver;
260import android.content.pm.IPackageManager;
261import android.content.pm.InstrumentationInfo;
262import android.content.pm.PackageInfo;
263import android.content.pm.PackageManager;
264import android.content.pm.PackageManager.NameNotFoundException;
265import android.content.pm.PackageManagerInternal;
266import android.content.pm.ParceledListSlice;
267import android.content.pm.PathPermission;
268import android.content.pm.PermissionInfo;
269import android.content.pm.ProviderInfo;
270import android.content.pm.ResolveInfo;
271import android.content.pm.SELinuxUtil;
272import android.content.pm.ServiceInfo;
273import android.content.pm.UserInfo;
274import android.content.res.CompatibilityInfo;
275import android.content.res.Configuration;
276import android.content.res.Resources;
277import android.database.ContentObserver;
278import android.graphics.Bitmap;
279import android.graphics.Point;
280import android.graphics.Rect;
281import android.location.LocationManager;
282import android.media.audiofx.AudioEffect;
283import android.metrics.LogMaker;
284import android.net.Proxy;
285import android.net.ProxyInfo;
286import android.net.Uri;
287import android.os.BatteryStats;
288import android.os.Binder;
289import android.os.Build;
290import android.os.Bundle;
291import android.os.Debug;
292import android.os.DropBoxManager;
293import android.os.Environment;
294import android.os.FactoryTest;
295import android.os.FileObserver;
296import android.os.FileUtils;
297import android.os.Handler;
298import android.os.IBinder;
299import android.os.IDeviceIdentifiersPolicyService;
300import android.os.IPermissionController;
301import android.os.IProcessInfoService;
302import android.os.IProgressListener;
303import android.os.LocaleList;
304import android.os.Looper;
305import android.os.Message;
306import android.os.Parcel;
307import android.os.ParcelFileDescriptor;
308import android.os.PersistableBundle;
309import android.os.PowerManager;
310import android.os.PowerManagerInternal;
311import android.os.Process;
312import android.os.RemoteCallbackList;
313import android.os.RemoteException;
314import android.os.ResultReceiver;
315import android.os.ServiceManager;
316import android.os.ShellCallback;
317import android.os.StrictMode;
318import android.os.SystemClock;
319import android.os.SystemProperties;
320import android.os.Trace;
321import android.os.TransactionTooLargeException;
322import android.os.UpdateLock;
323import android.os.UserHandle;
324import android.os.UserManager;
325import android.os.WorkSource;
326import android.os.storage.IStorageManager;
327import android.os.storage.StorageManager;
328import android.os.storage.StorageManagerInternal;
329import android.provider.Downloads;
330import android.provider.Settings;
331import android.service.voice.IVoiceInteractionSession;
332import android.service.voice.VoiceInteractionManagerInternal;
333import android.service.voice.VoiceInteractionSession;
334import android.telecom.TelecomManager;
335import android.text.TextUtils;
336import android.text.format.DateUtils;
337import android.text.format.Time;
338import android.text.style.SuggestionSpan;
339import android.util.ArrayMap;
340import android.util.ArraySet;
341import android.util.AtomicFile;
342import android.util.TimingsTraceLog;
343import android.util.DebugUtils;
344import android.util.DisplayMetrics;
345import android.util.EventLog;
346import android.util.Log;
347import android.util.Pair;
348import android.util.PrintWriterPrinter;
349import android.util.Slog;
350import android.util.SparseArray;
351import android.util.SparseIntArray;
352import android.util.TimeUtils;
353import android.util.Xml;
354import android.view.Gravity;
355import android.view.LayoutInflater;
356import android.view.View;
357import android.view.WindowManager;
358
359import com.android.server.job.JobSchedulerInternal;
360import com.google.android.collect.Lists;
361import com.google.android.collect.Maps;
362
363import com.android.internal.R;
364import com.android.internal.annotations.GuardedBy;
365import com.android.internal.annotations.VisibleForTesting;
366import com.android.internal.app.AssistUtils;
367import com.android.internal.app.DumpHeapActivity;
368import com.android.internal.app.IAppOpsCallback;
369import com.android.internal.app.IAppOpsService;
370import com.android.internal.app.IVoiceInteractor;
371import com.android.internal.app.ProcessMap;
372import com.android.internal.app.SystemUserHomeActivity;
373import com.android.internal.app.procstats.ProcessStats;
374import com.android.internal.logging.MetricsLogger;
375import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
376import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
377import com.android.internal.notification.SystemNotificationChannels;
378import com.android.internal.os.BackgroundThread;
379import com.android.internal.os.BatteryStatsImpl;
380import com.android.internal.os.IResultReceiver;
381import com.android.internal.os.ProcessCpuTracker;
382import com.android.internal.os.TransferPipe;
383import com.android.internal.os.Zygote;
384import com.android.internal.policy.IKeyguardDismissCallback;
385import com.android.internal.telephony.TelephonyIntents;
386import com.android.internal.util.ArrayUtils;
387import com.android.internal.util.DumpUtils;
388import com.android.internal.util.FastPrintWriter;
389import com.android.internal.util.FastXmlSerializer;
390import com.android.internal.util.MemInfoReader;
391import com.android.internal.util.Preconditions;
392import com.android.server.AppOpsService;
393import com.android.server.AttributeCache;
394import com.android.server.DeviceIdleController;
395import com.android.server.IntentResolver;
396import com.android.server.LocalServices;
397import com.android.server.LockGuard;
398import com.android.server.NetworkManagementInternal;
399import com.android.server.RescueParty;
400import com.android.server.ServiceThread;
401import com.android.server.SystemConfig;
402import com.android.server.SystemService;
403import com.android.server.SystemServiceManager;
404import com.android.server.ThreadPriorityBooster;
405import com.android.server.Watchdog;
406import com.android.server.am.ActivityStack.ActivityState;
407import com.android.server.firewall.IntentFirewall;
408import com.android.server.pm.Installer;
409import com.android.server.pm.Installer.InstallerException;
410import com.android.server.statusbar.StatusBarManagerInternal;
411import com.android.server.vr.VrManagerInternal;
412import com.android.server.wm.PinnedStackWindowController;
413import com.android.server.wm.WindowManagerService;
414
415import java.text.SimpleDateFormat;
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.text.DateFormat;
433import java.util.ArrayList;
434import java.util.Arrays;
435import java.util.Collections;
436import java.util.Comparator;
437import java.util.Date;
438import java.util.HashMap;
439import java.util.HashSet;
440import java.util.Iterator;
441import java.util.List;
442import java.util.Locale;
443import java.util.Map;
444import java.util.Objects;
445import java.util.Set;
446import java.util.concurrent.CountDownLatch;
447import java.util.concurrent.atomic.AtomicBoolean;
448import java.util.concurrent.atomic.AtomicLong;
449
450import dalvik.system.VMRuntime;
451import libcore.io.IoUtils;
452import libcore.util.EmptyArray;
453
454public class ActivityManagerService extends IActivityManager.Stub
455        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
456
457    /**
458     * Priority we boost main thread and RT of top app to.
459     */
460    public static final int TOP_APP_PRIORITY_BOOST = -10;
461
462    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
463    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
464    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
465    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
466    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
467    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
468    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
469    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
470    private static final String TAG_LRU = TAG + POSTFIX_LRU;
471    private static final String TAG_MU = TAG + POSTFIX_MU;
472    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
473    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
474    private static final String TAG_POWER = TAG + POSTFIX_POWER;
475    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
476    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
477    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
478    private static final String TAG_PSS = TAG + POSTFIX_PSS;
479    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
480    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
481    private static final String TAG_STACK = TAG + POSTFIX_STACK;
482    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
483    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
484    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
485    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
486
487    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
488    // here so that while the job scheduler can depend on AMS, the other way around
489    // need not be the case.
490    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
491
492    /** Control over CPU and battery monitoring */
493    // write battery stats every 30 minutes.
494    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
495    static final boolean MONITOR_CPU_USAGE = true;
496    // don't sample cpu less than every 5 seconds.
497    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
498    // wait possibly forever for next cpu sample.
499    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
500    static final boolean MONITOR_THREAD_CPU_USAGE = false;
501
502    // The flags that are set for all calls we make to the package manager.
503    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
504
505    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
506
507    // Amount of time after a call to stopAppSwitches() during which we will
508    // prevent further untrusted switches from happening.
509    static final long APP_SWITCH_DELAY_TIME = 5*1000;
510
511    // How long we wait for a launched process to attach to the activity manager
512    // before we decide it's never going to come up for real.
513    static final int PROC_START_TIMEOUT = 10*1000;
514    // How long we wait for an attached process to publish its content providers
515    // before we decide it must be hung.
516    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
517
518    // How long we wait for a launched process to attach to the activity manager
519    // before we decide it's never going to come up for real, when the process was
520    // started with a wrapper for instrumentation (such as Valgrind) because it
521    // could take much longer than usual.
522    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
523
524    // How long we allow a receiver to run before giving up on it.
525    static final int BROADCAST_FG_TIMEOUT = 10*1000;
526    static final int BROADCAST_BG_TIMEOUT = 60*1000;
527
528    // How long we wait until we timeout on key dispatching.
529    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
530
531    // How long we wait until we timeout on key dispatching during instrumentation.
532    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
533
534    // How long to wait in getAssistContextExtras for the activity and foreground services
535    // to respond with the result.
536    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
537
538    // How long top wait when going through the modern assist (which doesn't need to block
539    // on getting this result before starting to launch its UI).
540    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
541
542    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
543    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
544
545    // Maximum number of persisted Uri grants a package is allowed
546    static final int MAX_PERSISTED_URI_GRANTS = 128;
547
548    static final int MY_PID = myPid();
549
550    static final String[] EMPTY_STRING_ARRAY = new String[0];
551
552    // How many bytes to write into the dropbox log before truncating
553    static final int DROPBOX_MAX_SIZE = 192 * 1024;
554    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
555    // as one line, but close enough for now.
556    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
557
558    // Access modes for handleIncomingUser.
559    static final int ALLOW_NON_FULL = 0;
560    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
561    static final int ALLOW_FULL_ONLY = 2;
562
563    // Necessary ApplicationInfo flags to mark an app as persistent
564    private static final int PERSISTENT_MASK =
565            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
566
567    // Intent sent when remote bugreport collection has been completed
568    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
569            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
570
571    // Used to indicate that an app transition should be animated.
572    static final boolean ANIMATE = true;
573
574    // Determines whether to take full screen screenshots
575    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
576
577    /**
578     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
579     */
580    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
581
582    /**
583     * State indicating that there is no need for any blocking for network.
584     */
585    @VisibleForTesting
586    static final int NETWORK_STATE_NO_CHANGE = 0;
587
588    /**
589     * State indicating that the main thread needs to be informed about the network wait.
590     */
591    @VisibleForTesting
592    static final int NETWORK_STATE_BLOCK = 1;
593
594    /**
595     * State indicating that any threads waiting for network state to get updated can be unblocked.
596     */
597    @VisibleForTesting
598    static final int NETWORK_STATE_UNBLOCK = 2;
599
600    // Max character limit for a notification title. If the notification title is larger than this
601    // the notification will not be legible to the user.
602    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
603
604    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
605
606    /** All system services */
607    SystemServiceManager mSystemServiceManager;
608    AssistUtils mAssistUtils;
609
610    private Installer mInstaller;
611
612    /** Run all ActivityStacks through this */
613    final ActivityStackSupervisor mStackSupervisor;
614    private final KeyguardController mKeyguardController;
615
616    final ActivityStarter mActivityStarter;
617
618    final TaskChangeNotificationController mTaskChangeNotificationController;
619
620    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
621
622    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
623
624    public final IntentFirewall mIntentFirewall;
625
626    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
627    // default action automatically.  Important for devices without direct input
628    // devices.
629    private boolean mShowDialogs = true;
630
631    private final VrController mVrController;
632
633    // VR Vr2d Display Id.
634    int mVr2dDisplayId = INVALID_DISPLAY;
635
636    // Whether we should use SCHED_FIFO for UI and RenderThreads.
637    private boolean mUseFifoUiScheduling = false;
638
639    BroadcastQueue mFgBroadcastQueue;
640    BroadcastQueue mBgBroadcastQueue;
641    // Convenient for easy iteration over the queues. Foreground is first
642    // so that dispatch of foreground broadcasts gets precedence.
643    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
644
645    BroadcastStats mLastBroadcastStats;
646    BroadcastStats mCurBroadcastStats;
647
648    BroadcastQueue broadcastQueueForIntent(Intent intent) {
649        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
650        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
651                "Broadcast intent " + intent + " on "
652                + (isFg ? "foreground" : "background") + " queue");
653        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
654    }
655
656    /**
657     * The last resumed activity. This is identical to the current resumed activity most
658     * of the time but could be different when we're pausing one activity before we resume
659     * another activity.
660     */
661    private ActivityRecord mLastResumedActivity;
662
663    /**
664     * If non-null, we are tracking the time the user spends in the currently focused app.
665     */
666    private AppTimeTracker mCurAppTimeTracker;
667
668    /**
669     * List of intents that were used to start the most recent tasks.
670     */
671    final RecentTasks mRecentTasks;
672
673    /**
674     * For addAppTask: cached of the last activity component that was added.
675     */
676    ComponentName mLastAddedTaskComponent;
677
678    /**
679     * For addAppTask: cached of the last activity uid that was added.
680     */
681    int mLastAddedTaskUid;
682
683    /**
684     * For addAppTask: cached of the last ActivityInfo that was added.
685     */
686    ActivityInfo mLastAddedTaskActivity;
687
688    /**
689     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
690     */
691    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
692
693    /**
694     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
695     */
696    String mDeviceOwnerName;
697
698    final UserController mUserController;
699
700    final AppErrors mAppErrors;
701
702    /**
703     * Dump of the activity state at the time of the last ANR. Cleared after
704     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
705     */
706    String mLastANRState;
707
708    /**
709     * Indicates the maximum time spent waiting for the network rules to get updated.
710     */
711    @VisibleForTesting
712    long mWaitForNetworkTimeoutMs;
713
714    public boolean canShowErrorDialogs() {
715        return mShowDialogs && !mSleeping && !mShuttingDown
716                && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
717                && !(UserManager.isDeviceInDemoMode(mContext)
718                        && mUserController.getCurrentUser().isDemo());
719    }
720
721    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
722            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
723
724    static void boostPriorityForLockedSection() {
725        sThreadPriorityBooster.boost();
726    }
727
728    static void resetPriorityAfterLockedSection() {
729        sThreadPriorityBooster.reset();
730    }
731
732    public class PendingAssistExtras extends Binder implements Runnable {
733        public final ActivityRecord activity;
734        public boolean isHome;
735        public final Bundle extras;
736        public final Intent intent;
737        public final String hint;
738        public final IResultReceiver receiver;
739        public final int userHandle;
740        public boolean haveResult = false;
741        public Bundle result = null;
742        public AssistStructure structure = null;
743        public AssistContent content = null;
744        public Bundle receiverExtras;
745
746        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
747                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
748            activity = _activity;
749            extras = _extras;
750            intent = _intent;
751            hint = _hint;
752            receiver = _receiver;
753            receiverExtras = _receiverExtras;
754            userHandle = _userHandle;
755        }
756
757        @Override
758        public void run() {
759            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
760            synchronized (this) {
761                haveResult = true;
762                notifyAll();
763            }
764            pendingAssistExtrasTimedOut(this);
765        }
766    }
767
768    final ArrayList<PendingAssistExtras> mPendingAssistExtras
769            = new ArrayList<PendingAssistExtras>();
770
771    /**
772     * Process management.
773     */
774    final ProcessList mProcessList = new ProcessList();
775
776    /**
777     * All of the applications we currently have running organized by name.
778     * The keys are strings of the application package name (as
779     * returned by the package manager), and the keys are ApplicationRecord
780     * objects.
781     */
782    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
783
784    /**
785     * Tracking long-term execution of processes to look for abuse and other
786     * bad app behavior.
787     */
788    final ProcessStatsService mProcessStats;
789
790    /**
791     * The currently running isolated processes.
792     */
793    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
794
795    /**
796     * Counter for assigning isolated process uids, to avoid frequently reusing the
797     * same ones.
798     */
799    int mNextIsolatedProcessUid = 0;
800
801    /**
802     * The currently running heavy-weight process, if any.
803     */
804    ProcessRecord mHeavyWeightProcess = null;
805
806    /**
807     * Non-persistent appId whitelist for background restrictions
808     */
809    int[] mBackgroundAppIdWhitelist = new int[] {
810            BLUETOOTH_UID
811    };
812
813    /**
814     * Broadcast actions that will always be deliverable to unlaunched/background apps
815     */
816    ArraySet<String> mBackgroundLaunchBroadcasts;
817
818    /**
819     * All of the processes we currently have running organized by pid.
820     * The keys are the pid running the application.
821     *
822     * <p>NOTE: This object is protected by its own lock, NOT the global
823     * activity manager lock!
824     */
825    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
826
827    /**
828     * All of the processes that have been forced to be important.  The key
829     * is the pid of the caller who requested it (we hold a death
830     * link on it).
831     */
832    abstract class ImportanceToken implements IBinder.DeathRecipient {
833        final int pid;
834        final IBinder token;
835        final String reason;
836
837        ImportanceToken(int _pid, IBinder _token, String _reason) {
838            pid = _pid;
839            token = _token;
840            reason = _reason;
841        }
842
843        @Override
844        public String toString() {
845            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
846                    + " " + reason + " " + pid + " " + token + " }";
847        }
848    }
849    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
850
851    /**
852     * List of records for processes that someone had tried to start before the
853     * system was ready.  We don't start them at that point, but ensure they
854     * are started by the time booting is complete.
855     */
856    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
857
858    /**
859     * List of persistent applications that are in the process
860     * of being started.
861     */
862    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
863
864    /**
865     * Processes that are being forcibly torn down.
866     */
867    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
868
869    /**
870     * List of running applications, sorted by recent usage.
871     * The first entry in the list is the least recently used.
872     */
873    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
874
875    /**
876     * Where in mLruProcesses that the processes hosting activities start.
877     */
878    int mLruProcessActivityStart = 0;
879
880    /**
881     * Where in mLruProcesses that the processes hosting services start.
882     * This is after (lower index) than mLruProcessesActivityStart.
883     */
884    int mLruProcessServiceStart = 0;
885
886    /**
887     * List of processes that should gc as soon as things are idle.
888     */
889    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
890
891    /**
892     * Processes we want to collect PSS data from.
893     */
894    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
895
896    private boolean mBinderTransactionTrackingEnabled = false;
897
898    /**
899     * Last time we requested PSS data of all processes.
900     */
901    long mLastFullPssTime = SystemClock.uptimeMillis();
902
903    /**
904     * If set, the next time we collect PSS data we should do a full collection
905     * with data from native processes and the kernel.
906     */
907    boolean mFullPssPending = false;
908
909    /**
910     * This is the process holding what we currently consider to be
911     * the "home" activity.
912     */
913    ProcessRecord mHomeProcess;
914
915    /**
916     * This is the process holding the activity the user last visited that
917     * is in a different process from the one they are currently in.
918     */
919    ProcessRecord mPreviousProcess;
920
921    /**
922     * The time at which the previous process was last visible.
923     */
924    long mPreviousProcessVisibleTime;
925
926    /**
927     * Track all uids that have actively running processes.
928     */
929    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
930
931    /**
932     * This is for verifying the UID report flow.
933     */
934    static final boolean VALIDATE_UID_STATES = true;
935    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
936
937    /**
938     * Packages that the user has asked to have run in screen size
939     * compatibility mode instead of filling the screen.
940     */
941    final CompatModePackages mCompatModePackages;
942
943    /**
944     * Set of IntentSenderRecord objects that are currently active.
945     */
946    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
947            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
948
949    /**
950     * Fingerprints (hashCode()) of stack traces that we've
951     * already logged DropBox entries for.  Guarded by itself.  If
952     * something (rogue user app) forces this over
953     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
954     */
955    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
956    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
957
958    /**
959     * Strict Mode background batched logging state.
960     *
961     * The string buffer is guarded by itself, and its lock is also
962     * used to determine if another batched write is already
963     * in-flight.
964     */
965    private final StringBuilder mStrictModeBuffer = new StringBuilder();
966
967    /**
968     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
969     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
970     */
971    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
972
973    /**
974     * Resolver for broadcast intents to registered receivers.
975     * Holds BroadcastFilter (subclass of IntentFilter).
976     */
977    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
978            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
979        @Override
980        protected boolean allowFilterResult(
981                BroadcastFilter filter, List<BroadcastFilter> dest) {
982            IBinder target = filter.receiverList.receiver.asBinder();
983            for (int i = dest.size() - 1; i >= 0; i--) {
984                if (dest.get(i).receiverList.receiver.asBinder() == target) {
985                    return false;
986                }
987            }
988            return true;
989        }
990
991        @Override
992        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
993            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
994                    || userId == filter.owningUserId) {
995                return super.newResult(filter, match, userId);
996            }
997            return null;
998        }
999
1000        @Override
1001        protected BroadcastFilter[] newArray(int size) {
1002            return new BroadcastFilter[size];
1003        }
1004
1005        @Override
1006        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1007            return packageName.equals(filter.packageName);
1008        }
1009    };
1010
1011    /**
1012     * State of all active sticky broadcasts per user.  Keys are the action of the
1013     * sticky Intent, values are an ArrayList of all broadcasted intents with
1014     * that action (which should usually be one).  The SparseArray is keyed
1015     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1016     * for stickies that are sent to all users.
1017     */
1018    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1019            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1020
1021    final ActiveServices mServices;
1022
1023    final static class Association {
1024        final int mSourceUid;
1025        final String mSourceProcess;
1026        final int mTargetUid;
1027        final ComponentName mTargetComponent;
1028        final String mTargetProcess;
1029
1030        int mCount;
1031        long mTime;
1032
1033        int mNesting;
1034        long mStartTime;
1035
1036        // states of the source process when the bind occurred.
1037        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1038        long mLastStateUptime;
1039        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1040                - ActivityManager.MIN_PROCESS_STATE+1];
1041
1042        Association(int sourceUid, String sourceProcess, int targetUid,
1043                ComponentName targetComponent, String targetProcess) {
1044            mSourceUid = sourceUid;
1045            mSourceProcess = sourceProcess;
1046            mTargetUid = targetUid;
1047            mTargetComponent = targetComponent;
1048            mTargetProcess = targetProcess;
1049        }
1050    }
1051
1052    /**
1053     * When service association tracking is enabled, this is all of the associations we
1054     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1055     * -> association data.
1056     */
1057    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1058            mAssociations = new SparseArray<>();
1059    boolean mTrackingAssociations;
1060
1061    /**
1062     * Backup/restore process management
1063     */
1064    String mBackupAppName = null;
1065    BackupRecord mBackupTarget = null;
1066
1067    final ProviderMap mProviderMap;
1068
1069    /**
1070     * List of content providers who have clients waiting for them.  The
1071     * application is currently being launched and the provider will be
1072     * removed from this list once it is published.
1073     */
1074    final ArrayList<ContentProviderRecord> mLaunchingProviders
1075            = new ArrayList<ContentProviderRecord>();
1076
1077    /**
1078     * File storing persisted {@link #mGrantedUriPermissions}.
1079     */
1080    private final AtomicFile mGrantFile;
1081
1082    /** XML constants used in {@link #mGrantFile} */
1083    private static final String TAG_URI_GRANTS = "uri-grants";
1084    private static final String TAG_URI_GRANT = "uri-grant";
1085    private static final String ATTR_USER_HANDLE = "userHandle";
1086    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1087    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1088    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1089    private static final String ATTR_TARGET_PKG = "targetPkg";
1090    private static final String ATTR_URI = "uri";
1091    private static final String ATTR_MODE_FLAGS = "modeFlags";
1092    private static final String ATTR_CREATED_TIME = "createdTime";
1093    private static final String ATTR_PREFIX = "prefix";
1094
1095    /**
1096     * Global set of specific {@link Uri} permissions that have been granted.
1097     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1098     * to {@link UriPermission#uri} to {@link UriPermission}.
1099     */
1100    @GuardedBy("this")
1101    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1102            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1103
1104    public static class GrantUri {
1105        public final int sourceUserId;
1106        public final Uri uri;
1107        public boolean prefix;
1108
1109        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1110            this.sourceUserId = sourceUserId;
1111            this.uri = uri;
1112            this.prefix = prefix;
1113        }
1114
1115        @Override
1116        public int hashCode() {
1117            int hashCode = 1;
1118            hashCode = 31 * hashCode + sourceUserId;
1119            hashCode = 31 * hashCode + uri.hashCode();
1120            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1121            return hashCode;
1122        }
1123
1124        @Override
1125        public boolean equals(Object o) {
1126            if (o instanceof GrantUri) {
1127                GrantUri other = (GrantUri) o;
1128                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1129                        && prefix == other.prefix;
1130            }
1131            return false;
1132        }
1133
1134        @Override
1135        public String toString() {
1136            String result = uri.toString() + " [user " + sourceUserId + "]";
1137            if (prefix) result += " [prefix]";
1138            return result;
1139        }
1140
1141        public String toSafeString() {
1142            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1143            if (prefix) result += " [prefix]";
1144            return result;
1145        }
1146
1147        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1148            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1149                    ContentProvider.getUriWithoutUserId(uri), false);
1150        }
1151    }
1152
1153    CoreSettingsObserver mCoreSettingsObserver;
1154
1155    FontScaleSettingObserver mFontScaleSettingObserver;
1156
1157    private final class FontScaleSettingObserver extends ContentObserver {
1158        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1159
1160        public FontScaleSettingObserver() {
1161            super(mHandler);
1162            ContentResolver resolver = mContext.getContentResolver();
1163            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1164        }
1165
1166        @Override
1167        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1168            if (mFontScaleUri.equals(uri)) {
1169                updateFontScaleIfNeeded(userId);
1170            }
1171        }
1172    }
1173
1174    /**
1175     * Thread-local storage used to carry caller permissions over through
1176     * indirect content-provider access.
1177     */
1178    private class Identity {
1179        public final IBinder token;
1180        public final int pid;
1181        public final int uid;
1182
1183        Identity(IBinder _token, int _pid, int _uid) {
1184            token = _token;
1185            pid = _pid;
1186            uid = _uid;
1187        }
1188    }
1189
1190    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1191
1192    /**
1193     * All information we have collected about the runtime performance of
1194     * any user id that can impact battery performance.
1195     */
1196    final BatteryStatsService mBatteryStatsService;
1197
1198    /**
1199     * Information about component usage
1200     */
1201    UsageStatsManagerInternal mUsageStatsService;
1202
1203    /**
1204     * Access to DeviceIdleController service.
1205     */
1206    DeviceIdleController.LocalService mLocalDeviceIdleController;
1207
1208    /**
1209     * Set of app ids that are whitelisted for device idle and thus background check.
1210     */
1211    int[] mDeviceIdleWhitelist = new int[0];
1212
1213    /**
1214     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1215     */
1216    int[] mDeviceIdleTempWhitelist = new int[0];
1217
1218    static final class PendingTempWhitelist {
1219        final int targetUid;
1220        final long duration;
1221        final String tag;
1222
1223        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1224            targetUid = _targetUid;
1225            duration = _duration;
1226            tag = _tag;
1227        }
1228    }
1229
1230    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1231
1232    /**
1233     * Information about and control over application operations
1234     */
1235    final AppOpsService mAppOpsService;
1236
1237    /** Current sequencing integer of the configuration, for skipping old configurations. */
1238    private int mConfigurationSeq;
1239
1240    /**
1241     * Temp object used when global and/or display override configuration is updated. It is also
1242     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1243     * anyone...
1244     */
1245    private Configuration mTempConfig = new Configuration();
1246
1247    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1248            new UpdateConfigurationResult();
1249    private static final class UpdateConfigurationResult {
1250        // Configuration changes that were updated.
1251        int changes;
1252        // If the activity was relaunched to match the new configuration.
1253        boolean activityRelaunched;
1254
1255        void reset() {
1256            changes = 0;
1257            activityRelaunched = false;
1258        }
1259    }
1260
1261    boolean mSuppressResizeConfigChanges;
1262
1263    /**
1264     * Hardware-reported OpenGLES version.
1265     */
1266    final int GL_ES_VERSION;
1267
1268    /**
1269     * List of initialization arguments to pass to all processes when binding applications to them.
1270     * For example, references to the commonly used services.
1271     */
1272    HashMap<String, IBinder> mAppBindArgs;
1273    HashMap<String, IBinder> mIsolatedAppBindArgs;
1274
1275    /**
1276     * Temporary to avoid allocations.  Protected by main lock.
1277     */
1278    final StringBuilder mStringBuilder = new StringBuilder(256);
1279
1280    /**
1281     * Used to control how we initialize the service.
1282     */
1283    ComponentName mTopComponent;
1284    String mTopAction = Intent.ACTION_MAIN;
1285    String mTopData;
1286
1287    volatile boolean mProcessesReady = false;
1288    volatile boolean mSystemReady = false;
1289    volatile boolean mOnBattery = false;
1290    volatile int mFactoryTest;
1291
1292    @GuardedBy("this") boolean mBooting = false;
1293    @GuardedBy("this") boolean mCallFinishBooting = false;
1294    @GuardedBy("this") boolean mBootAnimationComplete = false;
1295    @GuardedBy("this") boolean mLaunchWarningShown = false;
1296    @GuardedBy("this") boolean mCheckedForSetup = false;
1297
1298    final Context mContext;
1299
1300    /**
1301     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1302     * change at runtime. Use mContext for non-UI purposes.
1303     */
1304    final Context mUiContext;
1305
1306    /**
1307     * The time at which we will allow normal application switches again,
1308     * after a call to {@link #stopAppSwitches()}.
1309     */
1310    long mAppSwitchesAllowedTime;
1311
1312    /**
1313     * This is set to true after the first switch after mAppSwitchesAllowedTime
1314     * is set; any switches after that will clear the time.
1315     */
1316    boolean mDidAppSwitch;
1317
1318    /**
1319     * Last time (in uptime) at which we checked for power usage.
1320     */
1321    long mLastPowerCheckUptime;
1322
1323    /**
1324     * Set while we are wanting to sleep, to prevent any
1325     * activities from being started/resumed.
1326     *
1327     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1328     *
1329     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1330     * while in the sleep state until there is a pending transition out of sleep, in which case
1331     * mSleeping is set to false, and remains false while awake.
1332     *
1333     * Whether mSleeping can quickly toggled between true/false without the device actually
1334     * display changing states is undefined.
1335     */
1336    private boolean mSleeping = false;
1337
1338    /**
1339     * The process state used for processes that are running the top activities.
1340     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1341     */
1342    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1343
1344    /**
1345     * Set while we are running a voice interaction.  This overrides
1346     * sleeping while it is active.
1347     */
1348    IVoiceInteractionSession mRunningVoice;
1349
1350    /**
1351     * For some direct access we need to power manager.
1352     */
1353    PowerManagerInternal mLocalPowerManager;
1354
1355    /**
1356     * We want to hold a wake lock while running a voice interaction session, since
1357     * this may happen with the screen off and we need to keep the CPU running to
1358     * be able to continue to interact with the user.
1359     */
1360    PowerManager.WakeLock mVoiceWakeLock;
1361
1362    /**
1363     * State of external calls telling us if the device is awake or asleep.
1364     */
1365    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1366
1367    /**
1368     * Set if we are shutting down the system, similar to sleeping.
1369     */
1370    boolean mShuttingDown = false;
1371
1372    /**
1373     * Current sequence id for oom_adj computation traversal.
1374     */
1375    int mAdjSeq = 0;
1376
1377    /**
1378     * Current sequence id for process LRU updating.
1379     */
1380    int mLruSeq = 0;
1381
1382    /**
1383     * Keep track of the non-cached/empty process we last found, to help
1384     * determine how to distribute cached/empty processes next time.
1385     */
1386    int mNumNonCachedProcs = 0;
1387
1388    /**
1389     * Keep track of the number of cached hidden procs, to balance oom adj
1390     * distribution between those and empty procs.
1391     */
1392    int mNumCachedHiddenProcs = 0;
1393
1394    /**
1395     * Keep track of the number of service processes we last found, to
1396     * determine on the next iteration which should be B services.
1397     */
1398    int mNumServiceProcs = 0;
1399    int mNewNumAServiceProcs = 0;
1400    int mNewNumServiceProcs = 0;
1401
1402    /**
1403     * Allow the current computed overall memory level of the system to go down?
1404     * This is set to false when we are killing processes for reasons other than
1405     * memory management, so that the now smaller process list will not be taken as
1406     * an indication that memory is tighter.
1407     */
1408    boolean mAllowLowerMemLevel = false;
1409
1410    /**
1411     * The last computed memory level, for holding when we are in a state that
1412     * processes are going away for other reasons.
1413     */
1414    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1415
1416    /**
1417     * The last total number of process we have, to determine if changes actually look
1418     * like a shrinking number of process due to lower RAM.
1419     */
1420    int mLastNumProcesses;
1421
1422    /**
1423     * The uptime of the last time we performed idle maintenance.
1424     */
1425    long mLastIdleTime = SystemClock.uptimeMillis();
1426
1427    /**
1428     * Total time spent with RAM that has been added in the past since the last idle time.
1429     */
1430    long mLowRamTimeSinceLastIdle = 0;
1431
1432    /**
1433     * If RAM is currently low, when that horrible situation started.
1434     */
1435    long mLowRamStartTime = 0;
1436
1437    /**
1438     * For reporting to battery stats the current top application.
1439     */
1440    private String mCurResumedPackage = null;
1441    private int mCurResumedUid = -1;
1442
1443    /**
1444     * For reporting to battery stats the apps currently running foreground
1445     * service.  The ProcessMap is package/uid tuples; each of these contain
1446     * an array of the currently foreground processes.
1447     */
1448    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1449            = new ProcessMap<ArrayList<ProcessRecord>>();
1450
1451    /**
1452     * Set if the systemServer made a call to enterSafeMode.
1453     */
1454    boolean mSafeMode;
1455
1456    /**
1457     * If true, we are running under a test environment so will sample PSS from processes
1458     * much more rapidly to try to collect better data when the tests are rapidly
1459     * running through apps.
1460     */
1461    boolean mTestPssMode = false;
1462
1463    String mDebugApp = null;
1464    boolean mWaitForDebugger = false;
1465    boolean mDebugTransient = false;
1466    String mOrigDebugApp = null;
1467    boolean mOrigWaitForDebugger = false;
1468    boolean mAlwaysFinishActivities = false;
1469    boolean mForceResizableActivities;
1470    /**
1471     * Flag that indicates if multi-window is enabled.
1472     *
1473     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1474     * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1475     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1476     * At least one of the forms of multi-window must be enabled in order for this flag to be
1477     * initialized to 'true'.
1478     *
1479     * @see #mSupportsSplitScreenMultiWindow
1480     * @see #mSupportsFreeformWindowManagement
1481     * @see #mSupportsPictureInPicture
1482     * @see #mSupportsMultiDisplay
1483     */
1484    boolean mSupportsMultiWindow;
1485    boolean mSupportsSplitScreenMultiWindow;
1486    boolean mSupportsFreeformWindowManagement;
1487    boolean mSupportsPictureInPicture;
1488    boolean mSupportsMultiDisplay;
1489    boolean mSupportsLeanbackOnly;
1490    IActivityController mController = null;
1491    boolean mControllerIsAMonkey = false;
1492    String mProfileApp = null;
1493    ProcessRecord mProfileProc = null;
1494    ProfilerInfo mProfilerInfo = null;
1495    int mProfileType = 0;
1496    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1497    String mMemWatchDumpProcName;
1498    String mMemWatchDumpFile;
1499    int mMemWatchDumpPid;
1500    int mMemWatchDumpUid;
1501    String mTrackAllocationApp = null;
1502    String mNativeDebuggingApp = null;
1503
1504    final long[] mTmpLong = new long[2];
1505
1506    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1507
1508    /**
1509     * A global counter for generating sequence numbers.
1510     * This value will be used when incrementing sequence numbers in individual uidRecords.
1511     *
1512     * Having a global counter ensures that seq numbers are monotonically increasing for a
1513     * particular uid even when the uidRecord is re-created.
1514     */
1515    @GuardedBy("this")
1516    @VisibleForTesting
1517    long mProcStateSeqCounter = 0;
1518
1519    private final Injector mInjector;
1520
1521    static final class ProcessChangeItem {
1522        static final int CHANGE_ACTIVITIES = 1<<0;
1523        int changes;
1524        int uid;
1525        int pid;
1526        int processState;
1527        boolean foregroundActivities;
1528    }
1529
1530    static final class UidObserverRegistration {
1531        final int uid;
1532        final String pkg;
1533        final int which;
1534        final int cutpoint;
1535
1536        final SparseIntArray lastProcStates;
1537
1538        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1539            uid = _uid;
1540            pkg = _pkg;
1541            which = _which;
1542            cutpoint = _cutpoint;
1543            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1544                lastProcStates = new SparseIntArray();
1545            } else {
1546                lastProcStates = null;
1547            }
1548        }
1549    }
1550
1551    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1552    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1553
1554    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1555    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1556
1557    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1558    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1559
1560    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1561    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1562
1563    OomAdjObserver mCurOomAdjObserver;
1564    int mCurOomAdjUid;
1565
1566    interface OomAdjObserver {
1567        void onOomAdjMessage(String msg);
1568    }
1569
1570    /**
1571     * Runtime CPU use collection thread.  This object's lock is used to
1572     * perform synchronization with the thread (notifying it to run).
1573     */
1574    final Thread mProcessCpuThread;
1575
1576    /**
1577     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1578     * Must acquire this object's lock when accessing it.
1579     * NOTE: this lock will be held while doing long operations (trawling
1580     * through all processes in /proc), so it should never be acquired by
1581     * any critical paths such as when holding the main activity manager lock.
1582     */
1583    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1584            MONITOR_THREAD_CPU_USAGE);
1585    final AtomicLong mLastCpuTime = new AtomicLong(0);
1586    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1587    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1588
1589    long mLastWriteTime = 0;
1590
1591    /**
1592     * Used to retain an update lock when the foreground activity is in
1593     * immersive mode.
1594     */
1595    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1596
1597    /**
1598     * Set to true after the system has finished booting.
1599     */
1600    boolean mBooted = false;
1601
1602    WindowManagerService mWindowManager;
1603    final ActivityThread mSystemThread;
1604
1605    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1606        final ProcessRecord mApp;
1607        final int mPid;
1608        final IApplicationThread mAppThread;
1609
1610        AppDeathRecipient(ProcessRecord app, int pid,
1611                IApplicationThread thread) {
1612            if (DEBUG_ALL) Slog.v(
1613                TAG, "New death recipient " + this
1614                + " for thread " + thread.asBinder());
1615            mApp = app;
1616            mPid = pid;
1617            mAppThread = thread;
1618        }
1619
1620        @Override
1621        public void binderDied() {
1622            if (DEBUG_ALL) Slog.v(
1623                TAG, "Death received in " + this
1624                + " for thread " + mAppThread.asBinder());
1625            synchronized(ActivityManagerService.this) {
1626                appDiedLocked(mApp, mPid, mAppThread, true);
1627            }
1628        }
1629    }
1630
1631    static final int SHOW_ERROR_UI_MSG = 1;
1632    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1633    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1634    static final int UPDATE_CONFIGURATION_MSG = 4;
1635    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1636    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1637    static final int SERVICE_TIMEOUT_MSG = 12;
1638    static final int UPDATE_TIME_ZONE = 13;
1639    static final int SHOW_UID_ERROR_UI_MSG = 14;
1640    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1641    static final int PROC_START_TIMEOUT_MSG = 20;
1642    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1643    static final int KILL_APPLICATION_MSG = 22;
1644    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1645    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1646    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1647    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1648    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1649    static final int CLEAR_DNS_CACHE_MSG = 28;
1650    static final int UPDATE_HTTP_PROXY_MSG = 29;
1651    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1652    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1653    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1654    static final int REPORT_MEM_USAGE_MSG = 33;
1655    static final int REPORT_USER_SWITCH_MSG = 34;
1656    static final int CONTINUE_USER_SWITCH_MSG = 35;
1657    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1658    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1659    static final int PERSIST_URI_GRANTS_MSG = 38;
1660    static final int REQUEST_ALL_PSS_MSG = 39;
1661    static final int START_PROFILES_MSG = 40;
1662    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1663    static final int SYSTEM_USER_START_MSG = 42;
1664    static final int SYSTEM_USER_CURRENT_MSG = 43;
1665    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1666    static final int FINISH_BOOTING_MSG = 45;
1667    static final int START_USER_SWITCH_UI_MSG = 46;
1668    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1669    static final int DISMISS_DIALOG_UI_MSG = 48;
1670    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1671    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1672    static final int DELETE_DUMPHEAP_MSG = 51;
1673    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1674    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1675    static final int REPORT_TIME_TRACKER_MSG = 54;
1676    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1677    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1678    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1679    static final int IDLE_UIDS_MSG = 58;
1680    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1681    static final int LOG_STACK_STATE = 60;
1682    static final int VR_MODE_CHANGE_MSG = 61;
1683    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1684    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1685    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1686    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1687    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1688    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1689    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1690    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1691    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1692    static final int START_USER_SWITCH_FG_MSG = 712;
1693    static final int NOTIFY_VR_KEYGUARD_MSG = 74;
1694
1695    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1696    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1697    static final int FIRST_COMPAT_MODE_MSG = 300;
1698    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1699
1700    static ServiceThread sKillThread = null;
1701    static KillHandler sKillHandler = null;
1702
1703    CompatModeDialog mCompatModeDialog;
1704    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1705    long mLastMemUsageReportTime = 0;
1706
1707    /**
1708     * Flag whether the current user is a "monkey", i.e. whether
1709     * the UI is driven by a UI automation tool.
1710     */
1711    private boolean mUserIsMonkey;
1712
1713    /** Flag whether the device has a Recents UI */
1714    boolean mHasRecents;
1715
1716    /** The dimensions of the thumbnails in the Recents UI. */
1717    int mThumbnailWidth;
1718    int mThumbnailHeight;
1719    float mFullscreenThumbnailScale;
1720
1721    final ServiceThread mHandlerThread;
1722    final MainHandler mHandler;
1723    final Handler mUiHandler;
1724
1725    final ActivityManagerConstants mConstants;
1726
1727    PackageManagerInternal mPackageManagerInt;
1728
1729    // VoiceInteraction session ID that changes for each new request except when
1730    // being called for multiwindow assist in a single session.
1731    private int mViSessionId = 1000;
1732
1733    final boolean mPermissionReviewRequired;
1734
1735    private static String sTheRealBuildSerial = Build.UNKNOWN;
1736
1737    /**
1738     * Current global configuration information. Contains general settings for the entire system,
1739     * also corresponds to the merged configuration of the default display.
1740     */
1741    Configuration getGlobalConfiguration() {
1742        return mStackSupervisor.getConfiguration();
1743    }
1744
1745    final class KillHandler extends Handler {
1746        static final int KILL_PROCESS_GROUP_MSG = 4000;
1747
1748        public KillHandler(Looper looper) {
1749            super(looper, null, true);
1750        }
1751
1752        @Override
1753        public void handleMessage(Message msg) {
1754            switch (msg.what) {
1755                case KILL_PROCESS_GROUP_MSG:
1756                {
1757                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1758                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1759                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1760                }
1761                break;
1762
1763                default:
1764                    super.handleMessage(msg);
1765            }
1766        }
1767    }
1768
1769    final class UiHandler extends Handler {
1770        public UiHandler() {
1771            super(com.android.server.UiThread.get().getLooper(), null, true);
1772        }
1773
1774        @Override
1775        public void handleMessage(Message msg) {
1776            switch (msg.what) {
1777            case SHOW_ERROR_UI_MSG: {
1778                mAppErrors.handleShowAppErrorUi(msg);
1779                ensureBootCompleted();
1780            } break;
1781            case SHOW_NOT_RESPONDING_UI_MSG: {
1782                mAppErrors.handleShowAnrUi(msg);
1783                ensureBootCompleted();
1784            } break;
1785            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1786                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1787                synchronized (ActivityManagerService.this) {
1788                    ProcessRecord proc = (ProcessRecord) data.get("app");
1789                    if (proc == null) {
1790                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1791                        break;
1792                    }
1793                    if (proc.crashDialog != null) {
1794                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1795                        return;
1796                    }
1797                    AppErrorResult res = (AppErrorResult) data.get("result");
1798                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1799                        Dialog d = new StrictModeViolationDialog(mUiContext,
1800                                ActivityManagerService.this, res, proc);
1801                        d.show();
1802                        proc.crashDialog = d;
1803                    } else {
1804                        // The device is asleep, so just pretend that the user
1805                        // saw a crash dialog and hit "force quit".
1806                        res.set(0);
1807                    }
1808                }
1809                ensureBootCompleted();
1810            } break;
1811            case SHOW_FACTORY_ERROR_UI_MSG: {
1812                Dialog d = new FactoryErrorDialog(
1813                        mUiContext, msg.getData().getCharSequence("msg"));
1814                d.show();
1815                ensureBootCompleted();
1816            } break;
1817            case WAIT_FOR_DEBUGGER_UI_MSG: {
1818                synchronized (ActivityManagerService.this) {
1819                    ProcessRecord app = (ProcessRecord)msg.obj;
1820                    if (msg.arg1 != 0) {
1821                        if (!app.waitedForDebugger) {
1822                            Dialog d = new AppWaitingForDebuggerDialog(
1823                                    ActivityManagerService.this,
1824                                    mUiContext, app);
1825                            app.waitDialog = d;
1826                            app.waitedForDebugger = true;
1827                            d.show();
1828                        }
1829                    } else {
1830                        if (app.waitDialog != null) {
1831                            app.waitDialog.dismiss();
1832                            app.waitDialog = null;
1833                        }
1834                    }
1835                }
1836            } break;
1837            case SHOW_UID_ERROR_UI_MSG: {
1838                if (mShowDialogs) {
1839                    AlertDialog d = new BaseErrorDialog(mUiContext);
1840                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1841                    d.setCancelable(false);
1842                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1843                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1844                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1845                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1846                    d.show();
1847                }
1848            } break;
1849            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1850                if (mShowDialogs) {
1851                    AlertDialog d = new BaseErrorDialog(mUiContext);
1852                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1853                    d.setCancelable(false);
1854                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1855                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1856                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1857                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1858                    d.show();
1859                }
1860            } break;
1861            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1862                synchronized (ActivityManagerService.this) {
1863                    ActivityRecord ar = (ActivityRecord) msg.obj;
1864                    if (mCompatModeDialog != null) {
1865                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1866                                ar.info.applicationInfo.packageName)) {
1867                            return;
1868                        }
1869                        mCompatModeDialog.dismiss();
1870                        mCompatModeDialog = null;
1871                    }
1872                    if (ar != null && false) {
1873                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1874                                ar.packageName)) {
1875                            int mode = mCompatModePackages.computeCompatModeLocked(
1876                                    ar.info.applicationInfo);
1877                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1878                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1879                                mCompatModeDialog = new CompatModeDialog(
1880                                        ActivityManagerService.this, mUiContext,
1881                                        ar.info.applicationInfo);
1882                                mCompatModeDialog.show();
1883                            }
1884                        }
1885                    }
1886                }
1887                break;
1888            }
1889            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1890                synchronized (ActivityManagerService.this) {
1891                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1892                    if (mUnsupportedDisplaySizeDialog != null) {
1893                        mUnsupportedDisplaySizeDialog.dismiss();
1894                        mUnsupportedDisplaySizeDialog = null;
1895                    }
1896                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1897                            ar.packageName)) {
1898                        // TODO(multi-display): Show dialog on appropriate display.
1899                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1900                                ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1901                        mUnsupportedDisplaySizeDialog.show();
1902                    }
1903                }
1904                break;
1905            }
1906            case START_USER_SWITCH_UI_MSG: {
1907                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1908                break;
1909            }
1910            case DISMISS_DIALOG_UI_MSG: {
1911                final Dialog d = (Dialog) msg.obj;
1912                d.dismiss();
1913                break;
1914            }
1915            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1916                dispatchProcessesChanged();
1917                break;
1918            }
1919            case DISPATCH_PROCESS_DIED_UI_MSG: {
1920                final int pid = msg.arg1;
1921                final int uid = msg.arg2;
1922                dispatchProcessDied(pid, uid);
1923                break;
1924            }
1925            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1926                dispatchUidsChanged();
1927            } break;
1928            case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1929                dispatchOomAdjObserver((String)msg.obj);
1930            } break;
1931            case PUSH_TEMP_WHITELIST_UI_MSG: {
1932                pushTempWhitelist();
1933            } break;
1934            }
1935        }
1936    }
1937
1938    final class MainHandler extends Handler {
1939        public MainHandler(Looper looper) {
1940            super(looper, null, true);
1941        }
1942
1943        @Override
1944        public void handleMessage(Message msg) {
1945            switch (msg.what) {
1946            case UPDATE_CONFIGURATION_MSG: {
1947                final ContentResolver resolver = mContext.getContentResolver();
1948                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1949                        msg.arg1);
1950            } break;
1951            case GC_BACKGROUND_PROCESSES_MSG: {
1952                synchronized (ActivityManagerService.this) {
1953                    performAppGcsIfAppropriateLocked();
1954                }
1955            } break;
1956            case SERVICE_TIMEOUT_MSG: {
1957                mServices.serviceTimeout((ProcessRecord)msg.obj);
1958            } break;
1959            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1960                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1961            } break;
1962            case SERVICE_FOREGROUND_CRASH_MSG: {
1963                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1964            } break;
1965            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1966                RemoteCallbackList<IResultReceiver> callbacks
1967                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
1968                int N = callbacks.beginBroadcast();
1969                for (int i = 0; i < N; i++) {
1970                    try {
1971                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1972                    } catch (RemoteException e) {
1973                    }
1974                }
1975                callbacks.finishBroadcast();
1976            } break;
1977            case UPDATE_TIME_ZONE: {
1978                synchronized (ActivityManagerService.this) {
1979                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1980                        ProcessRecord r = mLruProcesses.get(i);
1981                        if (r.thread != null) {
1982                            try {
1983                                r.thread.updateTimeZone();
1984                            } catch (RemoteException ex) {
1985                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1986                            }
1987                        }
1988                    }
1989                }
1990            } break;
1991            case CLEAR_DNS_CACHE_MSG: {
1992                synchronized (ActivityManagerService.this) {
1993                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1994                        ProcessRecord r = mLruProcesses.get(i);
1995                        if (r.thread != null) {
1996                            try {
1997                                r.thread.clearDnsCache();
1998                            } catch (RemoteException ex) {
1999                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2000                            }
2001                        }
2002                    }
2003                }
2004            } break;
2005            case UPDATE_HTTP_PROXY_MSG: {
2006                ProxyInfo proxy = (ProxyInfo)msg.obj;
2007                String host = "";
2008                String port = "";
2009                String exclList = "";
2010                Uri pacFileUrl = Uri.EMPTY;
2011                if (proxy != null) {
2012                    host = proxy.getHost();
2013                    port = Integer.toString(proxy.getPort());
2014                    exclList = proxy.getExclusionListAsString();
2015                    pacFileUrl = proxy.getPacFileUrl();
2016                }
2017                synchronized (ActivityManagerService.this) {
2018                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2019                        ProcessRecord r = mLruProcesses.get(i);
2020                        if (r.thread != null) {
2021                            try {
2022                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2023                            } catch (RemoteException ex) {
2024                                Slog.w(TAG, "Failed to update http proxy for: " +
2025                                        r.info.processName);
2026                            }
2027                        }
2028                    }
2029                }
2030            } break;
2031            case PROC_START_TIMEOUT_MSG: {
2032                ProcessRecord app = (ProcessRecord)msg.obj;
2033                synchronized (ActivityManagerService.this) {
2034                    processStartTimedOutLocked(app);
2035                }
2036            } break;
2037            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2038                ProcessRecord app = (ProcessRecord)msg.obj;
2039                synchronized (ActivityManagerService.this) {
2040                    processContentProviderPublishTimedOutLocked(app);
2041                }
2042            } break;
2043            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2044                synchronized (ActivityManagerService.this) {
2045                    mActivityStarter.doPendingActivityLaunchesLocked(true);
2046                }
2047            } break;
2048            case KILL_APPLICATION_MSG: {
2049                synchronized (ActivityManagerService.this) {
2050                    final int appId = msg.arg1;
2051                    final int userId = msg.arg2;
2052                    Bundle bundle = (Bundle)msg.obj;
2053                    String pkg = bundle.getString("pkg");
2054                    String reason = bundle.getString("reason");
2055                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2056                            false, userId, reason);
2057                }
2058            } break;
2059            case FINALIZE_PENDING_INTENT_MSG: {
2060                ((PendingIntentRecord)msg.obj).completeFinalize();
2061            } break;
2062            case POST_HEAVY_NOTIFICATION_MSG: {
2063                INotificationManager inm = NotificationManager.getService();
2064                if (inm == null) {
2065                    return;
2066                }
2067
2068                ActivityRecord root = (ActivityRecord)msg.obj;
2069                ProcessRecord process = root.app;
2070                if (process == null) {
2071                    return;
2072                }
2073
2074                try {
2075                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2076                    String text = mContext.getString(R.string.heavy_weight_notification,
2077                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2078                    Notification notification =
2079                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2080                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2081                            .setWhen(0)
2082                            .setOngoing(true)
2083                            .setTicker(text)
2084                            .setColor(mContext.getColor(
2085                                    com.android.internal.R.color.system_notification_accent_color))
2086                            .setContentTitle(text)
2087                            .setContentText(
2088                                    mContext.getText(R.string.heavy_weight_notification_detail))
2089                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2090                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2091                                    new UserHandle(root.userId)))
2092                            .build();
2093                    try {
2094                        inm.enqueueNotificationWithTag("android", "android", null,
2095                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2096                                notification, root.userId);
2097                    } catch (RuntimeException e) {
2098                        Slog.w(ActivityManagerService.TAG,
2099                                "Error showing notification for heavy-weight app", e);
2100                    } catch (RemoteException e) {
2101                    }
2102                } catch (NameNotFoundException e) {
2103                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2104                }
2105            } break;
2106            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2107                INotificationManager inm = NotificationManager.getService();
2108                if (inm == null) {
2109                    return;
2110                }
2111                try {
2112                    inm.cancelNotificationWithTag("android", null,
2113                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2114                } catch (RuntimeException e) {
2115                    Slog.w(ActivityManagerService.TAG,
2116                            "Error canceling notification for service", e);
2117                } catch (RemoteException e) {
2118                }
2119            } break;
2120            case CHECK_EXCESSIVE_POWER_USE_MSG: {
2121                synchronized (ActivityManagerService.this) {
2122                    checkExcessivePowerUsageLocked();
2123                    removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2124                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2125                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2126                }
2127            } break;
2128            case REPORT_MEM_USAGE_MSG: {
2129                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2130                Thread thread = new Thread() {
2131                    @Override public void run() {
2132                        reportMemUsage(memInfos);
2133                    }
2134                };
2135                thread.start();
2136                break;
2137            }
2138            case START_USER_SWITCH_FG_MSG: {
2139                mUserController.startUserInForeground(msg.arg1);
2140                break;
2141            }
2142            case REPORT_USER_SWITCH_MSG: {
2143                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2144                break;
2145            }
2146            case CONTINUE_USER_SWITCH_MSG: {
2147                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2148                break;
2149            }
2150            case USER_SWITCH_TIMEOUT_MSG: {
2151                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2152                break;
2153            }
2154            case IMMERSIVE_MODE_LOCK_MSG: {
2155                final boolean nextState = (msg.arg1 != 0);
2156                if (mUpdateLock.isHeld() != nextState) {
2157                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2158                            "Applying new update lock state '" + nextState
2159                            + "' for " + (ActivityRecord)msg.obj);
2160                    if (nextState) {
2161                        mUpdateLock.acquire();
2162                    } else {
2163                        mUpdateLock.release();
2164                    }
2165                }
2166                break;
2167            }
2168            case PERSIST_URI_GRANTS_MSG: {
2169                writeGrantedUriPermissions();
2170                break;
2171            }
2172            case REQUEST_ALL_PSS_MSG: {
2173                synchronized (ActivityManagerService.this) {
2174                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2175                }
2176                break;
2177            }
2178            case START_PROFILES_MSG: {
2179                synchronized (ActivityManagerService.this) {
2180                    mUserController.startProfilesLocked();
2181                }
2182                break;
2183            }
2184            case UPDATE_TIME_PREFERENCE_MSG: {
2185                // The user's time format preference might have changed.
2186                // For convenience we re-use the Intent extra values.
2187                synchronized (ActivityManagerService.this) {
2188                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2189                        ProcessRecord r = mLruProcesses.get(i);
2190                        if (r.thread != null) {
2191                            try {
2192                                r.thread.updateTimePrefs(msg.arg1);
2193                            } catch (RemoteException ex) {
2194                                Slog.w(TAG, "Failed to update preferences for: "
2195                                        + r.info.processName);
2196                            }
2197                        }
2198                    }
2199                }
2200                break;
2201            }
2202            case SYSTEM_USER_START_MSG: {
2203                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2204                        Integer.toString(msg.arg1), msg.arg1);
2205                mSystemServiceManager.startUser(msg.arg1);
2206                break;
2207            }
2208            case SYSTEM_USER_UNLOCK_MSG: {
2209                final int userId = msg.arg1;
2210                mSystemServiceManager.unlockUser(userId);
2211                synchronized (ActivityManagerService.this) {
2212                    mRecentTasks.loadUserRecentsLocked(userId);
2213                }
2214                if (userId == UserHandle.USER_SYSTEM) {
2215                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2216                }
2217                installEncryptionUnawareProviders(userId);
2218                mUserController.finishUserUnlocked((UserState) msg.obj);
2219                break;
2220            }
2221            case SYSTEM_USER_CURRENT_MSG: {
2222                mBatteryStatsService.noteEvent(
2223                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2224                        Integer.toString(msg.arg2), msg.arg2);
2225                mBatteryStatsService.noteEvent(
2226                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2227                        Integer.toString(msg.arg1), msg.arg1);
2228                mSystemServiceManager.switchUser(msg.arg1);
2229                break;
2230            }
2231            case ENTER_ANIMATION_COMPLETE_MSG: {
2232                synchronized (ActivityManagerService.this) {
2233                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2234                    if (r != null && r.app != null && r.app.thread != null) {
2235                        try {
2236                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2237                        } catch (RemoteException e) {
2238                        }
2239                    }
2240                }
2241                break;
2242            }
2243            case FINISH_BOOTING_MSG: {
2244                if (msg.arg1 != 0) {
2245                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2246                    finishBooting();
2247                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2248                }
2249                if (msg.arg2 != 0) {
2250                    enableScreenAfterBoot();
2251                }
2252                break;
2253            }
2254            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2255                try {
2256                    Locale l = (Locale) msg.obj;
2257                    IBinder service = ServiceManager.getService("mount");
2258                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2259                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2260                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2261                } catch (RemoteException e) {
2262                    Log.e(TAG, "Error storing locale for decryption UI", e);
2263                }
2264                break;
2265            }
2266            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2267                final int uid = msg.arg1;
2268                final byte[] firstPacket = (byte[]) msg.obj;
2269
2270                synchronized (mPidsSelfLocked) {
2271                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2272                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2273                        if (p.uid == uid) {
2274                            try {
2275                                p.thread.notifyCleartextNetwork(firstPacket);
2276                            } catch (RemoteException ignored) {
2277                            }
2278                        }
2279                    }
2280                }
2281                break;
2282            }
2283            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2284                final String procName;
2285                final int uid;
2286                final long memLimit;
2287                final String reportPackage;
2288                synchronized (ActivityManagerService.this) {
2289                    procName = mMemWatchDumpProcName;
2290                    uid = mMemWatchDumpUid;
2291                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2292                    if (val == null) {
2293                        val = mMemWatchProcesses.get(procName, 0);
2294                    }
2295                    if (val != null) {
2296                        memLimit = val.first;
2297                        reportPackage = val.second;
2298                    } else {
2299                        memLimit = 0;
2300                        reportPackage = null;
2301                    }
2302                }
2303                if (procName == null) {
2304                    return;
2305                }
2306
2307                if (DEBUG_PSS) Slog.d(TAG_PSS,
2308                        "Showing dump heap notification from " + procName + "/" + uid);
2309
2310                INotificationManager inm = NotificationManager.getService();
2311                if (inm == null) {
2312                    return;
2313                }
2314
2315                String text = mContext.getString(R.string.dump_heap_notification, procName);
2316
2317
2318                Intent deleteIntent = new Intent();
2319                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2320                Intent intent = new Intent();
2321                intent.setClassName("android", DumpHeapActivity.class.getName());
2322                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2323                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2324                if (reportPackage != null) {
2325                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2326                }
2327                int userId = UserHandle.getUserId(uid);
2328                Notification notification =
2329                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2330                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2331                        .setWhen(0)
2332                        .setOngoing(true)
2333                        .setAutoCancel(true)
2334                        .setTicker(text)
2335                        .setColor(mContext.getColor(
2336                                com.android.internal.R.color.system_notification_accent_color))
2337                        .setContentTitle(text)
2338                        .setContentText(
2339                                mContext.getText(R.string.dump_heap_notification_detail))
2340                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2341                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2342                                new UserHandle(userId)))
2343                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2344                                deleteIntent, 0, UserHandle.SYSTEM))
2345                        .build();
2346
2347                try {
2348                    inm.enqueueNotificationWithTag("android", "android", null,
2349                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2350                            notification, userId);
2351                } catch (RuntimeException e) {
2352                    Slog.w(ActivityManagerService.TAG,
2353                            "Error showing notification for dump heap", e);
2354                } catch (RemoteException e) {
2355                }
2356            } break;
2357            case DELETE_DUMPHEAP_MSG: {
2358                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2359                        null, DumpHeapActivity.JAVA_URI,
2360                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2361                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2362                        UserHandle.myUserId());
2363                synchronized (ActivityManagerService.this) {
2364                    mMemWatchDumpFile = null;
2365                    mMemWatchDumpProcName = null;
2366                    mMemWatchDumpPid = -1;
2367                    mMemWatchDumpUid = -1;
2368                }
2369            } break;
2370            case FOREGROUND_PROFILE_CHANGED_MSG: {
2371                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2372            } break;
2373            case REPORT_TIME_TRACKER_MSG: {
2374                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2375                tracker.deliverResult(mContext);
2376            } break;
2377            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2378                mUserController.dispatchUserSwitchComplete(msg.arg1);
2379            } break;
2380            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2381                mUserController.dispatchLockedBootComplete(msg.arg1);
2382            } break;
2383            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2384                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2385                try {
2386                    connection.shutdown();
2387                } catch (RemoteException e) {
2388                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2389                }
2390                // Only a UiAutomation can set this flag and now that
2391                // it is finished we make sure it is reset to its default.
2392                mUserIsMonkey = false;
2393            } break;
2394            case IDLE_UIDS_MSG: {
2395                idleUids();
2396            } break;
2397            case VR_MODE_CHANGE_MSG: {
2398                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2399                    return;
2400                }
2401                synchronized (ActivityManagerService.this) {
2402                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2403                    mWindowManager.disableNonVrUi(disableNonVrUi);
2404                    if (disableNonVrUi) {
2405                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2406                        // then remove the pinned stack.
2407                        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2408                                PINNED_STACK_ID);
2409                        if (pinnedStack != null) {
2410                            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2411                        }
2412                    }
2413                }
2414            } break;
2415            case NOTIFY_VR_SLEEPING_MSG: {
2416                notifyVrManagerOfSleepState(msg.arg1 != 0);
2417            } break;
2418            case NOTIFY_VR_KEYGUARD_MSG: {
2419                notifyVrManagerOfKeyguardState(msg.arg1 != 0);
2420            } break;
2421            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2422                synchronized (ActivityManagerService.this) {
2423                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2424                        ProcessRecord r = mLruProcesses.get(i);
2425                        if (r.thread != null) {
2426                            try {
2427                                r.thread.handleTrustStorageUpdate();
2428                            } catch (RemoteException ex) {
2429                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2430                                        r.info.processName);
2431                            }
2432                        }
2433                    }
2434                }
2435            } break;
2436            }
2437        }
2438    };
2439
2440    static final int COLLECT_PSS_BG_MSG = 1;
2441
2442    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2443        @Override
2444        public void handleMessage(Message msg) {
2445            switch (msg.what) {
2446            case COLLECT_PSS_BG_MSG: {
2447                long start = SystemClock.uptimeMillis();
2448                MemInfoReader memInfo = null;
2449                synchronized (ActivityManagerService.this) {
2450                    if (mFullPssPending) {
2451                        mFullPssPending = false;
2452                        memInfo = new MemInfoReader();
2453                    }
2454                }
2455                if (memInfo != null) {
2456                    updateCpuStatsNow();
2457                    long nativeTotalPss = 0;
2458                    final List<ProcessCpuTracker.Stats> stats;
2459                    synchronized (mProcessCpuTracker) {
2460                        stats = mProcessCpuTracker.getStats( (st)-> {
2461                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2462                        });
2463                    }
2464                    final int N = stats.size();
2465                    for (int j = 0; j < N; j++) {
2466                        synchronized (mPidsSelfLocked) {
2467                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2468                                // This is one of our own processes; skip it.
2469                                continue;
2470                            }
2471                        }
2472                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2473                    }
2474                    memInfo.readMemInfo();
2475                    synchronized (ActivityManagerService.this) {
2476                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2477                                + (SystemClock.uptimeMillis()-start) + "ms");
2478                        final long cachedKb = memInfo.getCachedSizeKb();
2479                        final long freeKb = memInfo.getFreeSizeKb();
2480                        final long zramKb = memInfo.getZramTotalSizeKb();
2481                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2482                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2483                                kernelKb*1024, nativeTotalPss*1024);
2484                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2485                                nativeTotalPss);
2486                    }
2487                }
2488
2489                int num = 0;
2490                long[] tmp = new long[2];
2491                do {
2492                    ProcessRecord proc;
2493                    int procState;
2494                    int pid;
2495                    long lastPssTime;
2496                    synchronized (ActivityManagerService.this) {
2497                        if (mPendingPssProcesses.size() <= 0) {
2498                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2499                                    "Collected PSS of " + num + " processes in "
2500                                    + (SystemClock.uptimeMillis() - start) + "ms");
2501                            mPendingPssProcesses.clear();
2502                            return;
2503                        }
2504                        proc = mPendingPssProcesses.remove(0);
2505                        procState = proc.pssProcState;
2506                        lastPssTime = proc.lastPssTime;
2507                        if (proc.thread != null && procState == proc.setProcState
2508                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2509                                        < SystemClock.uptimeMillis()) {
2510                            pid = proc.pid;
2511                        } else {
2512                            proc = null;
2513                            pid = 0;
2514                        }
2515                    }
2516                    if (proc != null) {
2517                        long pss = Debug.getPss(pid, tmp, null);
2518                        synchronized (ActivityManagerService.this) {
2519                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2520                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2521                                num++;
2522                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2523                                        SystemClock.uptimeMillis());
2524                            }
2525                        }
2526                    }
2527                } while (true);
2528            }
2529            }
2530        }
2531    };
2532
2533    public void setSystemProcess() {
2534        try {
2535            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2536            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2537            ServiceManager.addService("meminfo", new MemBinder(this));
2538            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2539            ServiceManager.addService("dbinfo", new DbBinder(this));
2540            if (MONITOR_CPU_USAGE) {
2541                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2542            }
2543            ServiceManager.addService("permission", new PermissionController(this));
2544            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2545
2546            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2547                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2548            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2549
2550            synchronized (this) {
2551                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2552                app.persistent = true;
2553                app.pid = MY_PID;
2554                app.maxAdj = ProcessList.SYSTEM_ADJ;
2555                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2556                synchronized (mPidsSelfLocked) {
2557                    mPidsSelfLocked.put(app.pid, app);
2558                }
2559                updateLruProcessLocked(app, false, null);
2560                updateOomAdjLocked();
2561            }
2562        } catch (PackageManager.NameNotFoundException e) {
2563            throw new RuntimeException(
2564                    "Unable to find android system package", e);
2565        }
2566    }
2567
2568    public void setWindowManager(WindowManagerService wm) {
2569        mWindowManager = wm;
2570        mStackSupervisor.setWindowManager(wm);
2571        mActivityStarter.setWindowManager(wm);
2572    }
2573
2574    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2575        mUsageStatsService = usageStatsManager;
2576    }
2577
2578    public void startObservingNativeCrashes() {
2579        final NativeCrashListener ncl = new NativeCrashListener(this);
2580        ncl.start();
2581    }
2582
2583    public IAppOpsService getAppOpsService() {
2584        return mAppOpsService;
2585    }
2586
2587    static class MemBinder extends Binder {
2588        ActivityManagerService mActivityManagerService;
2589        MemBinder(ActivityManagerService activityManagerService) {
2590            mActivityManagerService = activityManagerService;
2591        }
2592
2593        @Override
2594        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2595            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2596                    "meminfo", pw)) return;
2597            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2598        }
2599    }
2600
2601    static class GraphicsBinder extends Binder {
2602        ActivityManagerService mActivityManagerService;
2603        GraphicsBinder(ActivityManagerService activityManagerService) {
2604            mActivityManagerService = activityManagerService;
2605        }
2606
2607        @Override
2608        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2609            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2610                    "gfxinfo", pw)) return;
2611            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2612        }
2613    }
2614
2615    static class DbBinder extends Binder {
2616        ActivityManagerService mActivityManagerService;
2617        DbBinder(ActivityManagerService activityManagerService) {
2618            mActivityManagerService = activityManagerService;
2619        }
2620
2621        @Override
2622        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2623            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2624                    "dbinfo", pw)) return;
2625            mActivityManagerService.dumpDbInfo(fd, pw, args);
2626        }
2627    }
2628
2629    static class CpuBinder extends Binder {
2630        ActivityManagerService mActivityManagerService;
2631        CpuBinder(ActivityManagerService activityManagerService) {
2632            mActivityManagerService = activityManagerService;
2633        }
2634
2635        @Override
2636        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2637            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2638                    "cpuinfo", pw)) return;
2639            synchronized (mActivityManagerService.mProcessCpuTracker) {
2640                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2641                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2642                        SystemClock.uptimeMillis()));
2643            }
2644        }
2645    }
2646
2647    public static final class Lifecycle extends SystemService {
2648        private final ActivityManagerService mService;
2649
2650        public Lifecycle(Context context) {
2651            super(context);
2652            mService = new ActivityManagerService(context);
2653        }
2654
2655        @Override
2656        public void onStart() {
2657            mService.start();
2658        }
2659
2660        @Override
2661        public void onCleanupUser(int userId) {
2662            mService.mBatteryStatsService.onCleanupUser(userId);
2663        }
2664
2665        public ActivityManagerService getService() {
2666            return mService;
2667        }
2668    }
2669
2670    @VisibleForTesting
2671    public ActivityManagerService(Injector injector) {
2672        mInjector = injector;
2673        mContext = mInjector.getContext();
2674        mUiContext = null;
2675        GL_ES_VERSION = 0;
2676        mActivityStarter = null;
2677        mAppErrors = null;
2678        mAppOpsService = mInjector.getAppOpsService(null, null);
2679        mBatteryStatsService = null;
2680        mCompatModePackages = null;
2681        mConstants = null;
2682        mGrantFile = null;
2683        mHandler = null;
2684        mHandlerThread = null;
2685        mIntentFirewall = null;
2686        mKeyguardController = null;
2687        mPermissionReviewRequired = false;
2688        mProcessCpuThread = null;
2689        mProcessStats = null;
2690        mProviderMap = null;
2691        mRecentTasks = null;
2692        mServices = null;
2693        mStackSupervisor = null;
2694        mSystemThread = null;
2695        mTaskChangeNotificationController = null;
2696        mUiHandler = injector.getUiHandler(null);
2697        mUserController = null;
2698        mVrController = null;
2699    }
2700
2701    // Note: This method is invoked on the main thread but may need to attach various
2702    // handlers to other threads.  So take care to be explicit about the looper.
2703    public ActivityManagerService(Context systemContext) {
2704        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2705        mInjector = new Injector();
2706        mContext = systemContext;
2707
2708        mFactoryTest = FactoryTest.getMode();
2709        mSystemThread = ActivityThread.currentActivityThread();
2710        mUiContext = mSystemThread.getSystemUiContext();
2711
2712        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2713
2714        mPermissionReviewRequired = mContext.getResources().getBoolean(
2715                com.android.internal.R.bool.config_permissionReviewRequired);
2716
2717        mHandlerThread = new ServiceThread(TAG,
2718                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2719        mHandlerThread.start();
2720        mHandler = new MainHandler(mHandlerThread.getLooper());
2721        mUiHandler = mInjector.getUiHandler(this);
2722
2723        mConstants = new ActivityManagerConstants(this, mHandler);
2724
2725        /* static; one-time init here */
2726        if (sKillHandler == null) {
2727            sKillThread = new ServiceThread(TAG + ":kill",
2728                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2729            sKillThread.start();
2730            sKillHandler = new KillHandler(sKillThread.getLooper());
2731        }
2732
2733        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2734                "foreground", BROADCAST_FG_TIMEOUT, false);
2735        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2736                "background", BROADCAST_BG_TIMEOUT, true);
2737        mBroadcastQueues[0] = mFgBroadcastQueue;
2738        mBroadcastQueues[1] = mBgBroadcastQueue;
2739
2740        mServices = new ActiveServices(this);
2741        mProviderMap = new ProviderMap(this);
2742        mAppErrors = new AppErrors(mUiContext, this);
2743
2744        // TODO: Move creation of battery stats service outside of activity manager service.
2745        File dataDir = Environment.getDataDirectory();
2746        File systemDir = new File(dataDir, "system");
2747        systemDir.mkdirs();
2748        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2749        mBatteryStatsService.getActiveStatistics().readLocked();
2750        mBatteryStatsService.scheduleWriteToDisk();
2751        mOnBattery = DEBUG_POWER ? true
2752                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2753        mBatteryStatsService.getActiveStatistics().setCallback(this);
2754
2755        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2756
2757        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2758        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2759                new IAppOpsCallback.Stub() {
2760                    @Override public void opChanged(int op, int uid, String packageName) {
2761                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2762                            if (mAppOpsService.checkOperation(op, uid, packageName)
2763                                    != AppOpsManager.MODE_ALLOWED) {
2764                                runInBackgroundDisabled(uid);
2765                            }
2766                        }
2767                    }
2768                });
2769
2770        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2771
2772        mUserController = new UserController(this);
2773
2774        mVrController = new VrController(this);
2775
2776        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2777            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2778
2779        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2780            mUseFifoUiScheduling = true;
2781        }
2782
2783        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2784        mTempConfig.setToDefaults();
2785        mTempConfig.setLocales(LocaleList.getDefault());
2786        mConfigurationSeq = mTempConfig.seq = 1;
2787        mStackSupervisor = createStackSupervisor();
2788        mStackSupervisor.onConfigurationChanged(mTempConfig);
2789        mKeyguardController = mStackSupervisor.mKeyguardController;
2790        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2791        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2792        mTaskChangeNotificationController =
2793                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2794        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2795        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2796
2797        mProcessCpuThread = new Thread("CpuTracker") {
2798            @Override
2799            public void run() {
2800                synchronized (mProcessCpuTracker) {
2801                    mProcessCpuInitLatch.countDown();
2802                    mProcessCpuTracker.init();
2803                }
2804                while (true) {
2805                    try {
2806                        try {
2807                            synchronized(this) {
2808                                final long now = SystemClock.uptimeMillis();
2809                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2810                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2811                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2812                                //        + ", write delay=" + nextWriteDelay);
2813                                if (nextWriteDelay < nextCpuDelay) {
2814                                    nextCpuDelay = nextWriteDelay;
2815                                }
2816                                if (nextCpuDelay > 0) {
2817                                    mProcessCpuMutexFree.set(true);
2818                                    this.wait(nextCpuDelay);
2819                                }
2820                            }
2821                        } catch (InterruptedException e) {
2822                        }
2823                        updateCpuStatsNow();
2824                    } catch (Exception e) {
2825                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2826                    }
2827                }
2828            }
2829        };
2830
2831        Watchdog.getInstance().addMonitor(this);
2832        Watchdog.getInstance().addThread(mHandler);
2833    }
2834
2835    protected ActivityStackSupervisor createStackSupervisor() {
2836        return new ActivityStackSupervisor(this, mHandler.getLooper());
2837    }
2838
2839    public void setSystemServiceManager(SystemServiceManager mgr) {
2840        mSystemServiceManager = mgr;
2841    }
2842
2843    public void setInstaller(Installer installer) {
2844        mInstaller = installer;
2845    }
2846
2847    private void start() {
2848        removeAllProcessGroups();
2849        mProcessCpuThread.start();
2850
2851        mBatteryStatsService.publish();
2852        mAppOpsService.publish(mContext);
2853        Slog.d("AppOps", "AppOpsService published");
2854        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2855        // Wait for the synchronized block started in mProcessCpuThread,
2856        // so that any other acccess to mProcessCpuTracker from main thread
2857        // will be blocked during mProcessCpuTracker initialization.
2858        try {
2859            mProcessCpuInitLatch.await();
2860        } catch (InterruptedException e) {
2861            Slog.wtf(TAG, "Interrupted wait during start", e);
2862            Thread.currentThread().interrupt();
2863            throw new IllegalStateException("Interrupted wait during start");
2864        }
2865    }
2866
2867    void onUserStoppedLocked(int userId) {
2868        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2869    }
2870
2871    public void initPowerManagement() {
2872        mStackSupervisor.initPowerManagement();
2873        mBatteryStatsService.initPowerManagement();
2874        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2875        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2876        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2877        mVoiceWakeLock.setReferenceCounted(false);
2878    }
2879
2880    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2881        if (mBackgroundLaunchBroadcasts == null) {
2882            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2883        }
2884        return mBackgroundLaunchBroadcasts;
2885    }
2886
2887    @Override
2888    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2889            throws RemoteException {
2890        if (code == SYSPROPS_TRANSACTION) {
2891            // We need to tell all apps about the system property change.
2892            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2893            synchronized(this) {
2894                final int NP = mProcessNames.getMap().size();
2895                for (int ip=0; ip<NP; ip++) {
2896                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2897                    final int NA = apps.size();
2898                    for (int ia=0; ia<NA; ia++) {
2899                        ProcessRecord app = apps.valueAt(ia);
2900                        if (app.thread != null) {
2901                            procs.add(app.thread.asBinder());
2902                        }
2903                    }
2904                }
2905            }
2906
2907            int N = procs.size();
2908            for (int i=0; i<N; i++) {
2909                Parcel data2 = Parcel.obtain();
2910                try {
2911                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2912                            Binder.FLAG_ONEWAY);
2913                } catch (RemoteException e) {
2914                }
2915                data2.recycle();
2916            }
2917        }
2918        try {
2919            return super.onTransact(code, data, reply, flags);
2920        } catch (RuntimeException e) {
2921            // The activity manager only throws security exceptions, so let's
2922            // log all others.
2923            if (!(e instanceof SecurityException)) {
2924                Slog.wtf(TAG, "Activity Manager Crash."
2925                        + " UID:" + Binder.getCallingUid()
2926                        + " PID:" + Binder.getCallingPid()
2927                        + " TRANS:" + code, e);
2928            }
2929            throw e;
2930        }
2931    }
2932
2933    void updateCpuStats() {
2934        final long now = SystemClock.uptimeMillis();
2935        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2936            return;
2937        }
2938        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2939            synchronized (mProcessCpuThread) {
2940                mProcessCpuThread.notify();
2941            }
2942        }
2943    }
2944
2945    void updateCpuStatsNow() {
2946        synchronized (mProcessCpuTracker) {
2947            mProcessCpuMutexFree.set(false);
2948            final long now = SystemClock.uptimeMillis();
2949            boolean haveNewCpuStats = false;
2950
2951            if (MONITOR_CPU_USAGE &&
2952                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2953                mLastCpuTime.set(now);
2954                mProcessCpuTracker.update();
2955                if (mProcessCpuTracker.hasGoodLastStats()) {
2956                    haveNewCpuStats = true;
2957                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2958                    //Slog.i(TAG, "Total CPU usage: "
2959                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2960
2961                    // Slog the cpu usage if the property is set.
2962                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2963                        int user = mProcessCpuTracker.getLastUserTime();
2964                        int system = mProcessCpuTracker.getLastSystemTime();
2965                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2966                        int irq = mProcessCpuTracker.getLastIrqTime();
2967                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2968                        int idle = mProcessCpuTracker.getLastIdleTime();
2969
2970                        int total = user + system + iowait + irq + softIrq + idle;
2971                        if (total == 0) total = 1;
2972
2973                        EventLog.writeEvent(EventLogTags.CPU,
2974                                ((user+system+iowait+irq+softIrq) * 100) / total,
2975                                (user * 100) / total,
2976                                (system * 100) / total,
2977                                (iowait * 100) / total,
2978                                (irq * 100) / total,
2979                                (softIrq * 100) / total);
2980                    }
2981                }
2982            }
2983
2984            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2985            synchronized(bstats) {
2986                synchronized(mPidsSelfLocked) {
2987                    if (haveNewCpuStats) {
2988                        if (bstats.startAddingCpuLocked()) {
2989                            int totalUTime = 0;
2990                            int totalSTime = 0;
2991                            final int N = mProcessCpuTracker.countStats();
2992                            for (int i=0; i<N; i++) {
2993                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2994                                if (!st.working) {
2995                                    continue;
2996                                }
2997                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2998                                totalUTime += st.rel_utime;
2999                                totalSTime += st.rel_stime;
3000                                if (pr != null) {
3001                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3002                                    if (ps == null || !ps.isActive()) {
3003                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3004                                                pr.info.uid, pr.processName);
3005                                    }
3006                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3007                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3008                                    if (pr.lastCpuTime == 0) {
3009                                        pr.lastCpuTime = pr.curCpuTime;
3010                                    }
3011                                } else {
3012                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3013                                    if (ps == null || !ps.isActive()) {
3014                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3015                                                bstats.mapUid(st.uid), st.name);
3016                                    }
3017                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3018                                }
3019                            }
3020                            final int userTime = mProcessCpuTracker.getLastUserTime();
3021                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3022                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3023                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3024                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3025                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3026                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3027                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3028                        }
3029                    }
3030                }
3031
3032                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3033                    mLastWriteTime = now;
3034                    mBatteryStatsService.scheduleWriteToDisk();
3035                }
3036            }
3037        }
3038    }
3039
3040    @Override
3041    public void batteryNeedsCpuUpdate() {
3042        updateCpuStatsNow();
3043    }
3044
3045    @Override
3046    public void batteryPowerChanged(boolean onBattery) {
3047        // When plugging in, update the CPU stats first before changing
3048        // the plug state.
3049        updateCpuStatsNow();
3050        synchronized (this) {
3051            synchronized(mPidsSelfLocked) {
3052                mOnBattery = DEBUG_POWER ? true : onBattery;
3053            }
3054        }
3055    }
3056
3057    @Override
3058    public void batterySendBroadcast(Intent intent) {
3059        synchronized (this) {
3060            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3061                    AppOpsManager.OP_NONE, null, false, false,
3062                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3063        }
3064    }
3065
3066    /**
3067     * Initialize the application bind args. These are passed to each
3068     * process when the bindApplication() IPC is sent to the process. They're
3069     * lazily setup to make sure the services are running when they're asked for.
3070     */
3071    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3072        // Isolated processes won't get this optimization, so that we don't
3073        // violate the rules about which services they have access to.
3074        if (isolated) {
3075            if (mIsolatedAppBindArgs == null) {
3076                mIsolatedAppBindArgs = new HashMap<>();
3077                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3078            }
3079            return mIsolatedAppBindArgs;
3080        }
3081
3082        if (mAppBindArgs == null) {
3083            mAppBindArgs = new HashMap<>();
3084
3085            // Setup the application init args
3086            mAppBindArgs.put("package", ServiceManager.getService("package"));
3087            mAppBindArgs.put("window", ServiceManager.getService("window"));
3088            mAppBindArgs.put(Context.ALARM_SERVICE,
3089                    ServiceManager.getService(Context.ALARM_SERVICE));
3090        }
3091        return mAppBindArgs;
3092    }
3093
3094    /**
3095     * Update AMS states when an activity is resumed. This should only be called by
3096     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3097     */
3098    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3099        final TaskRecord task = r.getTask();
3100        if (task.isApplicationTask()) {
3101            if (mCurAppTimeTracker != r.appTimeTracker) {
3102                // We are switching app tracking.  Complete the current one.
3103                if (mCurAppTimeTracker != null) {
3104                    mCurAppTimeTracker.stop();
3105                    mHandler.obtainMessage(
3106                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3107                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3108                    mCurAppTimeTracker = null;
3109                }
3110                if (r.appTimeTracker != null) {
3111                    mCurAppTimeTracker = r.appTimeTracker;
3112                    startTimeTrackingFocusedActivityLocked();
3113                }
3114            } else {
3115                startTimeTrackingFocusedActivityLocked();
3116            }
3117        } else {
3118            r.appTimeTracker = null;
3119        }
3120        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3121        // TODO: Probably not, because we don't want to resume voice on switching
3122        // back to this activity
3123        if (task.voiceInteractor != null) {
3124            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3125        } else {
3126            finishRunningVoiceLocked();
3127
3128            if (mLastResumedActivity != null) {
3129                final IVoiceInteractionSession session;
3130
3131                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3132                if (lastResumedActivityTask != null
3133                        && lastResumedActivityTask.voiceSession != null) {
3134                    session = lastResumedActivityTask.voiceSession;
3135                } else {
3136                    session = mLastResumedActivity.voiceSession;
3137                }
3138
3139                if (session != null) {
3140                    // We had been in a voice interaction session, but now focused has
3141                    // move to something different.  Just finish the session, we can't
3142                    // return to it and retain the proper state and synchronization with
3143                    // the voice interaction service.
3144                    finishVoiceTask(session);
3145                }
3146            }
3147        }
3148
3149        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3150            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3151            mHandler.obtainMessage(
3152                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3153        }
3154        mLastResumedActivity = r;
3155
3156        mWindowManager.setFocusedApp(r.appToken, true);
3157
3158        applyUpdateLockStateLocked(r);
3159        applyUpdateVrModeLocked(r);
3160
3161        EventLogTags.writeAmSetResumedActivity(
3162                r == null ? -1 : r.userId,
3163                r == null ? "NULL" : r.shortComponentName,
3164                reason);
3165    }
3166
3167    @Override
3168    public void setFocusedStack(int stackId) {
3169        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3170        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3171        final long callingId = Binder.clearCallingIdentity();
3172        try {
3173            synchronized (this) {
3174                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3175                if (stack == null) {
3176                    return;
3177                }
3178                final ActivityRecord r = stack.topRunningActivityLocked();
3179                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3180                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3181                }
3182            }
3183        } finally {
3184            Binder.restoreCallingIdentity(callingId);
3185        }
3186    }
3187
3188    @Override
3189    public void setFocusedTask(int taskId) {
3190        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3191        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3192        final long callingId = Binder.clearCallingIdentity();
3193        try {
3194            synchronized (this) {
3195                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3196                if (task == null) {
3197                    return;
3198                }
3199                final ActivityRecord r = task.topRunningActivityLocked();
3200                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3201                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3202                }
3203            }
3204        } finally {
3205            Binder.restoreCallingIdentity(callingId);
3206        }
3207    }
3208
3209    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3210    @Override
3211    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3212        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3213        mTaskChangeNotificationController.registerTaskStackListener(listener);
3214    }
3215
3216    /**
3217     * Unregister a task stack listener so that it stops receiving callbacks.
3218     */
3219    @Override
3220    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3221         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3222         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3223     }
3224
3225    @Override
3226    public void notifyActivityDrawn(IBinder token) {
3227        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3228        synchronized (this) {
3229            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3230            if (r != null) {
3231                r.getStack().notifyActivityDrawnLocked(r);
3232            }
3233        }
3234    }
3235
3236    final void applyUpdateLockStateLocked(ActivityRecord r) {
3237        // Modifications to the UpdateLock state are done on our handler, outside
3238        // the activity manager's locks.  The new state is determined based on the
3239        // state *now* of the relevant activity record.  The object is passed to
3240        // the handler solely for logging detail, not to be consulted/modified.
3241        final boolean nextState = r != null && r.immersive;
3242        mHandler.sendMessage(
3243                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3244    }
3245
3246    final void applyUpdateVrModeLocked(ActivityRecord r) {
3247        // VR apps are expected to run in a main display. If an app is turning on VR for
3248        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3249        // fullscreen stack before enabling VR Mode.
3250        // TODO: The goal of this code is to keep the VR app on the main display. When the
3251        // stack implementation changes in the future, keep in mind that the use of the fullscreen
3252        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3253        // option would be a better choice here.
3254        if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
3255            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3256                    + " to main stack for VR");
3257            moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
3258        }
3259        mHandler.sendMessage(
3260                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3261    }
3262
3263    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3264        mHandler.sendMessage(
3265                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3266    }
3267
3268    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3269        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3270        if (vrService == null) {
3271            return;
3272        }
3273        vrService.onSleepStateChanged(isSleeping);
3274    }
3275
3276    private void sendNotifyVrManagerOfKeyguardState(boolean isShowing) {
3277        mHandler.sendMessage(
3278                mHandler.obtainMessage(NOTIFY_VR_KEYGUARD_MSG, isShowing ? 1 : 0, 0));
3279    }
3280
3281    private void notifyVrManagerOfKeyguardState(boolean isShowing) {
3282        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3283        if (vrService == null) {
3284            return;
3285        }
3286        vrService.onKeyguardStateChanged(isShowing);
3287    }
3288
3289    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3290        Message msg = Message.obtain();
3291        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3292        msg.obj = r.getTask().askedCompatMode ? null : r;
3293        mUiHandler.sendMessage(msg);
3294    }
3295
3296    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3297        final Configuration globalConfig = getGlobalConfiguration();
3298        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3299                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3300            final Message msg = Message.obtain();
3301            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3302            msg.obj = r;
3303            mUiHandler.sendMessage(msg);
3304        }
3305    }
3306
3307    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3308            String what, Object obj, ProcessRecord srcApp) {
3309        app.lastActivityTime = now;
3310
3311        if (app.activities.size() > 0) {
3312            // Don't want to touch dependent processes that are hosting activities.
3313            return index;
3314        }
3315
3316        int lrui = mLruProcesses.lastIndexOf(app);
3317        if (lrui < 0) {
3318            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3319                    + what + " " + obj + " from " + srcApp);
3320            return index;
3321        }
3322
3323        if (lrui >= index) {
3324            // Don't want to cause this to move dependent processes *back* in the
3325            // list as if they were less frequently used.
3326            return index;
3327        }
3328
3329        if (lrui >= mLruProcessActivityStart) {
3330            // Don't want to touch dependent processes that are hosting activities.
3331            return index;
3332        }
3333
3334        mLruProcesses.remove(lrui);
3335        if (index > 0) {
3336            index--;
3337        }
3338        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3339                + " in LRU list: " + app);
3340        mLruProcesses.add(index, app);
3341        return index;
3342    }
3343
3344    static void killProcessGroup(int uid, int pid) {
3345        if (sKillHandler != null) {
3346            sKillHandler.sendMessage(
3347                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3348        } else {
3349            Slog.w(TAG, "Asked to kill process group before system bringup!");
3350            Process.killProcessGroup(uid, pid);
3351        }
3352    }
3353
3354    final void removeLruProcessLocked(ProcessRecord app) {
3355        int lrui = mLruProcesses.lastIndexOf(app);
3356        if (lrui >= 0) {
3357            if (!app.killed) {
3358                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3359                killProcessQuiet(app.pid);
3360                killProcessGroup(app.uid, app.pid);
3361            }
3362            if (lrui <= mLruProcessActivityStart) {
3363                mLruProcessActivityStart--;
3364            }
3365            if (lrui <= mLruProcessServiceStart) {
3366                mLruProcessServiceStart--;
3367            }
3368            mLruProcesses.remove(lrui);
3369        }
3370    }
3371
3372    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3373            ProcessRecord client) {
3374        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3375                || app.treatLikeActivity;
3376        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3377        if (!activityChange && hasActivity) {
3378            // The process has activities, so we are only allowing activity-based adjustments
3379            // to move it.  It should be kept in the front of the list with other
3380            // processes that have activities, and we don't want those to change their
3381            // order except due to activity operations.
3382            return;
3383        }
3384
3385        mLruSeq++;
3386        final long now = SystemClock.uptimeMillis();
3387        app.lastActivityTime = now;
3388
3389        // First a quick reject: if the app is already at the position we will
3390        // put it, then there is nothing to do.
3391        if (hasActivity) {
3392            final int N = mLruProcesses.size();
3393            if (N > 0 && mLruProcesses.get(N-1) == app) {
3394                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3395                return;
3396            }
3397        } else {
3398            if (mLruProcessServiceStart > 0
3399                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3400                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3401                return;
3402            }
3403        }
3404
3405        int lrui = mLruProcesses.lastIndexOf(app);
3406
3407        if (app.persistent && lrui >= 0) {
3408            // We don't care about the position of persistent processes, as long as
3409            // they are in the list.
3410            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3411            return;
3412        }
3413
3414        /* In progress: compute new position first, so we can avoid doing work
3415           if the process is not actually going to move.  Not yet working.
3416        int addIndex;
3417        int nextIndex;
3418        boolean inActivity = false, inService = false;
3419        if (hasActivity) {
3420            // Process has activities, put it at the very tipsy-top.
3421            addIndex = mLruProcesses.size();
3422            nextIndex = mLruProcessServiceStart;
3423            inActivity = true;
3424        } else if (hasService) {
3425            // Process has services, put it at the top of the service list.
3426            addIndex = mLruProcessActivityStart;
3427            nextIndex = mLruProcessServiceStart;
3428            inActivity = true;
3429            inService = true;
3430        } else  {
3431            // Process not otherwise of interest, it goes to the top of the non-service area.
3432            addIndex = mLruProcessServiceStart;
3433            if (client != null) {
3434                int clientIndex = mLruProcesses.lastIndexOf(client);
3435                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3436                        + app);
3437                if (clientIndex >= 0 && addIndex > clientIndex) {
3438                    addIndex = clientIndex;
3439                }
3440            }
3441            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3442        }
3443
3444        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3445                + mLruProcessActivityStart + "): " + app);
3446        */
3447
3448        if (lrui >= 0) {
3449            if (lrui < mLruProcessActivityStart) {
3450                mLruProcessActivityStart--;
3451            }
3452            if (lrui < mLruProcessServiceStart) {
3453                mLruProcessServiceStart--;
3454            }
3455            /*
3456            if (addIndex > lrui) {
3457                addIndex--;
3458            }
3459            if (nextIndex > lrui) {
3460                nextIndex--;
3461            }
3462            */
3463            mLruProcesses.remove(lrui);
3464        }
3465
3466        /*
3467        mLruProcesses.add(addIndex, app);
3468        if (inActivity) {
3469            mLruProcessActivityStart++;
3470        }
3471        if (inService) {
3472            mLruProcessActivityStart++;
3473        }
3474        */
3475
3476        int nextIndex;
3477        if (hasActivity) {
3478            final int N = mLruProcesses.size();
3479            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3480                // Process doesn't have activities, but has clients with
3481                // activities...  move it up, but one below the top (the top
3482                // should always have a real activity).
3483                if (DEBUG_LRU) Slog.d(TAG_LRU,
3484                        "Adding to second-top of LRU activity list: " + app);
3485                mLruProcesses.add(N - 1, app);
3486                // To keep it from spamming the LRU list (by making a bunch of clients),
3487                // we will push down any other entries owned by the app.
3488                final int uid = app.info.uid;
3489                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3490                    ProcessRecord subProc = mLruProcesses.get(i);
3491                    if (subProc.info.uid == uid) {
3492                        // We want to push this one down the list.  If the process after
3493                        // it is for the same uid, however, don't do so, because we don't
3494                        // want them internally to be re-ordered.
3495                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3496                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3497                                    "Pushing uid " + uid + " swapping at " + i + ": "
3498                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3499                            ProcessRecord tmp = mLruProcesses.get(i);
3500                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3501                            mLruProcesses.set(i - 1, tmp);
3502                            i--;
3503                        }
3504                    } else {
3505                        // A gap, we can stop here.
3506                        break;
3507                    }
3508                }
3509            } else {
3510                // Process has activities, put it at the very tipsy-top.
3511                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3512                mLruProcesses.add(app);
3513            }
3514            nextIndex = mLruProcessServiceStart;
3515        } else if (hasService) {
3516            // Process has services, put it at the top of the service list.
3517            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3518            mLruProcesses.add(mLruProcessActivityStart, app);
3519            nextIndex = mLruProcessServiceStart;
3520            mLruProcessActivityStart++;
3521        } else  {
3522            // Process not otherwise of interest, it goes to the top of the non-service area.
3523            int index = mLruProcessServiceStart;
3524            if (client != null) {
3525                // If there is a client, don't allow the process to be moved up higher
3526                // in the list than that client.
3527                int clientIndex = mLruProcesses.lastIndexOf(client);
3528                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3529                        + " when updating " + app);
3530                if (clientIndex <= lrui) {
3531                    // Don't allow the client index restriction to push it down farther in the
3532                    // list than it already is.
3533                    clientIndex = lrui;
3534                }
3535                if (clientIndex >= 0 && index > clientIndex) {
3536                    index = clientIndex;
3537                }
3538            }
3539            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3540            mLruProcesses.add(index, app);
3541            nextIndex = index-1;
3542            mLruProcessActivityStart++;
3543            mLruProcessServiceStart++;
3544        }
3545
3546        // If the app is currently using a content provider or service,
3547        // bump those processes as well.
3548        for (int j=app.connections.size()-1; j>=0; j--) {
3549            ConnectionRecord cr = app.connections.valueAt(j);
3550            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3551                    && cr.binding.service.app != null
3552                    && cr.binding.service.app.lruSeq != mLruSeq
3553                    && !cr.binding.service.app.persistent) {
3554                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3555                        "service connection", cr, app);
3556            }
3557        }
3558        for (int j=app.conProviders.size()-1; j>=0; j--) {
3559            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3560            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3561                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3562                        "provider reference", cpr, app);
3563            }
3564        }
3565    }
3566
3567    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3568        if (uid == SYSTEM_UID) {
3569            // The system gets to run in any process.  If there are multiple
3570            // processes with the same uid, just pick the first (this
3571            // should never happen).
3572            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3573            if (procs == null) return null;
3574            final int procCount = procs.size();
3575            for (int i = 0; i < procCount; i++) {
3576                final int procUid = procs.keyAt(i);
3577                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3578                    // Don't use an app process or different user process for system component.
3579                    continue;
3580                }
3581                return procs.valueAt(i);
3582            }
3583        }
3584        ProcessRecord proc = mProcessNames.get(processName, uid);
3585        if (false && proc != null && !keepIfLarge
3586                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3587                && proc.lastCachedPss >= 4000) {
3588            // Turn this condition on to cause killing to happen regularly, for testing.
3589            if (proc.baseProcessTracker != null) {
3590                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3591            }
3592            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3593        } else if (proc != null && !keepIfLarge
3594                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3595                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3596            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3597            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3598                if (proc.baseProcessTracker != null) {
3599                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3600                }
3601                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3602            }
3603        }
3604        return proc;
3605    }
3606
3607    void notifyPackageUse(String packageName, int reason) {
3608        synchronized(this) {
3609            getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3610        }
3611    }
3612
3613    boolean isNextTransitionForward() {
3614        int transit = mWindowManager.getPendingAppTransition();
3615        return transit == TRANSIT_ACTIVITY_OPEN
3616                || transit == TRANSIT_TASK_OPEN
3617                || transit == TRANSIT_TASK_TO_FRONT;
3618    }
3619
3620    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3621            String processName, String abiOverride, int uid, Runnable crashHandler) {
3622        synchronized(this) {
3623            ApplicationInfo info = new ApplicationInfo();
3624            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3625            // For isolated processes, the former contains the parent's uid and the latter the
3626            // actual uid of the isolated process.
3627            // In the special case introduced by this method (which is, starting an isolated
3628            // process directly from the SystemServer without an actual parent app process) the
3629            // closest thing to a parent's uid is SYSTEM_UID.
3630            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3631            // the |isolated| logic in the ProcessRecord constructor.
3632            info.uid = SYSTEM_UID;
3633            info.processName = processName;
3634            info.className = entryPoint;
3635            info.packageName = "android";
3636            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3637            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3638                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3639                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3640                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3641                    crashHandler);
3642            return proc != null ? proc.pid : 0;
3643        }
3644    }
3645
3646    final ProcessRecord startProcessLocked(String processName,
3647            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3648            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3649            boolean isolated, boolean keepIfLarge) {
3650        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3651                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3652                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3653                null /* crashHandler */);
3654    }
3655
3656    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3657            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3658            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3659            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3660        long startTime = SystemClock.elapsedRealtime();
3661        ProcessRecord app;
3662        if (!isolated) {
3663            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3664            checkTime(startTime, "startProcess: after getProcessRecord");
3665
3666            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3667                // If we are in the background, then check to see if this process
3668                // is bad.  If so, we will just silently fail.
3669                if (mAppErrors.isBadProcessLocked(info)) {
3670                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3671                            + "/" + info.processName);
3672                    return null;
3673                }
3674            } else {
3675                // When the user is explicitly starting a process, then clear its
3676                // crash count so that we won't make it bad until they see at
3677                // least one crash dialog again, and make the process good again
3678                // if it had been bad.
3679                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3680                        + "/" + info.processName);
3681                mAppErrors.resetProcessCrashTimeLocked(info);
3682                if (mAppErrors.isBadProcessLocked(info)) {
3683                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3684                            UserHandle.getUserId(info.uid), info.uid,
3685                            info.processName);
3686                    mAppErrors.clearBadProcessLocked(info);
3687                    if (app != null) {
3688                        app.bad = false;
3689                    }
3690                }
3691            }
3692        } else {
3693            // If this is an isolated process, it can't re-use an existing process.
3694            app = null;
3695        }
3696
3697        // We don't have to do anything more if:
3698        // (1) There is an existing application record; and
3699        // (2) The caller doesn't think it is dead, OR there is no thread
3700        //     object attached to it so we know it couldn't have crashed; and
3701        // (3) There is a pid assigned to it, so it is either starting or
3702        //     already running.
3703        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3704                + " app=" + app + " knownToBeDead=" + knownToBeDead
3705                + " thread=" + (app != null ? app.thread : null)
3706                + " pid=" + (app != null ? app.pid : -1));
3707        if (app != null && app.pid > 0) {
3708            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3709                // We already have the app running, or are waiting for it to
3710                // come up (we have a pid but not yet its thread), so keep it.
3711                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3712                // If this is a new package in the process, add the package to the list
3713                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3714                checkTime(startTime, "startProcess: done, added package to proc");
3715                return app;
3716            }
3717
3718            // An application record is attached to a previous process,
3719            // clean it up now.
3720            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3721            checkTime(startTime, "startProcess: bad proc running, killing");
3722            killProcessGroup(app.uid, app.pid);
3723            handleAppDiedLocked(app, true, true);
3724            checkTime(startTime, "startProcess: done killing old proc");
3725        }
3726
3727        String hostingNameStr = hostingName != null
3728                ? hostingName.flattenToShortString() : null;
3729
3730        if (app == null) {
3731            checkTime(startTime, "startProcess: creating new process record");
3732            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3733            if (app == null) {
3734                Slog.w(TAG, "Failed making new process record for "
3735                        + processName + "/" + info.uid + " isolated=" + isolated);
3736                return null;
3737            }
3738            app.crashHandler = crashHandler;
3739            checkTime(startTime, "startProcess: done creating new process record");
3740        } else {
3741            // If this is a new package in the process, add the package to the list
3742            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3743            checkTime(startTime, "startProcess: added package to existing proc");
3744        }
3745
3746        // If the system is not ready yet, then hold off on starting this
3747        // process until it is.
3748        if (!mProcessesReady
3749                && !isAllowedWhileBooting(info)
3750                && !allowWhileBooting) {
3751            if (!mProcessesOnHold.contains(app)) {
3752                mProcessesOnHold.add(app);
3753            }
3754            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3755                    "System not ready, putting on hold: " + app);
3756            checkTime(startTime, "startProcess: returning with proc on hold");
3757            return app;
3758        }
3759
3760        checkTime(startTime, "startProcess: stepping in to startProcess");
3761        startProcessLocked(
3762                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3763        checkTime(startTime, "startProcess: done starting proc!");
3764        return (app.pid != 0) ? app : null;
3765    }
3766
3767    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3768        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3769    }
3770
3771    private final void startProcessLocked(ProcessRecord app,
3772            String hostingType, String hostingNameStr) {
3773        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3774                null /* entryPoint */, null /* entryPointArgs */);
3775    }
3776
3777    private final void startProcessLocked(ProcessRecord app, String hostingType,
3778            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3779        long startTime = SystemClock.elapsedRealtime();
3780        if (app.pid > 0 && app.pid != MY_PID) {
3781            checkTime(startTime, "startProcess: removing from pids map");
3782            synchronized (mPidsSelfLocked) {
3783                mPidsSelfLocked.remove(app.pid);
3784                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3785            }
3786            checkTime(startTime, "startProcess: done removing from pids map");
3787            app.setPid(0);
3788        }
3789
3790        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3791                "startProcessLocked removing on hold: " + app);
3792        mProcessesOnHold.remove(app);
3793
3794        checkTime(startTime, "startProcess: starting to update cpu stats");
3795        updateCpuStats();
3796        checkTime(startTime, "startProcess: done updating cpu stats");
3797
3798        try {
3799            try {
3800                final int userId = UserHandle.getUserId(app.uid);
3801                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3802            } catch (RemoteException e) {
3803                throw e.rethrowAsRuntimeException();
3804            }
3805
3806            int uid = app.uid;
3807            int[] gids = null;
3808            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3809            if (!app.isolated) {
3810                int[] permGids = null;
3811                try {
3812                    checkTime(startTime, "startProcess: getting gids from package manager");
3813                    final IPackageManager pm = AppGlobals.getPackageManager();
3814                    permGids = pm.getPackageGids(app.info.packageName,
3815                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3816                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3817                            StorageManagerInternal.class);
3818                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3819                            app.info.packageName);
3820                } catch (RemoteException e) {
3821                    throw e.rethrowAsRuntimeException();
3822                }
3823
3824                /*
3825                 * Add shared application and profile GIDs so applications can share some
3826                 * resources like shared libraries and access user-wide resources
3827                 */
3828                if (ArrayUtils.isEmpty(permGids)) {
3829                    gids = new int[3];
3830                } else {
3831                    gids = new int[permGids.length + 3];
3832                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3833                }
3834                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3835                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3836                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3837            }
3838            checkTime(startTime, "startProcess: building args");
3839            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3840                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3841                        && mTopComponent != null
3842                        && app.processName.equals(mTopComponent.getPackageName())) {
3843                    uid = 0;
3844                }
3845                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3846                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3847                    uid = 0;
3848                }
3849            }
3850            int debugFlags = 0;
3851            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3852                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3853                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3854                // Also turn on CheckJNI for debuggable apps. It's quite
3855                // awkward to turn on otherwise.
3856                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3857            }
3858            // Run the app in safe mode if its manifest requests so or the
3859            // system is booted in safe mode.
3860            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3861                mSafeMode == true) {
3862                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3863            }
3864            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3865                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3866            }
3867            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3868            if ("true".equals(genDebugInfoProperty)) {
3869                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3870            }
3871            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3872                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3873            }
3874            if ("1".equals(SystemProperties.get("debug.assert"))) {
3875                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3876            }
3877            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3878                // Enable all debug flags required by the native debugger.
3879                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3880                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3881                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3882                mNativeDebuggingApp = null;
3883            }
3884
3885            String invokeWith = null;
3886            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3887                // Debuggable apps may include a wrapper script with their library directory.
3888                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3889                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3890                try {
3891                    if (new File(wrapperFileName).exists()) {
3892                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3893                    }
3894                } finally {
3895                    StrictMode.setThreadPolicy(oldPolicy);
3896                }
3897            }
3898
3899            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3900            if (requiredAbi == null) {
3901                requiredAbi = Build.SUPPORTED_ABIS[0];
3902            }
3903
3904            String instructionSet = null;
3905            if (app.info.primaryCpuAbi != null) {
3906                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3907            }
3908
3909            app.gids = gids;
3910            app.requiredAbi = requiredAbi;
3911            app.instructionSet = instructionSet;
3912
3913            // the per-user SELinux context must be set
3914            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3915                Slog.wtf(TAG, "SELinux tag not defined",
3916                        new IllegalStateException("SELinux tag not defined for "
3917                        + app.info.packageName + " (uid " + app.uid + ")"));
3918            }
3919            final String seInfo = app.info.seInfo
3920                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3921            // Start the process.  It will either succeed and return a result containing
3922            // the PID of the new process, or else throw a RuntimeException.
3923            boolean isActivityProcess = (entryPoint == null);
3924            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3925            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3926                    app.processName);
3927            checkTime(startTime, "startProcess: asking zygote to start proc");
3928            ProcessStartResult startResult;
3929            if (hostingType.equals("webview_service")) {
3930                startResult = startWebView(entryPoint,
3931                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3932                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3933                        app.info.dataDir, null, entryPointArgs);
3934            } else {
3935                startResult = Process.start(entryPoint,
3936                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3937                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3938                        app.info.dataDir, invokeWith, entryPointArgs);
3939            }
3940            checkTime(startTime, "startProcess: returned from zygote!");
3941            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3942
3943            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3944            checkTime(startTime, "startProcess: done updating battery stats");
3945
3946            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3947                    UserHandle.getUserId(uid), startResult.pid, uid,
3948                    app.processName, hostingType,
3949                    hostingNameStr != null ? hostingNameStr : "");
3950
3951            try {
3952                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3953                        seInfo, app.info.sourceDir, startResult.pid);
3954            } catch (RemoteException ex) {
3955                // Ignore
3956            }
3957
3958            if (app.persistent) {
3959                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3960            }
3961
3962            checkTime(startTime, "startProcess: building log message");
3963            StringBuilder buf = mStringBuilder;
3964            buf.setLength(0);
3965            buf.append("Start proc ");
3966            buf.append(startResult.pid);
3967            buf.append(':');
3968            buf.append(app.processName);
3969            buf.append('/');
3970            UserHandle.formatUid(buf, uid);
3971            if (!isActivityProcess) {
3972                buf.append(" [");
3973                buf.append(entryPoint);
3974                buf.append("]");
3975            }
3976            buf.append(" for ");
3977            buf.append(hostingType);
3978            if (hostingNameStr != null) {
3979                buf.append(" ");
3980                buf.append(hostingNameStr);
3981            }
3982            Slog.i(TAG, buf.toString());
3983            app.setPid(startResult.pid);
3984            app.usingWrapper = startResult.usingWrapper;
3985            app.removed = false;
3986            app.killed = false;
3987            app.killedByAm = false;
3988            checkTime(startTime, "startProcess: starting to update pids map");
3989            ProcessRecord oldApp;
3990            synchronized (mPidsSelfLocked) {
3991                oldApp = mPidsSelfLocked.get(startResult.pid);
3992            }
3993            // If there is already an app occupying that pid that hasn't been cleaned up
3994            if (oldApp != null && !app.isolated) {
3995                // Clean up anything relating to this pid first
3996                Slog.w(TAG, "Reusing pid " + startResult.pid
3997                        + " while app is still mapped to it");
3998                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3999                        true /*replacingPid*/);
4000            }
4001            synchronized (mPidsSelfLocked) {
4002                this.mPidsSelfLocked.put(startResult.pid, app);
4003                if (isActivityProcess) {
4004                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4005                    msg.obj = app;
4006                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4007                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4008                }
4009            }
4010            checkTime(startTime, "startProcess: done updating pids map");
4011        } catch (RuntimeException e) {
4012            Slog.e(TAG, "Failure starting process " + app.processName, e);
4013
4014            // Something went very wrong while trying to start this process; one
4015            // common case is when the package is frozen due to an active
4016            // upgrade. To recover, clean up any active bookkeeping related to
4017            // starting this process. (We already invoked this method once when
4018            // the package was initially frozen through KILL_APPLICATION_MSG, so
4019            // it doesn't hurt to use it again.)
4020            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4021                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4022        }
4023    }
4024
4025    void updateUsageStats(ActivityRecord component, boolean resumed) {
4026        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4027                "updateUsageStats: comp=" + component + "res=" + resumed);
4028        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4029        if (resumed) {
4030            if (mUsageStatsService != null) {
4031                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4032                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4033            }
4034            synchronized (stats) {
4035                stats.noteActivityResumedLocked(component.app.uid);
4036            }
4037        } else {
4038            if (mUsageStatsService != null) {
4039                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4040                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4041            }
4042            synchronized (stats) {
4043                stats.noteActivityPausedLocked(component.app.uid);
4044            }
4045        }
4046    }
4047
4048    Intent getHomeIntent() {
4049        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4050        intent.setComponent(mTopComponent);
4051        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4052        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4053            intent.addCategory(Intent.CATEGORY_HOME);
4054        }
4055        return intent;
4056    }
4057
4058    boolean startHomeActivityLocked(int userId, String reason) {
4059        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4060                && mTopAction == null) {
4061            // We are running in factory test mode, but unable to find
4062            // the factory test app, so just sit around displaying the
4063            // error message and don't try to start anything.
4064            return false;
4065        }
4066        Intent intent = getHomeIntent();
4067        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4068        if (aInfo != null) {
4069            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4070            // Don't do this if the home app is currently being
4071            // instrumented.
4072            aInfo = new ActivityInfo(aInfo);
4073            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4074            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4075                    aInfo.applicationInfo.uid, true);
4076            if (app == null || app.instr == null) {
4077                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4078                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4079                // For ANR debugging to verify if the user activity is the one that actually
4080                // launched.
4081                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4082                mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4083            }
4084        } else {
4085            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4086        }
4087
4088        return true;
4089    }
4090
4091    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4092        ActivityInfo ai = null;
4093        ComponentName comp = intent.getComponent();
4094        try {
4095            if (comp != null) {
4096                // Factory test.
4097                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4098            } else {
4099                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4100                        intent,
4101                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4102                        flags, userId);
4103
4104                if (info != null) {
4105                    ai = info.activityInfo;
4106                }
4107            }
4108        } catch (RemoteException e) {
4109            // ignore
4110        }
4111
4112        return ai;
4113    }
4114
4115    /**
4116     * Starts the "new version setup screen" if appropriate.
4117     */
4118    void startSetupActivityLocked() {
4119        // Only do this once per boot.
4120        if (mCheckedForSetup) {
4121            return;
4122        }
4123
4124        // We will show this screen if the current one is a different
4125        // version than the last one shown, and we are not running in
4126        // low-level factory test mode.
4127        final ContentResolver resolver = mContext.getContentResolver();
4128        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4129                Settings.Global.getInt(resolver,
4130                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4131            mCheckedForSetup = true;
4132
4133            // See if we should be showing the platform update setup UI.
4134            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4135            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4136                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4137            if (!ris.isEmpty()) {
4138                final ResolveInfo ri = ris.get(0);
4139                String vers = ri.activityInfo.metaData != null
4140                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4141                        : null;
4142                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4143                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4144                            Intent.METADATA_SETUP_VERSION);
4145                }
4146                String lastVers = Settings.Secure.getString(
4147                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4148                if (vers != null && !vers.equals(lastVers)) {
4149                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4150                    intent.setComponent(new ComponentName(
4151                            ri.activityInfo.packageName, ri.activityInfo.name));
4152                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4153                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4154                            null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4155                }
4156            }
4157        }
4158    }
4159
4160    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4161        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4162    }
4163
4164    void enforceNotIsolatedCaller(String caller) {
4165        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4166            throw new SecurityException("Isolated process not allowed to call " + caller);
4167        }
4168    }
4169
4170    void enforceShellRestriction(String restriction, int userHandle) {
4171        if (Binder.getCallingUid() == SHELL_UID) {
4172            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4173                throw new SecurityException("Shell does not have permission to access user "
4174                        + userHandle);
4175            }
4176        }
4177    }
4178
4179    @Override
4180    public int getFrontActivityScreenCompatMode() {
4181        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4182        synchronized (this) {
4183            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4184        }
4185    }
4186
4187    @Override
4188    public void setFrontActivityScreenCompatMode(int mode) {
4189        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4190                "setFrontActivityScreenCompatMode");
4191        synchronized (this) {
4192            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4193        }
4194    }
4195
4196    @Override
4197    public int getPackageScreenCompatMode(String packageName) {
4198        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4199        synchronized (this) {
4200            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4201        }
4202    }
4203
4204    @Override
4205    public void setPackageScreenCompatMode(String packageName, int mode) {
4206        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4207                "setPackageScreenCompatMode");
4208        synchronized (this) {
4209            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4210        }
4211    }
4212
4213    @Override
4214    public boolean getPackageAskScreenCompat(String packageName) {
4215        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4216        synchronized (this) {
4217            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4218        }
4219    }
4220
4221    @Override
4222    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4223        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4224                "setPackageAskScreenCompat");
4225        synchronized (this) {
4226            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4227        }
4228    }
4229
4230    private boolean hasUsageStatsPermission(String callingPackage) {
4231        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4232                Binder.getCallingUid(), callingPackage);
4233        if (mode == AppOpsManager.MODE_DEFAULT) {
4234            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4235                    == PackageManager.PERMISSION_GRANTED;
4236        }
4237        return mode == AppOpsManager.MODE_ALLOWED;
4238    }
4239
4240    @Override
4241    public int getPackageProcessState(String packageName, String callingPackage) {
4242        if (!hasUsageStatsPermission(callingPackage)) {
4243            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4244                    "getPackageProcessState");
4245        }
4246
4247        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4248        synchronized (this) {
4249            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4250                final ProcessRecord proc = mLruProcesses.get(i);
4251                if (procState > proc.setProcState) {
4252                    if (proc.pkgList.containsKey(packageName) ||
4253                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4254                        procState = proc.setProcState;
4255                    }
4256                }
4257            }
4258        }
4259        return procState;
4260    }
4261
4262    @Override
4263    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4264            throws RemoteException {
4265        synchronized (this) {
4266            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4267            if (app == null) {
4268                throw new IllegalArgumentException("Unknown process: " + process);
4269            }
4270            if (app.thread == null) {
4271                throw new IllegalArgumentException("Process has no app thread");
4272            }
4273            if (app.trimMemoryLevel >= level) {
4274                throw new IllegalArgumentException(
4275                        "Unable to set a higher trim level than current level");
4276            }
4277            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4278                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4279                throw new IllegalArgumentException("Unable to set a background trim level "
4280                    + "on a foreground process");
4281            }
4282            app.thread.scheduleTrimMemory(level);
4283            app.trimMemoryLevel = level;
4284            return true;
4285        }
4286    }
4287
4288    private void dispatchProcessesChanged() {
4289        int N;
4290        synchronized (this) {
4291            N = mPendingProcessChanges.size();
4292            if (mActiveProcessChanges.length < N) {
4293                mActiveProcessChanges = new ProcessChangeItem[N];
4294            }
4295            mPendingProcessChanges.toArray(mActiveProcessChanges);
4296            mPendingProcessChanges.clear();
4297            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4298                    "*** Delivering " + N + " process changes");
4299        }
4300
4301        int i = mProcessObservers.beginBroadcast();
4302        while (i > 0) {
4303            i--;
4304            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4305            if (observer != null) {
4306                try {
4307                    for (int j=0; j<N; j++) {
4308                        ProcessChangeItem item = mActiveProcessChanges[j];
4309                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4310                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4311                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4312                                    + item.uid + ": " + item.foregroundActivities);
4313                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4314                                    item.foregroundActivities);
4315                        }
4316                    }
4317                } catch (RemoteException e) {
4318                }
4319            }
4320        }
4321        mProcessObservers.finishBroadcast();
4322
4323        synchronized (this) {
4324            for (int j=0; j<N; j++) {
4325                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4326            }
4327        }
4328    }
4329
4330    private void dispatchProcessDied(int pid, int uid) {
4331        int i = mProcessObservers.beginBroadcast();
4332        while (i > 0) {
4333            i--;
4334            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4335            if (observer != null) {
4336                try {
4337                    observer.onProcessDied(pid, uid);
4338                } catch (RemoteException e) {
4339                }
4340            }
4341        }
4342        mProcessObservers.finishBroadcast();
4343    }
4344
4345    @VisibleForTesting
4346    void dispatchUidsChanged() {
4347        int N;
4348        synchronized (this) {
4349            N = mPendingUidChanges.size();
4350            if (mActiveUidChanges.length < N) {
4351                mActiveUidChanges = new UidRecord.ChangeItem[N];
4352            }
4353            for (int i=0; i<N; i++) {
4354                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4355                mActiveUidChanges[i] = change;
4356                if (change.uidRecord != null) {
4357                    change.uidRecord.pendingChange = null;
4358                    change.uidRecord = null;
4359                }
4360            }
4361            mPendingUidChanges.clear();
4362            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4363                    "*** Delivering " + N + " uid changes");
4364        }
4365
4366        int i = mUidObservers.beginBroadcast();
4367        while (i > 0) {
4368            i--;
4369            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4370                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4371        }
4372        mUidObservers.finishBroadcast();
4373
4374        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4375            for (int j = 0; j < N; ++j) {
4376                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4377                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4378                    mValidateUids.remove(item.uid);
4379                } else {
4380                    UidRecord validateUid = mValidateUids.get(item.uid);
4381                    if (validateUid == null) {
4382                        validateUid = new UidRecord(item.uid);
4383                        mValidateUids.put(item.uid, validateUid);
4384                    }
4385                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4386                        validateUid.idle = true;
4387                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4388                        validateUid.idle = false;
4389                    }
4390                    validateUid.curProcState = validateUid.setProcState = item.processState;
4391                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4392                }
4393            }
4394        }
4395
4396        synchronized (this) {
4397            for (int j = 0; j < N; j++) {
4398                mAvailUidChanges.add(mActiveUidChanges[j]);
4399            }
4400        }
4401    }
4402
4403    private void dispatchUidsChangedForObserver(IUidObserver observer,
4404            UidObserverRegistration reg, int changesSize) {
4405        if (observer == null) {
4406            return;
4407        }
4408        try {
4409            for (int j = 0; j < changesSize; j++) {
4410                UidRecord.ChangeItem item = mActiveUidChanges[j];
4411                final int change = item.change;
4412                if (change == UidRecord.CHANGE_PROCSTATE &&
4413                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4414                    // No-op common case: no significant change, the observer is not
4415                    // interested in all proc state changes.
4416                    continue;
4417                }
4418                if ((change & UidRecord.CHANGE_IDLE) != 0) {
4419                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4420                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4421                                "UID idle uid=" + item.uid);
4422                        observer.onUidIdle(item.uid, item.ephemeral);
4423                    }
4424                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4425                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4426                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4427                                "UID active uid=" + item.uid);
4428                        observer.onUidActive(item.uid);
4429                    }
4430                }
4431                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4432                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
4433                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4434                                "UID cached uid=" + item.uid);
4435                        observer.onUidCachedChanged(item.uid, true);
4436                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4437                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4438                                "UID active uid=" + item.uid);
4439                        observer.onUidCachedChanged(item.uid, false);
4440                    }
4441                }
4442                if ((change & UidRecord.CHANGE_GONE) != 0) {
4443                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4444                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4445                                "UID gone uid=" + item.uid);
4446                        observer.onUidGone(item.uid, item.ephemeral);
4447                    }
4448                    if (reg.lastProcStates != null) {
4449                        reg.lastProcStates.delete(item.uid);
4450                    }
4451                } else {
4452                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4453                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4454                                "UID CHANGED uid=" + item.uid
4455                                        + ": " + item.processState);
4456                        boolean doReport = true;
4457                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4458                            final int lastState = reg.lastProcStates.get(item.uid,
4459                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4460                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4461                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4462                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4463                                doReport = lastAboveCut != newAboveCut;
4464                            } else {
4465                                doReport = item.processState
4466                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4467                            }
4468                        }
4469                        if (doReport) {
4470                            if (reg.lastProcStates != null) {
4471                                reg.lastProcStates.put(item.uid, item.processState);
4472                            }
4473                            observer.onUidStateChanged(item.uid, item.processState,
4474                                    item.procStateSeq);
4475                        }
4476                    }
4477                }
4478            }
4479        } catch (RemoteException e) {
4480        }
4481    }
4482
4483    void dispatchOomAdjObserver(String msg) {
4484        OomAdjObserver observer;
4485        synchronized (this) {
4486            observer = mCurOomAdjObserver;
4487        }
4488
4489        if (observer != null) {
4490            observer.onOomAdjMessage(msg);
4491        }
4492    }
4493
4494    void setOomAdjObserver(int uid, OomAdjObserver observer) {
4495        synchronized (this) {
4496            mCurOomAdjUid = uid;
4497            mCurOomAdjObserver = observer;
4498        }
4499    }
4500
4501    void clearOomAdjObserver() {
4502        synchronized (this) {
4503            mCurOomAdjUid = -1;
4504            mCurOomAdjObserver = null;
4505        }
4506    }
4507
4508    void reportOomAdjMessageLocked(String tag, String msg) {
4509        Slog.d(tag, msg);
4510        if (mCurOomAdjObserver != null) {
4511            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4512        }
4513    }
4514
4515    @Override
4516    public final int startActivity(IApplicationThread caller, String callingPackage,
4517            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4518            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4519        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4520                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4521                UserHandle.getCallingUserId());
4522    }
4523
4524    @Override
4525    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4526            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4527            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4528        enforceNotIsolatedCaller("startActivity");
4529        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4530                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4531        // TODO: Switch to user app stacks here.
4532        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4533                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4534                profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4535    }
4536
4537    @Override
4538    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4539            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4540            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4541            int userId) {
4542
4543        // This is very dangerous -- it allows you to perform a start activity (including
4544        // permission grants) as any app that may launch one of your own activities.  So
4545        // we will only allow this to be done from activities that are part of the core framework,
4546        // and then only when they are running as the system.
4547        final ActivityRecord sourceRecord;
4548        final int targetUid;
4549        final String targetPackage;
4550        synchronized (this) {
4551            if (resultTo == null) {
4552                throw new SecurityException("Must be called from an activity");
4553            }
4554            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4555            if (sourceRecord == null) {
4556                throw new SecurityException("Called with bad activity token: " + resultTo);
4557            }
4558            if (!sourceRecord.info.packageName.equals("android")) {
4559                throw new SecurityException(
4560                        "Must be called from an activity that is declared in the android package");
4561            }
4562            if (sourceRecord.app == null) {
4563                throw new SecurityException("Called without a process attached to activity");
4564            }
4565            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4566                // This is still okay, as long as this activity is running under the
4567                // uid of the original calling activity.
4568                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4569                    throw new SecurityException(
4570                            "Calling activity in uid " + sourceRecord.app.uid
4571                                    + " must be system uid or original calling uid "
4572                                    + sourceRecord.launchedFromUid);
4573                }
4574            }
4575            if (ignoreTargetSecurity) {
4576                if (intent.getComponent() == null) {
4577                    throw new SecurityException(
4578                            "Component must be specified with ignoreTargetSecurity");
4579                }
4580                if (intent.getSelector() != null) {
4581                    throw new SecurityException(
4582                            "Selector not allowed with ignoreTargetSecurity");
4583                }
4584            }
4585            targetUid = sourceRecord.launchedFromUid;
4586            targetPackage = sourceRecord.launchedFromPackage;
4587        }
4588
4589        if (userId == UserHandle.USER_NULL) {
4590            userId = UserHandle.getUserId(sourceRecord.app.uid);
4591        }
4592
4593        // TODO: Switch to user app stacks here.
4594        try {
4595            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4596                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4597                    null, null, bOptions, ignoreTargetSecurity, userId, null,
4598                    "startActivityAsCaller");
4599            return ret;
4600        } catch (SecurityException e) {
4601            // XXX need to figure out how to propagate to original app.
4602            // A SecurityException here is generally actually a fault of the original
4603            // calling activity (such as a fairly granting permissions), so propagate it
4604            // back to them.
4605            /*
4606            StringBuilder msg = new StringBuilder();
4607            msg.append("While launching");
4608            msg.append(intent.toString());
4609            msg.append(": ");
4610            msg.append(e.getMessage());
4611            */
4612            throw e;
4613        }
4614    }
4615
4616    @Override
4617    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4618            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4619            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4620        enforceNotIsolatedCaller("startActivityAndWait");
4621        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4622                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4623        WaitResult res = new WaitResult();
4624        // TODO: Switch to user app stacks here.
4625        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4626                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4627                bOptions, false, userId, null, "startActivityAndWait");
4628        return res;
4629    }
4630
4631    @Override
4632    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4633            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4634            int startFlags, Configuration config, Bundle bOptions, int userId) {
4635        enforceNotIsolatedCaller("startActivityWithConfig");
4636        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4637                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4638        // TODO: Switch to user app stacks here.
4639        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4640                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4641                null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4642        return ret;
4643    }
4644
4645    @Override
4646    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4647            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4648            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4649            throws TransactionTooLargeException {
4650        enforceNotIsolatedCaller("startActivityIntentSender");
4651        // Refuse possible leaked file descriptors
4652        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4653            throw new IllegalArgumentException("File descriptors passed in Intent");
4654        }
4655
4656        if (!(target instanceof PendingIntentRecord)) {
4657            throw new IllegalArgumentException("Bad PendingIntent object");
4658        }
4659
4660        PendingIntentRecord pir = (PendingIntentRecord)target;
4661
4662        synchronized (this) {
4663            // If this is coming from the currently resumed activity, it is
4664            // effectively saying that app switches are allowed at this point.
4665            final ActivityStack stack = getFocusedStack();
4666            if (stack.mResumedActivity != null &&
4667                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4668                mAppSwitchesAllowedTime = 0;
4669            }
4670        }
4671        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4672                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4673        return ret;
4674    }
4675
4676    @Override
4677    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4678            Intent intent, String resolvedType, IVoiceInteractionSession session,
4679            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4680            Bundle bOptions, int userId) {
4681        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4682                != PackageManager.PERMISSION_GRANTED) {
4683            String msg = "Permission Denial: startVoiceActivity() from pid="
4684                    + Binder.getCallingPid()
4685                    + ", uid=" + Binder.getCallingUid()
4686                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4687            Slog.w(TAG, msg);
4688            throw new SecurityException(msg);
4689        }
4690        if (session == null || interactor == null) {
4691            throw new NullPointerException("null session or interactor");
4692        }
4693        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4694                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4695        // TODO: Switch to user app stacks here.
4696        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4697                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4698                null, bOptions, false, userId, null, "startVoiceActivity");
4699    }
4700
4701    @Override
4702    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4703            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4704        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4705                != PackageManager.PERMISSION_GRANTED) {
4706            final String msg = "Permission Denial: startAssistantActivity() from pid="
4707                    + Binder.getCallingPid()
4708                    + ", uid=" + Binder.getCallingUid()
4709                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4710            Slog.w(TAG, msg);
4711            throw new SecurityException(msg);
4712        }
4713        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4714                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4715        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4716                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4717                userId, null, "startAssistantActivity");
4718    }
4719
4720    @Override
4721    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4722            throws RemoteException {
4723        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4724        synchronized (this) {
4725            ActivityRecord activity = getFocusedStack().topActivity();
4726            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4727                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4728            }
4729            if (mRunningVoice != null || activity.getTask().voiceSession != null
4730                    || activity.voiceSession != null) {
4731                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4732                return;
4733            }
4734            if (activity.pendingVoiceInteractionStart) {
4735                Slog.w(TAG, "Pending start of voice interaction already.");
4736                return;
4737            }
4738            activity.pendingVoiceInteractionStart = true;
4739        }
4740        LocalServices.getService(VoiceInteractionManagerInternal.class)
4741                .startLocalVoiceInteraction(callingActivity, options);
4742    }
4743
4744    @Override
4745    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4746        LocalServices.getService(VoiceInteractionManagerInternal.class)
4747                .stopLocalVoiceInteraction(callingActivity);
4748    }
4749
4750    @Override
4751    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4752        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4753                .supportsLocalVoiceInteraction();
4754    }
4755
4756    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4757            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4758        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4759        if (activityToCallback == null) return;
4760        activityToCallback.setVoiceSessionLocked(voiceSession);
4761
4762        // Inform the activity
4763        try {
4764            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4765                    voiceInteractor);
4766            long token = Binder.clearCallingIdentity();
4767            try {
4768                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4769            } finally {
4770                Binder.restoreCallingIdentity(token);
4771            }
4772            // TODO: VI Should we cache the activity so that it's easier to find later
4773            // rather than scan through all the stacks and activities?
4774        } catch (RemoteException re) {
4775            activityToCallback.clearVoiceSessionLocked();
4776            // TODO: VI Should this terminate the voice session?
4777        }
4778    }
4779
4780    @Override
4781    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4782        synchronized (this) {
4783            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4784                if (keepAwake) {
4785                    mVoiceWakeLock.acquire();
4786                } else {
4787                    mVoiceWakeLock.release();
4788                }
4789            }
4790        }
4791    }
4792
4793    @Override
4794    public boolean startNextMatchingActivity(IBinder callingActivity,
4795            Intent intent, Bundle bOptions) {
4796        // Refuse possible leaked file descriptors
4797        if (intent != null && intent.hasFileDescriptors() == true) {
4798            throw new IllegalArgumentException("File descriptors passed in Intent");
4799        }
4800        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4801
4802        synchronized (this) {
4803            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4804            if (r == null) {
4805                ActivityOptions.abort(options);
4806                return false;
4807            }
4808            if (r.app == null || r.app.thread == null) {
4809                // The caller is not running...  d'oh!
4810                ActivityOptions.abort(options);
4811                return false;
4812            }
4813            intent = new Intent(intent);
4814            // The caller is not allowed to change the data.
4815            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4816            // And we are resetting to find the next component...
4817            intent.setComponent(null);
4818
4819            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4820
4821            ActivityInfo aInfo = null;
4822            try {
4823                List<ResolveInfo> resolves =
4824                    AppGlobals.getPackageManager().queryIntentActivities(
4825                            intent, r.resolvedType,
4826                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4827                            UserHandle.getCallingUserId()).getList();
4828
4829                // Look for the original activity in the list...
4830                final int N = resolves != null ? resolves.size() : 0;
4831                for (int i=0; i<N; i++) {
4832                    ResolveInfo rInfo = resolves.get(i);
4833                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4834                            && rInfo.activityInfo.name.equals(r.info.name)) {
4835                        // We found the current one...  the next matching is
4836                        // after it.
4837                        i++;
4838                        if (i<N) {
4839                            aInfo = resolves.get(i).activityInfo;
4840                        }
4841                        if (debug) {
4842                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4843                                    + "/" + r.info.name);
4844                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4845                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4846                        }
4847                        break;
4848                    }
4849                }
4850            } catch (RemoteException e) {
4851            }
4852
4853            if (aInfo == null) {
4854                // Nobody who is next!
4855                ActivityOptions.abort(options);
4856                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4857                return false;
4858            }
4859
4860            intent.setComponent(new ComponentName(
4861                    aInfo.applicationInfo.packageName, aInfo.name));
4862            intent.setFlags(intent.getFlags()&~(
4863                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4864                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4865                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4866                    Intent.FLAG_ACTIVITY_NEW_TASK));
4867
4868            // Okay now we need to start the new activity, replacing the
4869            // currently running activity.  This is a little tricky because
4870            // we want to start the new one as if the current one is finished,
4871            // but not finish the current one first so that there is no flicker.
4872            // And thus...
4873            final boolean wasFinishing = r.finishing;
4874            r.finishing = true;
4875
4876            // Propagate reply information over to the new activity.
4877            final ActivityRecord resultTo = r.resultTo;
4878            final String resultWho = r.resultWho;
4879            final int requestCode = r.requestCode;
4880            r.resultTo = null;
4881            if (resultTo != null) {
4882                resultTo.removeResultsLocked(r, resultWho, requestCode);
4883            }
4884
4885            final long origId = Binder.clearCallingIdentity();
4886            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4887                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4888                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4889                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4890                    false, false, null, null, "startNextMatchingActivity");
4891            Binder.restoreCallingIdentity(origId);
4892
4893            r.finishing = wasFinishing;
4894            if (res != ActivityManager.START_SUCCESS) {
4895                return false;
4896            }
4897            return true;
4898        }
4899    }
4900
4901    @Override
4902    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4903        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4904            String msg = "Permission Denial: startActivityFromRecents called without " +
4905                    START_TASKS_FROM_RECENTS;
4906            Slog.w(TAG, msg);
4907            throw new SecurityException(msg);
4908        }
4909        final long origId = Binder.clearCallingIdentity();
4910        try {
4911            synchronized (this) {
4912                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4913            }
4914        } finally {
4915            Binder.restoreCallingIdentity(origId);
4916        }
4917    }
4918
4919    final int startActivityInPackage(int uid, String callingPackage,
4920            Intent intent, String resolvedType, IBinder resultTo,
4921            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4922            TaskRecord inTask, String reason) {
4923
4924        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4925                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4926
4927        // TODO: Switch to user app stacks here.
4928        return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4929                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4930                null, null, null, bOptions, false, userId, inTask, reason);
4931    }
4932
4933    @Override
4934    public final int startActivities(IApplicationThread caller, String callingPackage,
4935            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4936            int userId) {
4937        final String reason = "startActivities";
4938        enforceNotIsolatedCaller(reason);
4939        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4940                userId, false, ALLOW_FULL_ONLY, reason, null);
4941        // TODO: Switch to user app stacks here.
4942        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4943                resolvedTypes, resultTo, bOptions, userId, reason);
4944        return ret;
4945    }
4946
4947    final int startActivitiesInPackage(int uid, String callingPackage,
4948            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4949            Bundle bOptions, int userId) {
4950
4951        final String reason = "startActivityInPackage";
4952        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4953                userId, false, ALLOW_FULL_ONLY, reason, null);
4954        // TODO: Switch to user app stacks here.
4955        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4956                resultTo, bOptions, userId, reason);
4957        return ret;
4958    }
4959
4960    @Override
4961    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4962        synchronized (this) {
4963            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4964            if (r == null) {
4965                return;
4966            }
4967            r.reportFullyDrawnLocked(restoredFromBundle);
4968        }
4969    }
4970
4971    @Override
4972    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4973        synchronized (this) {
4974            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4975            if (r == null) {
4976                return;
4977            }
4978            final long origId = Binder.clearCallingIdentity();
4979            try {
4980                r.setRequestedOrientation(requestedOrientation);
4981            } finally {
4982                Binder.restoreCallingIdentity(origId);
4983            }
4984        }
4985    }
4986
4987    @Override
4988    public int getRequestedOrientation(IBinder token) {
4989        synchronized (this) {
4990            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4991            if (r == null) {
4992                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4993            }
4994            return r.getRequestedOrientation();
4995        }
4996    }
4997
4998    @Override
4999    public final void requestActivityRelaunch(IBinder token) {
5000        synchronized(this) {
5001            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5002            if (r == null) {
5003                return;
5004            }
5005            final long origId = Binder.clearCallingIdentity();
5006            try {
5007                r.forceNewConfig = true;
5008                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5009                        true /* preserveWindow */);
5010            } finally {
5011                Binder.restoreCallingIdentity(origId);
5012            }
5013        }
5014    }
5015
5016    /**
5017     * This is the internal entry point for handling Activity.finish().
5018     *
5019     * @param token The Binder token referencing the Activity we want to finish.
5020     * @param resultCode Result code, if any, from this Activity.
5021     * @param resultData Result data (Intent), if any, from this Activity.
5022     * @param finishTask Whether to finish the task associated with this Activity.
5023     *
5024     * @return Returns true if the activity successfully finished, or false if it is still running.
5025     */
5026    @Override
5027    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5028            int finishTask) {
5029        // Refuse possible leaked file descriptors
5030        if (resultData != null && resultData.hasFileDescriptors() == true) {
5031            throw new IllegalArgumentException("File descriptors passed in Intent");
5032        }
5033
5034        synchronized(this) {
5035            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5036            if (r == null) {
5037                return true;
5038            }
5039            // Keep track of the root activity of the task before we finish it
5040            TaskRecord tr = r.getTask();
5041            ActivityRecord rootR = tr.getRootActivity();
5042            if (rootR == null) {
5043                Slog.w(TAG, "Finishing task with all activities already finished");
5044            }
5045            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5046            // finish.
5047            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5048                    mStackSupervisor.isLastLockedTask(tr)) {
5049                Slog.i(TAG, "Not finishing task in lock task mode");
5050                mStackSupervisor.showLockTaskToast();
5051                return false;
5052            }
5053            if (mController != null) {
5054                // Find the first activity that is not finishing.
5055                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5056                if (next != null) {
5057                    // ask watcher if this is allowed
5058                    boolean resumeOK = true;
5059                    try {
5060                        resumeOK = mController.activityResuming(next.packageName);
5061                    } catch (RemoteException e) {
5062                        mController = null;
5063                        Watchdog.getInstance().setActivityController(null);
5064                    }
5065
5066                    if (!resumeOK) {
5067                        Slog.i(TAG, "Not finishing activity because controller resumed");
5068                        return false;
5069                    }
5070                }
5071            }
5072            final long origId = Binder.clearCallingIdentity();
5073            try {
5074                boolean res;
5075                final boolean finishWithRootActivity =
5076                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5077                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5078                        || (finishWithRootActivity && r == rootR)) {
5079                    // If requested, remove the task that is associated to this activity only if it
5080                    // was the root activity in the task. The result code and data is ignored
5081                    // because we don't support returning them across task boundaries. Also, to
5082                    // keep backwards compatibility we remove the task from recents when finishing
5083                    // task with root activity.
5084                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5085                    if (!res) {
5086                        Slog.i(TAG, "Removing task failed to finish activity");
5087                    }
5088                } else {
5089                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5090                            resultData, "app-request", true);
5091                    if (!res) {
5092                        Slog.i(TAG, "Failed to finish by app-request");
5093                    }
5094                }
5095                return res;
5096            } finally {
5097                Binder.restoreCallingIdentity(origId);
5098            }
5099        }
5100    }
5101
5102    @Override
5103    public final void finishHeavyWeightApp() {
5104        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5105                != PackageManager.PERMISSION_GRANTED) {
5106            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5107                    + Binder.getCallingPid()
5108                    + ", uid=" + Binder.getCallingUid()
5109                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5110            Slog.w(TAG, msg);
5111            throw new SecurityException(msg);
5112        }
5113
5114        synchronized(this) {
5115            if (mHeavyWeightProcess == null) {
5116                return;
5117            }
5118
5119            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5120            for (int i = 0; i < activities.size(); i++) {
5121                ActivityRecord r = activities.get(i);
5122                if (!r.finishing && r.isInStackLocked()) {
5123                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5124                            null, "finish-heavy", true);
5125                }
5126            }
5127
5128            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5129                    mHeavyWeightProcess.userId, 0));
5130            mHeavyWeightProcess = null;
5131        }
5132    }
5133
5134    @Override
5135    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5136            String message) {
5137        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5138                != PackageManager.PERMISSION_GRANTED) {
5139            String msg = "Permission Denial: crashApplication() from pid="
5140                    + Binder.getCallingPid()
5141                    + ", uid=" + Binder.getCallingUid()
5142                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5143            Slog.w(TAG, msg);
5144            throw new SecurityException(msg);
5145        }
5146
5147        synchronized(this) {
5148            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5149        }
5150    }
5151
5152    @Override
5153    public final void finishSubActivity(IBinder token, String resultWho,
5154            int requestCode) {
5155        synchronized(this) {
5156            final long origId = Binder.clearCallingIdentity();
5157            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5158            if (r != null) {
5159                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5160            }
5161            Binder.restoreCallingIdentity(origId);
5162        }
5163    }
5164
5165    @Override
5166    public boolean finishActivityAffinity(IBinder token) {
5167        synchronized(this) {
5168            final long origId = Binder.clearCallingIdentity();
5169            try {
5170                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5171                if (r == null) {
5172                    return false;
5173                }
5174
5175                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5176                // can finish.
5177                final TaskRecord task = r.getTask();
5178                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5179                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5180                    mStackSupervisor.showLockTaskToast();
5181                    return false;
5182                }
5183                return task.getStack().finishActivityAffinityLocked(r);
5184            } finally {
5185                Binder.restoreCallingIdentity(origId);
5186            }
5187        }
5188    }
5189
5190    @Override
5191    public void finishVoiceTask(IVoiceInteractionSession session) {
5192        synchronized (this) {
5193            final long origId = Binder.clearCallingIdentity();
5194            try {
5195                // TODO: VI Consider treating local voice interactions and voice tasks
5196                // differently here
5197                mStackSupervisor.finishVoiceTask(session);
5198            } finally {
5199                Binder.restoreCallingIdentity(origId);
5200            }
5201        }
5202
5203    }
5204
5205    @Override
5206    public boolean releaseActivityInstance(IBinder token) {
5207        synchronized(this) {
5208            final long origId = Binder.clearCallingIdentity();
5209            try {
5210                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5211                if (r == null) {
5212                    return false;
5213                }
5214                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5215            } finally {
5216                Binder.restoreCallingIdentity(origId);
5217            }
5218        }
5219    }
5220
5221    @Override
5222    public void releaseSomeActivities(IApplicationThread appInt) {
5223        synchronized(this) {
5224            final long origId = Binder.clearCallingIdentity();
5225            try {
5226                ProcessRecord app = getRecordForAppLocked(appInt);
5227                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5228            } finally {
5229                Binder.restoreCallingIdentity(origId);
5230            }
5231        }
5232    }
5233
5234    @Override
5235    public boolean willActivityBeVisible(IBinder token) {
5236        synchronized(this) {
5237            ActivityStack stack = ActivityRecord.getStackLocked(token);
5238            if (stack != null) {
5239                return stack.willActivityBeVisibleLocked(token);
5240            }
5241            return false;
5242        }
5243    }
5244
5245    @Override
5246    public void overridePendingTransition(IBinder token, String packageName,
5247            int enterAnim, int exitAnim) {
5248        synchronized(this) {
5249            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5250            if (self == null) {
5251                return;
5252            }
5253
5254            final long origId = Binder.clearCallingIdentity();
5255
5256            if (self.state == ActivityState.RESUMED
5257                    || self.state == ActivityState.PAUSING) {
5258                mWindowManager.overridePendingAppTransition(packageName,
5259                        enterAnim, exitAnim, null);
5260            }
5261
5262            Binder.restoreCallingIdentity(origId);
5263        }
5264    }
5265
5266    /**
5267     * Main function for removing an existing process from the activity manager
5268     * as a result of that process going away.  Clears out all connections
5269     * to the process.
5270     */
5271    private final void handleAppDiedLocked(ProcessRecord app,
5272            boolean restarting, boolean allowRestart) {
5273        int pid = app.pid;
5274        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5275                false /*replacingPid*/);
5276        if (!kept && !restarting) {
5277            removeLruProcessLocked(app);
5278            if (pid > 0) {
5279                ProcessList.remove(pid);
5280            }
5281        }
5282
5283        if (mProfileProc == app) {
5284            clearProfilerLocked();
5285        }
5286
5287        // Remove this application's activities from active lists.
5288        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5289
5290        app.activities.clear();
5291
5292        if (app.instr != null) {
5293            Slog.w(TAG, "Crash of app " + app.processName
5294                  + " running instrumentation " + app.instr.mClass);
5295            Bundle info = new Bundle();
5296            info.putString("shortMsg", "Process crashed.");
5297            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5298        }
5299
5300        mWindowManager.deferSurfaceLayout();
5301        try {
5302            if (!restarting && hasVisibleActivities
5303                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5304                // If there was nothing to resume, and we are not already restarting this process, but
5305                // there is a visible activity that is hosted by the process...  then make sure all
5306                // visible activities are running, taking care of restarting this process.
5307                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5308            }
5309        } finally {
5310            mWindowManager.continueSurfaceLayout();
5311        }
5312    }
5313
5314    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5315        final IBinder threadBinder = thread.asBinder();
5316        // Find the application record.
5317        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5318            final ProcessRecord rec = mLruProcesses.get(i);
5319            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5320                return i;
5321            }
5322        }
5323        return -1;
5324    }
5325
5326    final ProcessRecord getRecordForAppLocked(
5327            IApplicationThread thread) {
5328        if (thread == null) {
5329            return null;
5330        }
5331
5332        int appIndex = getLRURecordIndexForAppLocked(thread);
5333        if (appIndex >= 0) {
5334            return mLruProcesses.get(appIndex);
5335        }
5336
5337        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5338        // double-check that.
5339        final IBinder threadBinder = thread.asBinder();
5340        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5341        for (int i = pmap.size()-1; i >= 0; i--) {
5342            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5343            for (int j = procs.size()-1; j >= 0; j--) {
5344                final ProcessRecord proc = procs.valueAt(j);
5345                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5346                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5347                            + proc);
5348                    return proc;
5349                }
5350            }
5351        }
5352
5353        return null;
5354    }
5355
5356    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5357        // If there are no longer any background processes running,
5358        // and the app that died was not running instrumentation,
5359        // then tell everyone we are now low on memory.
5360        boolean haveBg = false;
5361        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5362            ProcessRecord rec = mLruProcesses.get(i);
5363            if (rec.thread != null
5364                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5365                haveBg = true;
5366                break;
5367            }
5368        }
5369
5370        if (!haveBg) {
5371            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5372            if (doReport) {
5373                long now = SystemClock.uptimeMillis();
5374                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5375                    doReport = false;
5376                } else {
5377                    mLastMemUsageReportTime = now;
5378                }
5379            }
5380            final ArrayList<ProcessMemInfo> memInfos
5381                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5382            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5383            long now = SystemClock.uptimeMillis();
5384            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5385                ProcessRecord rec = mLruProcesses.get(i);
5386                if (rec == dyingProc || rec.thread == null) {
5387                    continue;
5388                }
5389                if (doReport) {
5390                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5391                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5392                }
5393                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5394                    // The low memory report is overriding any current
5395                    // state for a GC request.  Make sure to do
5396                    // heavy/important/visible/foreground processes first.
5397                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5398                        rec.lastRequestedGc = 0;
5399                    } else {
5400                        rec.lastRequestedGc = rec.lastLowMemory;
5401                    }
5402                    rec.reportLowMemory = true;
5403                    rec.lastLowMemory = now;
5404                    mProcessesToGc.remove(rec);
5405                    addProcessToGcListLocked(rec);
5406                }
5407            }
5408            if (doReport) {
5409                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5410                mHandler.sendMessage(msg);
5411            }
5412            scheduleAppGcsLocked();
5413        }
5414    }
5415
5416    final void appDiedLocked(ProcessRecord app) {
5417       appDiedLocked(app, app.pid, app.thread, false);
5418    }
5419
5420    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5421            boolean fromBinderDied) {
5422        // First check if this ProcessRecord is actually active for the pid.
5423        synchronized (mPidsSelfLocked) {
5424            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5425            if (curProc != app) {
5426                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5427                return;
5428            }
5429        }
5430
5431        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5432        synchronized (stats) {
5433            stats.noteProcessDiedLocked(app.info.uid, pid);
5434        }
5435
5436        if (!app.killed) {
5437            if (!fromBinderDied) {
5438                killProcessQuiet(pid);
5439            }
5440            killProcessGroup(app.uid, pid);
5441            app.killed = true;
5442        }
5443
5444        // Clean up already done if the process has been re-started.
5445        if (app.pid == pid && app.thread != null &&
5446                app.thread.asBinder() == thread.asBinder()) {
5447            boolean doLowMem = app.instr == null;
5448            boolean doOomAdj = doLowMem;
5449            if (!app.killedByAm) {
5450                Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5451                        + ProcessList.makeOomAdjString(app.setAdj)
5452                        + ProcessList.makeProcStateString(app.setProcState));
5453                mAllowLowerMemLevel = true;
5454            } else {
5455                // Note that we always want to do oom adj to update our state with the
5456                // new number of procs.
5457                mAllowLowerMemLevel = false;
5458                doLowMem = false;
5459            }
5460            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5461                    app.setAdj, app.setProcState);
5462            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5463                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5464            handleAppDiedLocked(app, false, true);
5465
5466            if (doOomAdj) {
5467                updateOomAdjLocked();
5468            }
5469            if (doLowMem) {
5470                doLowMemReportIfNeededLocked(app);
5471            }
5472        } else if (app.pid != pid) {
5473            // A new process has already been started.
5474            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5475                    + ") has died and restarted (pid " + app.pid + ").");
5476            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5477        } else if (DEBUG_PROCESSES) {
5478            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5479                    + thread.asBinder());
5480        }
5481    }
5482
5483    /**
5484     * If a stack trace dump file is configured, dump process stack traces.
5485     * @param clearTraces causes the dump file to be erased prior to the new
5486     *    traces being written, if true; when false, the new traces will be
5487     *    appended to any existing file content.
5488     * @param firstPids of dalvik VM processes to dump stack traces for first
5489     * @param lastPids of dalvik VM processes to dump stack traces for last
5490     * @param nativePids optional list of native pids to dump stack crawls
5491     */
5492    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5493            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5494            ArrayList<Integer> nativePids) {
5495        ArrayList<Integer> extraPids = null;
5496
5497        // Measure CPU usage as soon as we're called in order to get a realistic sampling
5498        // of the top users at the time of the request.
5499        if (processCpuTracker != null) {
5500            processCpuTracker.init();
5501            try {
5502                Thread.sleep(200);
5503            } catch (InterruptedException ignored) {
5504            }
5505
5506            processCpuTracker.update();
5507
5508            // We'll take the stack crawls of just the top apps using CPU.
5509            final int N = processCpuTracker.countWorkingStats();
5510            extraPids = new ArrayList<>();
5511            for (int i = 0; i < N && extraPids.size() < 5; i++) {
5512                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5513                if (lastPids.indexOfKey(stats.pid) >= 0) {
5514                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5515
5516                    extraPids.add(stats.pid);
5517                } else if (DEBUG_ANR) {
5518                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5519                            + stats.pid);
5520                }
5521            }
5522        }
5523
5524        boolean useTombstonedForJavaTraces = false;
5525        File tracesFile;
5526
5527        final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5528        if (tracesDirProp.isEmpty()) {
5529            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5530            // dumping scheme. All traces are written to a global trace file (usually
5531            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5532            // the file if requested.
5533            //
5534            // This mode of operation will be removed in the near future.
5535
5536
5537            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5538            if (globalTracesPath.isEmpty()) {
5539                Slog.w(TAG, "dumpStackTraces: no trace path configured");
5540                return null;
5541            }
5542
5543            tracesFile = new File(globalTracesPath);
5544            try {
5545                if (clearTraces && tracesFile.exists()) {
5546                    tracesFile.delete();
5547                }
5548
5549                tracesFile.createNewFile();
5550                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5551            } catch (IOException e) {
5552                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5553                return null;
5554            }
5555        } else {
5556            File tracesDir = new File(tracesDirProp);
5557            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5558            // Each set of ANR traces is written to a separate file and dumpstate will process
5559            // all such files and add them to a captured bug report if they're recent enough.
5560            maybePruneOldTraces(tracesDir);
5561
5562            // NOTE: We should consider creating the file in native code atomically once we've
5563            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5564            // can be removed.
5565            tracesFile = createAnrDumpFile(tracesDir);
5566            if (tracesFile == null) {
5567                return null;
5568            }
5569
5570            useTombstonedForJavaTraces = true;
5571        }
5572
5573        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5574                useTombstonedForJavaTraces);
5575        return tracesFile;
5576    }
5577
5578    @GuardedBy("ActivityManagerService.class")
5579    private static SimpleDateFormat sAnrFileDateFormat;
5580
5581    private static synchronized File createAnrDumpFile(File tracesDir) {
5582        if (sAnrFileDateFormat == null) {
5583            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5584        }
5585
5586        final String formattedDate = sAnrFileDateFormat.format(new Date());
5587        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5588
5589        try {
5590            if (anrFile.createNewFile()) {
5591                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5592                return anrFile;
5593            } else {
5594                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5595            }
5596        } catch (IOException ioe) {
5597            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5598        }
5599
5600        return null;
5601    }
5602
5603    /**
5604     * Prune all trace files that are more than a day old.
5605     *
5606     * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5607     * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5608     * since it's the system_server that creates trace files for most ANRs.
5609     */
5610    private static void maybePruneOldTraces(File tracesDir) {
5611        final long now = System.currentTimeMillis();
5612        final File[] traceFiles = tracesDir.listFiles();
5613
5614        if (traceFiles != null) {
5615            for (File file : traceFiles) {
5616                if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5617                    if (!file.delete()) {
5618                        Slog.w(TAG, "Unable to prune stale trace file: " + file);
5619                    }
5620                }
5621            }
5622        }
5623    }
5624
5625    /**
5626     * Legacy code, do not use. Existing users will be deleted.
5627     *
5628     * @deprecated
5629     */
5630    @Deprecated
5631    public static class DumpStackFileObserver extends FileObserver {
5632        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5633        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5634
5635        private final String mTracesPath;
5636        private boolean mClosed;
5637
5638        public DumpStackFileObserver(String tracesPath) {
5639            super(tracesPath, FileObserver.CLOSE_WRITE);
5640            mTracesPath = tracesPath;
5641        }
5642
5643        @Override
5644        public synchronized void onEvent(int event, String path) {
5645            mClosed = true;
5646            notify();
5647        }
5648
5649        public long dumpWithTimeout(int pid, long timeout) {
5650            sendSignal(pid, SIGNAL_QUIT);
5651            final long start = SystemClock.elapsedRealtime();
5652
5653            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5654            synchronized (this) {
5655                try {
5656                    wait(waitTime); // Wait for traces file to be closed.
5657                } catch (InterruptedException e) {
5658                    Slog.wtf(TAG, e);
5659                }
5660            }
5661
5662            // This avoids a corner case of passing a negative time to the native
5663            // trace in case we've already hit the overall timeout.
5664            final long timeWaited = SystemClock.elapsedRealtime() - start;
5665            if (timeWaited >= timeout) {
5666                return timeWaited;
5667            }
5668
5669            if (!mClosed) {
5670                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5671                       ". Attempting native stack collection.");
5672
5673                final long nativeDumpTimeoutMs = Math.min(
5674                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5675
5676                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5677                        (int) (nativeDumpTimeoutMs / 1000));
5678            }
5679
5680            final long end = SystemClock.elapsedRealtime();
5681            mClosed = false;
5682
5683            return (end - start);
5684        }
5685    }
5686
5687    /**
5688     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5689     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5690     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5691     * attempting to obtain native traces in the case of a failure. Returns the total time spent
5692     * capturing traces.
5693     */
5694    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5695        final long timeStart = SystemClock.elapsedRealtime();
5696        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5697            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5698                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
5699        }
5700
5701        return SystemClock.elapsedRealtime() - timeStart;
5702    }
5703
5704    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5705            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5706            boolean useTombstonedForJavaTraces) {
5707
5708        // We don't need any sort of inotify based monitoring when we're dumping traces via
5709        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5710        // control of all writes to the file in question.
5711        final DumpStackFileObserver observer;
5712        if (useTombstonedForJavaTraces) {
5713            observer = null;
5714        } else {
5715            // Use a FileObserver to detect when traces finish writing.
5716            // The order of traces is considered important to maintain for legibility.
5717            observer = new DumpStackFileObserver(tracesFile);
5718        }
5719
5720        // We must complete all stack dumps within 20 seconds.
5721        long remainingTime = 20 * 1000;
5722        try {
5723            if (observer != null) {
5724                observer.startWatching();
5725            }
5726
5727            // First collect all of the stacks of the most important pids.
5728            if (firstPids != null) {
5729                int num = firstPids.size();
5730                for (int i = 0; i < num; i++) {
5731                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5732                            + firstPids.get(i));
5733                    final long timeTaken;
5734                    if (useTombstonedForJavaTraces) {
5735                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5736                    } else {
5737                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5738                    }
5739
5740                    remainingTime -= timeTaken;
5741                    if (remainingTime <= 0) {
5742                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5743                            "); deadline exceeded.");
5744                        return;
5745                    }
5746
5747                    if (DEBUG_ANR) {
5748                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5749                    }
5750                }
5751            }
5752
5753            // Next collect the stacks of the native pids
5754            if (nativePids != null) {
5755                for (int pid : nativePids) {
5756                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5757                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5758
5759                    final long start = SystemClock.elapsedRealtime();
5760                    Debug.dumpNativeBacktraceToFileTimeout(
5761                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5762                    final long timeTaken = SystemClock.elapsedRealtime() - start;
5763
5764                    remainingTime -= timeTaken;
5765                    if (remainingTime <= 0) {
5766                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5767                            "); deadline exceeded.");
5768                        return;
5769                    }
5770
5771                    if (DEBUG_ANR) {
5772                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5773                    }
5774                }
5775            }
5776
5777            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5778            if (extraPids != null) {
5779                for (int pid : extraPids) {
5780                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5781
5782                    final long timeTaken;
5783                    if (useTombstonedForJavaTraces) {
5784                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5785                    } else {
5786                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5787                    }
5788
5789                    remainingTime -= timeTaken;
5790                    if (remainingTime <= 0) {
5791                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5792                                "); deadline exceeded.");
5793                        return;
5794                    }
5795
5796                    if (DEBUG_ANR) {
5797                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5798                    }
5799                }
5800            }
5801        } finally {
5802            if (observer != null) {
5803                observer.stopWatching();
5804            }
5805        }
5806    }
5807
5808    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5809        if (true || Build.IS_USER) {
5810            return;
5811        }
5812        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5813        if (tracesPath == null || tracesPath.length() == 0) {
5814            return;
5815        }
5816
5817        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5818        StrictMode.allowThreadDiskWrites();
5819        try {
5820            final File tracesFile = new File(tracesPath);
5821            final File tracesDir = tracesFile.getParentFile();
5822            final File tracesTmp = new File(tracesDir, "__tmp__");
5823            try {
5824                if (tracesFile.exists()) {
5825                    tracesTmp.delete();
5826                    tracesFile.renameTo(tracesTmp);
5827                }
5828                StringBuilder sb = new StringBuilder();
5829                Time tobj = new Time();
5830                tobj.set(System.currentTimeMillis());
5831                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5832                sb.append(": ");
5833                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5834                sb.append(" since ");
5835                sb.append(msg);
5836                FileOutputStream fos = new FileOutputStream(tracesFile);
5837                fos.write(sb.toString().getBytes());
5838                if (app == null) {
5839                    fos.write("\n*** No application process!".getBytes());
5840                }
5841                fos.close();
5842                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5843            } catch (IOException e) {
5844                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5845                return;
5846            }
5847
5848            if (app != null) {
5849                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5850                firstPids.add(app.pid);
5851                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5852            }
5853
5854            File lastTracesFile = null;
5855            File curTracesFile = null;
5856            for (int i=9; i>=0; i--) {
5857                String name = String.format(Locale.US, "slow%02d.txt", i);
5858                curTracesFile = new File(tracesDir, name);
5859                if (curTracesFile.exists()) {
5860                    if (lastTracesFile != null) {
5861                        curTracesFile.renameTo(lastTracesFile);
5862                    } else {
5863                        curTracesFile.delete();
5864                    }
5865                }
5866                lastTracesFile = curTracesFile;
5867            }
5868            tracesFile.renameTo(curTracesFile);
5869            if (tracesTmp.exists()) {
5870                tracesTmp.renameTo(tracesFile);
5871            }
5872        } finally {
5873            StrictMode.setThreadPolicy(oldPolicy);
5874        }
5875    }
5876
5877    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5878        if (!mLaunchWarningShown) {
5879            mLaunchWarningShown = true;
5880            mUiHandler.post(new Runnable() {
5881                @Override
5882                public void run() {
5883                    synchronized (ActivityManagerService.this) {
5884                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5885                        d.show();
5886                        mUiHandler.postDelayed(new Runnable() {
5887                            @Override
5888                            public void run() {
5889                                synchronized (ActivityManagerService.this) {
5890                                    d.dismiss();
5891                                    mLaunchWarningShown = false;
5892                                }
5893                            }
5894                        }, 4000);
5895                    }
5896                }
5897            });
5898        }
5899    }
5900
5901    @Override
5902    public boolean clearApplicationUserData(final String packageName,
5903            final IPackageDataObserver observer, int userId) {
5904        enforceNotIsolatedCaller("clearApplicationUserData");
5905        int uid = Binder.getCallingUid();
5906        int pid = Binder.getCallingPid();
5907        final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5908                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5909
5910        final ApplicationInfo appInfo;
5911        final boolean isInstantApp;
5912
5913        long callingId = Binder.clearCallingIdentity();
5914        try {
5915            IPackageManager pm = AppGlobals.getPackageManager();
5916            synchronized(this) {
5917                // Instant packages are not protected
5918                if (getPackageManagerInternalLocked().isPackageDataProtected(
5919                        resolvedUserId, packageName)) {
5920                    throw new SecurityException(
5921                            "Cannot clear data for a protected package: " + packageName);
5922                }
5923
5924                ApplicationInfo applicationInfo = null;
5925                try {
5926                    applicationInfo = pm.getApplicationInfo(packageName,
5927                            MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5928                } catch (RemoteException e) {
5929                    /* ignore */
5930                }
5931                appInfo = applicationInfo;
5932
5933                final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5934
5935                if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5936                        pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5937                    throw new SecurityException("PID " + pid + " does not have permission "
5938                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5939                            + " of package " + packageName);
5940                }
5941
5942                final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5943                        .hasInstantApplicationMetadata(packageName, resolvedUserId);
5944                final boolean isUninstalledAppWithoutInstantMetadata =
5945                        (appInfo == null && !hasInstantMetadata);
5946                isInstantApp = (appInfo != null && appInfo.isInstantApp())
5947                        || hasInstantMetadata;
5948                final boolean canAccessInstantApps = checkComponentPermission(
5949                        permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5950                        == PackageManager.PERMISSION_GRANTED;
5951
5952                if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5953                        && !canAccessInstantApps)) {
5954                    Slog.w(TAG, "Invalid packageName: " + packageName);
5955                    if (observer != null) {
5956                        try {
5957                            observer.onRemoveCompleted(packageName, false);
5958                        } catch (RemoteException e) {
5959                            Slog.i(TAG, "Observer no longer exists.");
5960                        }
5961                    }
5962                    return false;
5963                }
5964
5965                if (appInfo != null) {
5966                    forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5967                    // Remove all tasks match the cleared application package and user
5968                    for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5969                        final TaskRecord tr = mRecentTasks.get(i);
5970                        final String taskPackageName =
5971                                tr.getBaseIntent().getComponent().getPackageName();
5972                        if (tr.userId != resolvedUserId) continue;
5973                        if (!taskPackageName.equals(packageName)) continue;
5974                        mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5975                                REMOVE_FROM_RECENTS);
5976                    }
5977                }
5978            }
5979
5980            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5981                @Override
5982                public void onRemoveCompleted(String packageName, boolean succeeded)
5983                        throws RemoteException {
5984                    if (appInfo != null) {
5985                        synchronized (ActivityManagerService.this) {
5986                            finishForceStopPackageLocked(packageName, appInfo.uid);
5987                        }
5988                    }
5989                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5990                            Uri.fromParts("package", packageName, null));
5991                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5992                    intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
5993                    intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
5994                    if (isInstantApp) {
5995                        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
5996                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5997                                null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
5998                                resolvedUserId);
5999                    } else {
6000                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6001                                null, null, null, null, false, false, resolvedUserId);
6002                    }
6003
6004                    if (observer != null) {
6005                        observer.onRemoveCompleted(packageName, succeeded);
6006                    }
6007                }
6008            };
6009
6010            try {
6011                // Clear application user data
6012                pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6013
6014                if (appInfo != null) {
6015                    synchronized (this) {
6016                        // Remove all permissions granted from/to this package
6017                        removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6018                    }
6019
6020                    // Reset notification settings.
6021                    INotificationManager inm = NotificationManager.getService();
6022                    inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6023                }
6024            } catch (RemoteException e) {
6025            }
6026        } finally {
6027            Binder.restoreCallingIdentity(callingId);
6028        }
6029        return true;
6030    }
6031
6032    @Override
6033    public void killBackgroundProcesses(final String packageName, int userId) {
6034        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6035                != PackageManager.PERMISSION_GRANTED &&
6036                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6037                        != PackageManager.PERMISSION_GRANTED) {
6038            String msg = "Permission Denial: killBackgroundProcesses() from pid="
6039                    + Binder.getCallingPid()
6040                    + ", uid=" + Binder.getCallingUid()
6041                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6042            Slog.w(TAG, msg);
6043            throw new SecurityException(msg);
6044        }
6045
6046        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6047                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6048        long callingId = Binder.clearCallingIdentity();
6049        try {
6050            IPackageManager pm = AppGlobals.getPackageManager();
6051            synchronized(this) {
6052                int appId = -1;
6053                try {
6054                    appId = UserHandle.getAppId(
6055                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6056                } catch (RemoteException e) {
6057                }
6058                if (appId == -1) {
6059                    Slog.w(TAG, "Invalid packageName: " + packageName);
6060                    return;
6061                }
6062                killPackageProcessesLocked(packageName, appId, userId,
6063                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6064            }
6065        } finally {
6066            Binder.restoreCallingIdentity(callingId);
6067        }
6068    }
6069
6070    @Override
6071    public void killAllBackgroundProcesses() {
6072        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6073                != PackageManager.PERMISSION_GRANTED) {
6074            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6075                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6076                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6077            Slog.w(TAG, msg);
6078            throw new SecurityException(msg);
6079        }
6080
6081        final long callingId = Binder.clearCallingIdentity();
6082        try {
6083            synchronized (this) {
6084                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6085                final int NP = mProcessNames.getMap().size();
6086                for (int ip = 0; ip < NP; ip++) {
6087                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6088                    final int NA = apps.size();
6089                    for (int ia = 0; ia < NA; ia++) {
6090                        final ProcessRecord app = apps.valueAt(ia);
6091                        if (app.persistent) {
6092                            // We don't kill persistent processes.
6093                            continue;
6094                        }
6095                        if (app.removed) {
6096                            procs.add(app);
6097                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6098                            app.removed = true;
6099                            procs.add(app);
6100                        }
6101                    }
6102                }
6103
6104                final int N = procs.size();
6105                for (int i = 0; i < N; i++) {
6106                    removeProcessLocked(procs.get(i), false, true, "kill all background");
6107                }
6108
6109                mAllowLowerMemLevel = true;
6110
6111                updateOomAdjLocked();
6112                doLowMemReportIfNeededLocked(null);
6113            }
6114        } finally {
6115            Binder.restoreCallingIdentity(callingId);
6116        }
6117    }
6118
6119    /**
6120     * Kills all background processes, except those matching any of the
6121     * specified properties.
6122     *
6123     * @param minTargetSdk the target SDK version at or above which to preserve
6124     *                     processes, or {@code -1} to ignore the target SDK
6125     * @param maxProcState the process state at or below which to preserve
6126     *                     processes, or {@code -1} to ignore the process state
6127     */
6128    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6129        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6130                != PackageManager.PERMISSION_GRANTED) {
6131            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6132                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6133                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6134            Slog.w(TAG, msg);
6135            throw new SecurityException(msg);
6136        }
6137
6138        final long callingId = Binder.clearCallingIdentity();
6139        try {
6140            synchronized (this) {
6141                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6142                final int NP = mProcessNames.getMap().size();
6143                for (int ip = 0; ip < NP; ip++) {
6144                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6145                    final int NA = apps.size();
6146                    for (int ia = 0; ia < NA; ia++) {
6147                        final ProcessRecord app = apps.valueAt(ia);
6148                        if (app.removed) {
6149                            procs.add(app);
6150                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6151                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6152                            app.removed = true;
6153                            procs.add(app);
6154                        }
6155                    }
6156                }
6157
6158                final int N = procs.size();
6159                for (int i = 0; i < N; i++) {
6160                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6161                }
6162            }
6163        } finally {
6164            Binder.restoreCallingIdentity(callingId);
6165        }
6166    }
6167
6168    @Override
6169    public void forceStopPackage(final String packageName, int userId) {
6170        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6171                != PackageManager.PERMISSION_GRANTED) {
6172            String msg = "Permission Denial: forceStopPackage() from pid="
6173                    + Binder.getCallingPid()
6174                    + ", uid=" + Binder.getCallingUid()
6175                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6176            Slog.w(TAG, msg);
6177            throw new SecurityException(msg);
6178        }
6179        final int callingPid = Binder.getCallingPid();
6180        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6181                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6182        long callingId = Binder.clearCallingIdentity();
6183        try {
6184            IPackageManager pm = AppGlobals.getPackageManager();
6185            synchronized(this) {
6186                int[] users = userId == UserHandle.USER_ALL
6187                        ? mUserController.getUsers() : new int[] { userId };
6188                for (int user : users) {
6189                    int pkgUid = -1;
6190                    try {
6191                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6192                                user);
6193                    } catch (RemoteException e) {
6194                    }
6195                    if (pkgUid == -1) {
6196                        Slog.w(TAG, "Invalid packageName: " + packageName);
6197                        continue;
6198                    }
6199                    try {
6200                        pm.setPackageStoppedState(packageName, true, user);
6201                    } catch (RemoteException e) {
6202                    } catch (IllegalArgumentException e) {
6203                        Slog.w(TAG, "Failed trying to unstop package "
6204                                + packageName + ": " + e);
6205                    }
6206                    if (mUserController.isUserRunningLocked(user, 0)) {
6207                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6208                        finishForceStopPackageLocked(packageName, pkgUid);
6209                    }
6210                }
6211            }
6212        } finally {
6213            Binder.restoreCallingIdentity(callingId);
6214        }
6215    }
6216
6217    @Override
6218    public void addPackageDependency(String packageName) {
6219        synchronized (this) {
6220            int callingPid = Binder.getCallingPid();
6221            if (callingPid == myPid()) {
6222                //  Yeah, um, no.
6223                return;
6224            }
6225            ProcessRecord proc;
6226            synchronized (mPidsSelfLocked) {
6227                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6228            }
6229            if (proc != null) {
6230                if (proc.pkgDeps == null) {
6231                    proc.pkgDeps = new ArraySet<String>(1);
6232                }
6233                proc.pkgDeps.add(packageName);
6234            }
6235        }
6236    }
6237
6238    /*
6239     * The pkg name and app id have to be specified.
6240     */
6241    @Override
6242    public void killApplication(String pkg, int appId, int userId, String reason) {
6243        if (pkg == null) {
6244            return;
6245        }
6246        // Make sure the uid is valid.
6247        if (appId < 0) {
6248            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6249            return;
6250        }
6251        int callerUid = Binder.getCallingUid();
6252        // Only the system server can kill an application
6253        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6254            // Post an aysnc message to kill the application
6255            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6256            msg.arg1 = appId;
6257            msg.arg2 = userId;
6258            Bundle bundle = new Bundle();
6259            bundle.putString("pkg", pkg);
6260            bundle.putString("reason", reason);
6261            msg.obj = bundle;
6262            mHandler.sendMessage(msg);
6263        } else {
6264            throw new SecurityException(callerUid + " cannot kill pkg: " +
6265                    pkg);
6266        }
6267    }
6268
6269    @Override
6270    public void closeSystemDialogs(String reason) {
6271        enforceNotIsolatedCaller("closeSystemDialogs");
6272
6273        final int pid = Binder.getCallingPid();
6274        final int uid = Binder.getCallingUid();
6275        final long origId = Binder.clearCallingIdentity();
6276        try {
6277            synchronized (this) {
6278                // Only allow this from foreground processes, so that background
6279                // applications can't abuse it to prevent system UI from being shown.
6280                if (uid >= FIRST_APPLICATION_UID) {
6281                    ProcessRecord proc;
6282                    synchronized (mPidsSelfLocked) {
6283                        proc = mPidsSelfLocked.get(pid);
6284                    }
6285                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6286                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6287                                + " from background process " + proc);
6288                        return;
6289                    }
6290                }
6291                closeSystemDialogsLocked(reason);
6292            }
6293        } finally {
6294            Binder.restoreCallingIdentity(origId);
6295        }
6296    }
6297
6298    void closeSystemDialogsLocked(String reason) {
6299        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6300        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6301                | Intent.FLAG_RECEIVER_FOREGROUND);
6302        if (reason != null) {
6303            intent.putExtra("reason", reason);
6304        }
6305        mWindowManager.closeSystemDialogs(reason);
6306
6307        mStackSupervisor.closeSystemDialogsLocked();
6308
6309        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6310                AppOpsManager.OP_NONE, null, false, false,
6311                -1, SYSTEM_UID, UserHandle.USER_ALL);
6312    }
6313
6314    @Override
6315    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6316        enforceNotIsolatedCaller("getProcessMemoryInfo");
6317        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6318        for (int i=pids.length-1; i>=0; i--) {
6319            ProcessRecord proc;
6320            int oomAdj;
6321            synchronized (this) {
6322                synchronized (mPidsSelfLocked) {
6323                    proc = mPidsSelfLocked.get(pids[i]);
6324                    oomAdj = proc != null ? proc.setAdj : 0;
6325                }
6326            }
6327            infos[i] = new Debug.MemoryInfo();
6328            Debug.getMemoryInfo(pids[i], infos[i]);
6329            if (proc != null) {
6330                synchronized (this) {
6331                    if (proc.thread != null && proc.setAdj == oomAdj) {
6332                        // Record this for posterity if the process has been stable.
6333                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6334                                infos[i].getTotalUss(), false, proc.pkgList);
6335                    }
6336                }
6337            }
6338        }
6339        return infos;
6340    }
6341
6342    @Override
6343    public long[] getProcessPss(int[] pids) {
6344        enforceNotIsolatedCaller("getProcessPss");
6345        long[] pss = new long[pids.length];
6346        for (int i=pids.length-1; i>=0; i--) {
6347            ProcessRecord proc;
6348            int oomAdj;
6349            synchronized (this) {
6350                synchronized (mPidsSelfLocked) {
6351                    proc = mPidsSelfLocked.get(pids[i]);
6352                    oomAdj = proc != null ? proc.setAdj : 0;
6353                }
6354            }
6355            long[] tmpUss = new long[1];
6356            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6357            if (proc != null) {
6358                synchronized (this) {
6359                    if (proc.thread != null && proc.setAdj == oomAdj) {
6360                        // Record this for posterity if the process has been stable.
6361                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6362                    }
6363                }
6364            }
6365        }
6366        return pss;
6367    }
6368
6369    @Override
6370    public void killApplicationProcess(String processName, int uid) {
6371        if (processName == null) {
6372            return;
6373        }
6374
6375        int callerUid = Binder.getCallingUid();
6376        // Only the system server can kill an application
6377        if (callerUid == SYSTEM_UID) {
6378            synchronized (this) {
6379                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6380                if (app != null && app.thread != null) {
6381                    try {
6382                        app.thread.scheduleSuicide();
6383                    } catch (RemoteException e) {
6384                        // If the other end already died, then our work here is done.
6385                    }
6386                } else {
6387                    Slog.w(TAG, "Process/uid not found attempting kill of "
6388                            + processName + " / " + uid);
6389                }
6390            }
6391        } else {
6392            throw new SecurityException(callerUid + " cannot kill app process: " +
6393                    processName);
6394        }
6395    }
6396
6397    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6398        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6399                false, true, false, false, UserHandle.getUserId(uid), reason);
6400    }
6401
6402    private void finishForceStopPackageLocked(final String packageName, int uid) {
6403        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6404                Uri.fromParts("package", packageName, null));
6405        if (!mProcessesReady) {
6406            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6407                    | Intent.FLAG_RECEIVER_FOREGROUND);
6408        }
6409        intent.putExtra(Intent.EXTRA_UID, uid);
6410        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6411        broadcastIntentLocked(null, null, intent,
6412                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6413                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6414    }
6415
6416
6417    private final boolean killPackageProcessesLocked(String packageName, int appId,
6418            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6419            boolean doit, boolean evenPersistent, String reason) {
6420        ArrayList<ProcessRecord> procs = new ArrayList<>();
6421
6422        // Remove all processes this package may have touched: all with the
6423        // same UID (except for the system or root user), and all whose name
6424        // matches the package name.
6425        final int NP = mProcessNames.getMap().size();
6426        for (int ip=0; ip<NP; ip++) {
6427            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6428            final int NA = apps.size();
6429            for (int ia=0; ia<NA; ia++) {
6430                ProcessRecord app = apps.valueAt(ia);
6431                if (app.persistent && !evenPersistent) {
6432                    // we don't kill persistent processes
6433                    continue;
6434                }
6435                if (app.removed) {
6436                    if (doit) {
6437                        procs.add(app);
6438                    }
6439                    continue;
6440                }
6441
6442                // Skip process if it doesn't meet our oom adj requirement.
6443                if (app.setAdj < minOomAdj) {
6444                    continue;
6445                }
6446
6447                // If no package is specified, we call all processes under the
6448                // give user id.
6449                if (packageName == null) {
6450                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6451                        continue;
6452                    }
6453                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6454                        continue;
6455                    }
6456                // Package has been specified, we want to hit all processes
6457                // that match it.  We need to qualify this by the processes
6458                // that are running under the specified app and user ID.
6459                } else {
6460                    final boolean isDep = app.pkgDeps != null
6461                            && app.pkgDeps.contains(packageName);
6462                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6463                        continue;
6464                    }
6465                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6466                        continue;
6467                    }
6468                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6469                        continue;
6470                    }
6471                }
6472
6473                // Process has passed all conditions, kill it!
6474                if (!doit) {
6475                    return true;
6476                }
6477                app.removed = true;
6478                procs.add(app);
6479            }
6480        }
6481
6482        int N = procs.size();
6483        for (int i=0; i<N; i++) {
6484            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6485        }
6486        updateOomAdjLocked();
6487        return N > 0;
6488    }
6489
6490    private void cleanupDisabledPackageComponentsLocked(
6491            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6492
6493        Set<String> disabledClasses = null;
6494        boolean packageDisabled = false;
6495        IPackageManager pm = AppGlobals.getPackageManager();
6496
6497        if (changedClasses == null) {
6498            // Nothing changed...
6499            return;
6500        }
6501
6502        // Determine enable/disable state of the package and its components.
6503        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6504        for (int i = changedClasses.length - 1; i >= 0; i--) {
6505            final String changedClass = changedClasses[i];
6506
6507            if (changedClass.equals(packageName)) {
6508                try {
6509                    // Entire package setting changed
6510                    enabled = pm.getApplicationEnabledSetting(packageName,
6511                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6512                } catch (Exception e) {
6513                    // No such package/component; probably racing with uninstall.  In any
6514                    // event it means we have nothing further to do here.
6515                    return;
6516                }
6517                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6518                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6519                if (packageDisabled) {
6520                    // Entire package is disabled.
6521                    // No need to continue to check component states.
6522                    disabledClasses = null;
6523                    break;
6524                }
6525            } else {
6526                try {
6527                    enabled = pm.getComponentEnabledSetting(
6528                            new ComponentName(packageName, changedClass),
6529                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6530                } catch (Exception e) {
6531                    // As above, probably racing with uninstall.
6532                    return;
6533                }
6534                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6535                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6536                    if (disabledClasses == null) {
6537                        disabledClasses = new ArraySet<>(changedClasses.length);
6538                    }
6539                    disabledClasses.add(changedClass);
6540                }
6541            }
6542        }
6543
6544        if (!packageDisabled && disabledClasses == null) {
6545            // Nothing to do here...
6546            return;
6547        }
6548
6549        // Clean-up disabled activities.
6550        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6551                packageName, disabledClasses, true, false, userId) && mBooted) {
6552            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6553            mStackSupervisor.scheduleIdleLocked();
6554        }
6555
6556        // Clean-up disabled tasks
6557        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6558
6559        // Clean-up disabled services.
6560        mServices.bringDownDisabledPackageServicesLocked(
6561                packageName, disabledClasses, userId, false, killProcess, true);
6562
6563        // Clean-up disabled providers.
6564        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6565        mProviderMap.collectPackageProvidersLocked(
6566                packageName, disabledClasses, true, false, userId, providers);
6567        for (int i = providers.size() - 1; i >= 0; i--) {
6568            removeDyingProviderLocked(null, providers.get(i), true);
6569        }
6570
6571        // Clean-up disabled broadcast receivers.
6572        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6573            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6574                    packageName, disabledClasses, userId, true);
6575        }
6576
6577    }
6578
6579    final boolean clearBroadcastQueueForUserLocked(int userId) {
6580        boolean didSomething = false;
6581        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6582            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6583                    null, null, userId, true);
6584        }
6585        return didSomething;
6586    }
6587
6588    final boolean forceStopPackageLocked(String packageName, int appId,
6589            boolean callerWillRestart, boolean purgeCache, boolean doit,
6590            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6591        int i;
6592
6593        if (userId == UserHandle.USER_ALL && packageName == null) {
6594            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6595        }
6596
6597        if (appId < 0 && packageName != null) {
6598            try {
6599                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6600                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6601            } catch (RemoteException e) {
6602            }
6603        }
6604
6605        if (doit) {
6606            if (packageName != null) {
6607                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6608                        + " user=" + userId + ": " + reason);
6609            } else {
6610                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6611            }
6612
6613            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6614        }
6615
6616        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6617                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6618                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6619
6620        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6621
6622        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6623                packageName, null, doit, evenPersistent, userId)) {
6624            if (!doit) {
6625                return true;
6626            }
6627            didSomething = true;
6628        }
6629
6630        if (mServices.bringDownDisabledPackageServicesLocked(
6631                packageName, null, userId, evenPersistent, true, doit)) {
6632            if (!doit) {
6633                return true;
6634            }
6635            didSomething = true;
6636        }
6637
6638        if (packageName == null) {
6639            // Remove all sticky broadcasts from this user.
6640            mStickyBroadcasts.remove(userId);
6641        }
6642
6643        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6644        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6645                userId, providers)) {
6646            if (!doit) {
6647                return true;
6648            }
6649            didSomething = true;
6650        }
6651        for (i = providers.size() - 1; i >= 0; i--) {
6652            removeDyingProviderLocked(null, providers.get(i), true);
6653        }
6654
6655        // Remove transient permissions granted from/to this package/user
6656        removeUriPermissionsForPackageLocked(packageName, userId, false);
6657
6658        if (doit) {
6659            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6660                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6661                        packageName, null, userId, doit);
6662            }
6663        }
6664
6665        if (packageName == null || uninstalling) {
6666            // Remove pending intents.  For now we only do this when force
6667            // stopping users, because we have some problems when doing this
6668            // for packages -- app widgets are not currently cleaned up for
6669            // such packages, so they can be left with bad pending intents.
6670            if (mIntentSenderRecords.size() > 0) {
6671                Iterator<WeakReference<PendingIntentRecord>> it
6672                        = mIntentSenderRecords.values().iterator();
6673                while (it.hasNext()) {
6674                    WeakReference<PendingIntentRecord> wpir = it.next();
6675                    if (wpir == null) {
6676                        it.remove();
6677                        continue;
6678                    }
6679                    PendingIntentRecord pir = wpir.get();
6680                    if (pir == null) {
6681                        it.remove();
6682                        continue;
6683                    }
6684                    if (packageName == null) {
6685                        // Stopping user, remove all objects for the user.
6686                        if (pir.key.userId != userId) {
6687                            // Not the same user, skip it.
6688                            continue;
6689                        }
6690                    } else {
6691                        if (UserHandle.getAppId(pir.uid) != appId) {
6692                            // Different app id, skip it.
6693                            continue;
6694                        }
6695                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6696                            // Different user, skip it.
6697                            continue;
6698                        }
6699                        if (!pir.key.packageName.equals(packageName)) {
6700                            // Different package, skip it.
6701                            continue;
6702                        }
6703                    }
6704                    if (!doit) {
6705                        return true;
6706                    }
6707                    didSomething = true;
6708                    it.remove();
6709                    makeIntentSenderCanceledLocked(pir);
6710                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6711                        pir.key.activity.pendingResults.remove(pir.ref);
6712                    }
6713                }
6714            }
6715        }
6716
6717        if (doit) {
6718            if (purgeCache && packageName != null) {
6719                AttributeCache ac = AttributeCache.instance();
6720                if (ac != null) {
6721                    ac.removePackage(packageName);
6722                }
6723            }
6724            if (mBooted) {
6725                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6726                mStackSupervisor.scheduleIdleLocked();
6727            }
6728        }
6729
6730        return didSomething;
6731    }
6732
6733    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6734        return removeProcessNameLocked(name, uid, null);
6735    }
6736
6737    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6738            final ProcessRecord expecting) {
6739        ProcessRecord old = mProcessNames.get(name, uid);
6740        // Only actually remove when the currently recorded value matches the
6741        // record that we expected; if it doesn't match then we raced with a
6742        // newly created process and we don't want to destroy the new one.
6743        if ((expecting == null) || (old == expecting)) {
6744            mProcessNames.remove(name, uid);
6745        }
6746        if (old != null && old.uidRecord != null) {
6747            old.uidRecord.numProcs--;
6748            if (old.uidRecord.numProcs == 0) {
6749                // No more processes using this uid, tell clients it is gone.
6750                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6751                        "No more processes in " + old.uidRecord);
6752                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6753                EventLogTags.writeAmUidStopped(uid);
6754                mActiveUids.remove(uid);
6755                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6756            }
6757            old.uidRecord = null;
6758        }
6759        mIsolatedProcesses.remove(uid);
6760        return old;
6761    }
6762
6763    private final void addProcessNameLocked(ProcessRecord proc) {
6764        // We shouldn't already have a process under this name, but just in case we
6765        // need to clean up whatever may be there now.
6766        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6767        if (old == proc && proc.persistent) {
6768            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6769            Slog.w(TAG, "Re-adding persistent process " + proc);
6770        } else if (old != null) {
6771            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6772        }
6773        UidRecord uidRec = mActiveUids.get(proc.uid);
6774        if (uidRec == null) {
6775            uidRec = new UidRecord(proc.uid);
6776            // This is the first appearance of the uid, report it now!
6777            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6778                    "Creating new process uid: " + uidRec);
6779            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6780                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6781                uidRec.setWhitelist = uidRec.curWhitelist = true;
6782            }
6783            uidRec.updateHasInternetPermission();
6784            mActiveUids.put(proc.uid, uidRec);
6785            EventLogTags.writeAmUidRunning(uidRec.uid);
6786            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6787        }
6788        proc.uidRecord = uidRec;
6789
6790        // Reset render thread tid if it was already set, so new process can set it again.
6791        proc.renderThreadTid = 0;
6792        uidRec.numProcs++;
6793        mProcessNames.put(proc.processName, proc.uid, proc);
6794        if (proc.isolated) {
6795            mIsolatedProcesses.put(proc.uid, proc);
6796        }
6797    }
6798
6799    boolean removeProcessLocked(ProcessRecord app,
6800            boolean callerWillRestart, boolean allowRestart, String reason) {
6801        final String name = app.processName;
6802        final int uid = app.uid;
6803        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6804            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6805
6806        ProcessRecord old = mProcessNames.get(name, uid);
6807        if (old != app) {
6808            // This process is no longer active, so nothing to do.
6809            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6810            return false;
6811        }
6812        removeProcessNameLocked(name, uid);
6813        if (mHeavyWeightProcess == app) {
6814            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6815                    mHeavyWeightProcess.userId, 0));
6816            mHeavyWeightProcess = null;
6817        }
6818        boolean needRestart = false;
6819        if (app.pid > 0 && app.pid != MY_PID) {
6820            int pid = app.pid;
6821            synchronized (mPidsSelfLocked) {
6822                mPidsSelfLocked.remove(pid);
6823                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6824            }
6825            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6826            boolean willRestart = false;
6827            if (app.persistent && !app.isolated) {
6828                if (!callerWillRestart) {
6829                    willRestart = true;
6830                } else {
6831                    needRestart = true;
6832                }
6833            }
6834            app.kill(reason, true);
6835            if (app.isolated) {
6836                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6837                getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6838            }
6839            handleAppDiedLocked(app, willRestart, allowRestart);
6840            if (willRestart) {
6841                removeLruProcessLocked(app);
6842                addAppLocked(app.info, null, false, null /* ABI override */);
6843            }
6844        } else {
6845            mRemovedProcesses.add(app);
6846        }
6847
6848        return needRestart;
6849    }
6850
6851    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6852        cleanupAppInLaunchingProvidersLocked(app, true);
6853        removeProcessLocked(app, false, true, "timeout publishing content providers");
6854    }
6855
6856    private final void processStartTimedOutLocked(ProcessRecord app) {
6857        final int pid = app.pid;
6858        boolean gone = false;
6859        synchronized (mPidsSelfLocked) {
6860            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6861            if (knownApp != null && knownApp.thread == null) {
6862                mPidsSelfLocked.remove(pid);
6863                gone = true;
6864            }
6865        }
6866
6867        if (gone) {
6868            Slog.w(TAG, "Process " + app + " failed to attach");
6869            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6870                    pid, app.uid, app.processName);
6871            removeProcessNameLocked(app.processName, app.uid);
6872            if (mHeavyWeightProcess == app) {
6873                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6874                        mHeavyWeightProcess.userId, 0));
6875                mHeavyWeightProcess = null;
6876            }
6877            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6878            // Take care of any launching providers waiting for this process.
6879            cleanupAppInLaunchingProvidersLocked(app, true);
6880            // Take care of any services that are waiting for the process.
6881            mServices.processStartTimedOutLocked(app);
6882            app.kill("start timeout", true);
6883            if (app.isolated) {
6884                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6885            }
6886            removeLruProcessLocked(app);
6887            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6888                Slog.w(TAG, "Unattached app died before backup, skipping");
6889                mHandler.post(new Runnable() {
6890                @Override
6891                    public void run(){
6892                        try {
6893                            IBackupManager bm = IBackupManager.Stub.asInterface(
6894                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6895                            bm.agentDisconnected(app.info.packageName);
6896                        } catch (RemoteException e) {
6897                            // Can't happen; the backup manager is local
6898                        }
6899                    }
6900                });
6901            }
6902            if (isPendingBroadcastProcessLocked(pid)) {
6903                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6904                skipPendingBroadcastLocked(pid);
6905            }
6906        } else {
6907            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6908        }
6909    }
6910
6911    private final boolean attachApplicationLocked(IApplicationThread thread,
6912            int pid) {
6913
6914        // Find the application record that is being attached...  either via
6915        // the pid if we are running in multiple processes, or just pull the
6916        // next app record if we are emulating process with anonymous threads.
6917        ProcessRecord app;
6918        long startTime = SystemClock.uptimeMillis();
6919        if (pid != MY_PID && pid >= 0) {
6920            synchronized (mPidsSelfLocked) {
6921                app = mPidsSelfLocked.get(pid);
6922            }
6923        } else {
6924            app = null;
6925        }
6926
6927        if (app == null) {
6928            Slog.w(TAG, "No pending application record for pid " + pid
6929                    + " (IApplicationThread " + thread + "); dropping process");
6930            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6931            if (pid > 0 && pid != MY_PID) {
6932                killProcessQuiet(pid);
6933                //TODO: killProcessGroup(app.info.uid, pid);
6934            } else {
6935                try {
6936                    thread.scheduleExit();
6937                } catch (Exception e) {
6938                    // Ignore exceptions.
6939                }
6940            }
6941            return false;
6942        }
6943
6944        // If this application record is still attached to a previous
6945        // process, clean it up now.
6946        if (app.thread != null) {
6947            handleAppDiedLocked(app, true, true);
6948        }
6949
6950        // Tell the process all about itself.
6951
6952        if (DEBUG_ALL) Slog.v(
6953                TAG, "Binding process pid " + pid + " to record " + app);
6954
6955        final String processName = app.processName;
6956        try {
6957            AppDeathRecipient adr = new AppDeathRecipient(
6958                    app, pid, thread);
6959            thread.asBinder().linkToDeath(adr, 0);
6960            app.deathRecipient = adr;
6961        } catch (RemoteException e) {
6962            app.resetPackageList(mProcessStats);
6963            startProcessLocked(app, "link fail", processName);
6964            return false;
6965        }
6966
6967        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6968
6969        app.makeActive(thread, mProcessStats);
6970        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6971        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6972        app.forcingToImportant = null;
6973        updateProcessForegroundLocked(app, false, false);
6974        app.hasShownUi = false;
6975        app.debugging = false;
6976        app.cached = false;
6977        app.killedByAm = false;
6978        app.killed = false;
6979
6980
6981        // We carefully use the same state that PackageManager uses for
6982        // filtering, since we use this flag to decide if we need to install
6983        // providers when user is unlocked later
6984        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6985
6986        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6987
6988        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6989        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6990
6991        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6992            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6993            msg.obj = app;
6994            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6995        }
6996
6997        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6998
6999        if (!normalMode) {
7000            Slog.i(TAG, "Launching preboot mode app: " + app);
7001        }
7002
7003        if (DEBUG_ALL) Slog.v(
7004            TAG, "New app record " + app
7005            + " thread=" + thread.asBinder() + " pid=" + pid);
7006        try {
7007            int testMode = ApplicationThreadConstants.DEBUG_OFF;
7008            if (mDebugApp != null && mDebugApp.equals(processName)) {
7009                testMode = mWaitForDebugger
7010                    ? ApplicationThreadConstants.DEBUG_WAIT
7011                    : ApplicationThreadConstants.DEBUG_ON;
7012                app.debugging = true;
7013                if (mDebugTransient) {
7014                    mDebugApp = mOrigDebugApp;
7015                    mWaitForDebugger = mOrigWaitForDebugger;
7016                }
7017            }
7018
7019            ProfilerInfo profilerInfo = null;
7020            String agent = null;
7021            if (mProfileApp != null && mProfileApp.equals(processName)) {
7022                mProfileProc = app;
7023                profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ?
7024                        new ProfilerInfo(mProfilerInfo) : null;
7025                agent = mProfilerInfo != null ? mProfilerInfo.agent : null;
7026            } else if (app.instr != null && app.instr.mProfileFile != null) {
7027                profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7028                        null);
7029            }
7030
7031            boolean enableTrackAllocation = false;
7032            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7033                enableTrackAllocation = true;
7034                mTrackAllocationApp = null;
7035            }
7036
7037            // If the app is being launched for restore or full backup, set it up specially
7038            boolean isRestrictedBackupMode = false;
7039            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7040                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7041                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7042                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7043                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7044            }
7045
7046            if (app.instr != null) {
7047                notifyPackageUse(app.instr.mClass.getPackageName(),
7048                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7049            }
7050            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7051                    + processName + " with config " + getGlobalConfiguration());
7052            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7053            app.compat = compatibilityInfoForPackageLocked(appInfo);
7054
7055            if (profilerInfo != null && profilerInfo.profileFd != null) {
7056                profilerInfo.profileFd = profilerInfo.profileFd.dup();
7057            }
7058
7059            // We deprecated Build.SERIAL and it is not accessible to
7060            // apps that target the v2 security sandbox. Since access to
7061            // the serial is now behind a permission we push down the value.
7062            String buildSerial = appInfo.targetSandboxVersion < 2
7063                    ? sTheRealBuildSerial : Build.UNKNOWN;
7064
7065            // Check if this is a secondary process that should be incorporated into some
7066            // currently active instrumentation.  (Note we do this AFTER all of the profiling
7067            // stuff above because profiling can currently happen only in the primary
7068            // instrumentation process.)
7069            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7070                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7071                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7072                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7073                        if (aInstr.mTargetProcesses.length == 0) {
7074                            // This is the wildcard mode, where every process brought up for
7075                            // the target instrumentation should be included.
7076                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7077                                app.instr = aInstr;
7078                                aInstr.mRunningProcesses.add(app);
7079                            }
7080                        } else {
7081                            for (String proc : aInstr.mTargetProcesses) {
7082                                if (proc.equals(app.processName)) {
7083                                    app.instr = aInstr;
7084                                    aInstr.mRunningProcesses.add(app);
7085                                    break;
7086                                }
7087                            }
7088                        }
7089                    }
7090                }
7091            }
7092
7093            // If we were asked to attach an agent on startup, do so now, before we're binding
7094            // application code.
7095            if (agent != null) {
7096                thread.attachAgent(agent);
7097            }
7098
7099            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7100            mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7101            if (app.instr != null) {
7102                thread.bindApplication(processName, appInfo, providers,
7103                        app.instr.mClass,
7104                        profilerInfo, app.instr.mArguments,
7105                        app.instr.mWatcher,
7106                        app.instr.mUiAutomationConnection, testMode,
7107                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7108                        isRestrictedBackupMode || !normalMode, app.persistent,
7109                        new Configuration(getGlobalConfiguration()), app.compat,
7110                        getCommonServicesLocked(app.isolated),
7111                        mCoreSettingsObserver.getCoreSettingsLocked(),
7112                        buildSerial);
7113            } else {
7114                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7115                        null, null, null, testMode,
7116                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7117                        isRestrictedBackupMode || !normalMode, app.persistent,
7118                        new Configuration(getGlobalConfiguration()), app.compat,
7119                        getCommonServicesLocked(app.isolated),
7120                        mCoreSettingsObserver.getCoreSettingsLocked(),
7121                        buildSerial);
7122            }
7123
7124            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7125            updateLruProcessLocked(app, false, null);
7126            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7127            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7128        } catch (Exception e) {
7129            // todo: Yikes!  What should we do?  For now we will try to
7130            // start another process, but that could easily get us in
7131            // an infinite loop of restarting processes...
7132            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7133
7134            app.resetPackageList(mProcessStats);
7135            app.unlinkDeathRecipient();
7136            startProcessLocked(app, "bind fail", processName);
7137            return false;
7138        }
7139
7140        // Remove this record from the list of starting applications.
7141        mPersistentStartingProcesses.remove(app);
7142        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7143                "Attach application locked removing on hold: " + app);
7144        mProcessesOnHold.remove(app);
7145
7146        boolean badApp = false;
7147        boolean didSomething = false;
7148
7149        // See if the top visible activity is waiting to run in this process...
7150        if (normalMode) {
7151            try {
7152                if (mStackSupervisor.attachApplicationLocked(app)) {
7153                    didSomething = true;
7154                }
7155            } catch (Exception e) {
7156                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7157                badApp = true;
7158            }
7159        }
7160
7161        // Find any services that should be running in this process...
7162        if (!badApp) {
7163            try {
7164                didSomething |= mServices.attachApplicationLocked(app, processName);
7165                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7166            } catch (Exception e) {
7167                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7168                badApp = true;
7169            }
7170        }
7171
7172        // Check if a next-broadcast receiver is in this process...
7173        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7174            try {
7175                didSomething |= sendPendingBroadcastsLocked(app);
7176                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7177            } catch (Exception e) {
7178                // If the app died trying to launch the receiver we declare it 'bad'
7179                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7180                badApp = true;
7181            }
7182        }
7183
7184        // Check whether the next backup agent is in this process...
7185        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7186            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7187                    "New app is backup target, launching agent for " + app);
7188            notifyPackageUse(mBackupTarget.appInfo.packageName,
7189                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7190            try {
7191                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7192                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7193                        mBackupTarget.backupMode);
7194            } catch (Exception e) {
7195                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7196                badApp = true;
7197            }
7198        }
7199
7200        if (badApp) {
7201            app.kill("error during init", true);
7202            handleAppDiedLocked(app, false, true);
7203            return false;
7204        }
7205
7206        if (!didSomething) {
7207            updateOomAdjLocked();
7208            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7209        }
7210
7211        return true;
7212    }
7213
7214    @Override
7215    public final void attachApplication(IApplicationThread thread) {
7216        synchronized (this) {
7217            int callingPid = Binder.getCallingPid();
7218            final long origId = Binder.clearCallingIdentity();
7219            attachApplicationLocked(thread, callingPid);
7220            Binder.restoreCallingIdentity(origId);
7221        }
7222    }
7223
7224    @Override
7225    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7226        final long origId = Binder.clearCallingIdentity();
7227        synchronized (this) {
7228            ActivityStack stack = ActivityRecord.getStackLocked(token);
7229            if (stack != null) {
7230                ActivityRecord r =
7231                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7232                                false /* processPausingActivities */, config);
7233                if (stopProfiling) {
7234                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
7235                        clearProfilerLocked();
7236                    }
7237                }
7238            }
7239        }
7240        Binder.restoreCallingIdentity(origId);
7241    }
7242
7243    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7244        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7245                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7246    }
7247
7248    void enableScreenAfterBoot() {
7249        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7250                SystemClock.uptimeMillis());
7251        mWindowManager.enableScreenAfterBoot();
7252
7253        synchronized (this) {
7254            updateEventDispatchingLocked();
7255        }
7256    }
7257
7258    @Override
7259    public void showBootMessage(final CharSequence msg, final boolean always) {
7260        if (Binder.getCallingUid() != myUid()) {
7261            throw new SecurityException();
7262        }
7263        mWindowManager.showBootMessage(msg, always);
7264    }
7265
7266    @Override
7267    public void keyguardGoingAway(int flags) {
7268        enforceNotIsolatedCaller("keyguardGoingAway");
7269        final long token = Binder.clearCallingIdentity();
7270        try {
7271            synchronized (this) {
7272                mKeyguardController.keyguardGoingAway(flags);
7273            }
7274        } finally {
7275            Binder.restoreCallingIdentity(token);
7276        }
7277    }
7278
7279    /**
7280     * @return whther the keyguard is currently locked.
7281     */
7282    boolean isKeyguardLocked() {
7283        return mKeyguardController.isKeyguardLocked();
7284    }
7285
7286    final void finishBooting() {
7287        synchronized (this) {
7288            if (!mBootAnimationComplete) {
7289                mCallFinishBooting = true;
7290                return;
7291            }
7292            mCallFinishBooting = false;
7293        }
7294
7295        ArraySet<String> completedIsas = new ArraySet<String>();
7296        for (String abi : Build.SUPPORTED_ABIS) {
7297            zygoteProcess.establishZygoteConnectionForAbi(abi);
7298            final String instructionSet = VMRuntime.getInstructionSet(abi);
7299            if (!completedIsas.contains(instructionSet)) {
7300                try {
7301                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7302                } catch (InstallerException e) {
7303                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7304                            e.getMessage() +")");
7305                }
7306                completedIsas.add(instructionSet);
7307            }
7308        }
7309
7310        IntentFilter pkgFilter = new IntentFilter();
7311        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7312        pkgFilter.addDataScheme("package");
7313        mContext.registerReceiver(new BroadcastReceiver() {
7314            @Override
7315            public void onReceive(Context context, Intent intent) {
7316                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7317                if (pkgs != null) {
7318                    for (String pkg : pkgs) {
7319                        synchronized (ActivityManagerService.this) {
7320                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7321                                    0, "query restart")) {
7322                                setResultCode(Activity.RESULT_OK);
7323                                return;
7324                            }
7325                        }
7326                    }
7327                }
7328            }
7329        }, pkgFilter);
7330
7331        IntentFilter dumpheapFilter = new IntentFilter();
7332        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7333        mContext.registerReceiver(new BroadcastReceiver() {
7334            @Override
7335            public void onReceive(Context context, Intent intent) {
7336                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7337                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7338                } else {
7339                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7340                }
7341            }
7342        }, dumpheapFilter);
7343
7344        // Let system services know.
7345        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7346
7347        synchronized (this) {
7348            // Ensure that any processes we had put on hold are now started
7349            // up.
7350            final int NP = mProcessesOnHold.size();
7351            if (NP > 0) {
7352                ArrayList<ProcessRecord> procs =
7353                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7354                for (int ip=0; ip<NP; ip++) {
7355                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7356                            + procs.get(ip));
7357                    startProcessLocked(procs.get(ip), "on-hold", null);
7358                }
7359            }
7360
7361            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7362                // Start looking for apps that are abusing wake locks.
7363                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7364                mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7365                // Tell anyone interested that we are done booting!
7366                SystemProperties.set("sys.boot_completed", "1");
7367
7368                // And trigger dev.bootcomplete if we are not showing encryption progress
7369                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7370                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7371                    SystemProperties.set("dev.bootcomplete", "1");
7372                }
7373                mUserController.sendBootCompletedLocked(
7374                        new IIntentReceiver.Stub() {
7375                            @Override
7376                            public void performReceive(Intent intent, int resultCode,
7377                                    String data, Bundle extras, boolean ordered,
7378                                    boolean sticky, int sendingUser) {
7379                                synchronized (ActivityManagerService.this) {
7380                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7381                                            true, false);
7382                                }
7383                            }
7384                        });
7385                scheduleStartProfilesLocked();
7386            }
7387        }
7388    }
7389
7390    @Override
7391    public void bootAnimationComplete() {
7392        final boolean callFinishBooting;
7393        synchronized (this) {
7394            callFinishBooting = mCallFinishBooting;
7395            mBootAnimationComplete = true;
7396        }
7397        if (callFinishBooting) {
7398            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7399            finishBooting();
7400            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7401        }
7402    }
7403
7404    final void ensureBootCompleted() {
7405        boolean booting;
7406        boolean enableScreen;
7407        synchronized (this) {
7408            booting = mBooting;
7409            mBooting = false;
7410            enableScreen = !mBooted;
7411            mBooted = true;
7412        }
7413
7414        if (booting) {
7415            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7416            finishBooting();
7417            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7418        }
7419
7420        if (enableScreen) {
7421            enableScreenAfterBoot();
7422        }
7423    }
7424
7425    @Override
7426    public final void activityResumed(IBinder token) {
7427        final long origId = Binder.clearCallingIdentity();
7428        synchronized(this) {
7429            ActivityRecord.activityResumedLocked(token);
7430            mWindowManager.notifyAppResumedFinished(token);
7431        }
7432        Binder.restoreCallingIdentity(origId);
7433    }
7434
7435    @Override
7436    public final void activityPaused(IBinder token) {
7437        final long origId = Binder.clearCallingIdentity();
7438        synchronized(this) {
7439            ActivityStack stack = ActivityRecord.getStackLocked(token);
7440            if (stack != null) {
7441                stack.activityPausedLocked(token, false);
7442            }
7443        }
7444        Binder.restoreCallingIdentity(origId);
7445    }
7446
7447    @Override
7448    public final void activityStopped(IBinder token, Bundle icicle,
7449            PersistableBundle persistentState, CharSequence description) {
7450        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7451
7452        // Refuse possible leaked file descriptors
7453        if (icicle != null && icicle.hasFileDescriptors()) {
7454            throw new IllegalArgumentException("File descriptors passed in Bundle");
7455        }
7456
7457        final long origId = Binder.clearCallingIdentity();
7458
7459        synchronized (this) {
7460            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7461            if (r != null) {
7462                r.activityStoppedLocked(icicle, persistentState, description);
7463            }
7464        }
7465
7466        trimApplications();
7467
7468        Binder.restoreCallingIdentity(origId);
7469    }
7470
7471    @Override
7472    public final void activityDestroyed(IBinder token) {
7473        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7474        synchronized (this) {
7475            ActivityStack stack = ActivityRecord.getStackLocked(token);
7476            if (stack != null) {
7477                stack.activityDestroyedLocked(token, "activityDestroyed");
7478            }
7479        }
7480    }
7481
7482    @Override
7483    public final void activityRelaunched(IBinder token) {
7484        final long origId = Binder.clearCallingIdentity();
7485        synchronized (this) {
7486            mStackSupervisor.activityRelaunchedLocked(token);
7487        }
7488        Binder.restoreCallingIdentity(origId);
7489    }
7490
7491    @Override
7492    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7493            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7494        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7495                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7496        synchronized (this) {
7497            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7498            if (record == null) {
7499                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7500                        + "found for: " + token);
7501            }
7502            record.setSizeConfigurations(horizontalSizeConfiguration,
7503                    verticalSizeConfigurations, smallestSizeConfigurations);
7504        }
7505    }
7506
7507    @Override
7508    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7509        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7510    }
7511
7512    @Override
7513    public final void notifyEnterAnimationComplete(IBinder token) {
7514        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7515    }
7516
7517    @Override
7518    public String getCallingPackage(IBinder token) {
7519        synchronized (this) {
7520            ActivityRecord r = getCallingRecordLocked(token);
7521            return r != null ? r.info.packageName : null;
7522        }
7523    }
7524
7525    @Override
7526    public ComponentName getCallingActivity(IBinder token) {
7527        synchronized (this) {
7528            ActivityRecord r = getCallingRecordLocked(token);
7529            return r != null ? r.intent.getComponent() : null;
7530        }
7531    }
7532
7533    private ActivityRecord getCallingRecordLocked(IBinder token) {
7534        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7535        if (r == null) {
7536            return null;
7537        }
7538        return r.resultTo;
7539    }
7540
7541    @Override
7542    public ComponentName getActivityClassForToken(IBinder token) {
7543        synchronized(this) {
7544            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7545            if (r == null) {
7546                return null;
7547            }
7548            return r.intent.getComponent();
7549        }
7550    }
7551
7552    @Override
7553    public String getPackageForToken(IBinder token) {
7554        synchronized(this) {
7555            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7556            if (r == null) {
7557                return null;
7558            }
7559            return r.packageName;
7560        }
7561    }
7562
7563    @Override
7564    public boolean isRootVoiceInteraction(IBinder token) {
7565        synchronized(this) {
7566            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7567            if (r == null) {
7568                return false;
7569            }
7570            return r.rootVoiceInteraction;
7571        }
7572    }
7573
7574    @Override
7575    public IIntentSender getIntentSender(int type,
7576            String packageName, IBinder token, String resultWho,
7577            int requestCode, Intent[] intents, String[] resolvedTypes,
7578            int flags, Bundle bOptions, int userId) {
7579        enforceNotIsolatedCaller("getIntentSender");
7580        // Refuse possible leaked file descriptors
7581        if (intents != null) {
7582            if (intents.length < 1) {
7583                throw new IllegalArgumentException("Intents array length must be >= 1");
7584            }
7585            for (int i=0; i<intents.length; i++) {
7586                Intent intent = intents[i];
7587                if (intent != null) {
7588                    if (intent.hasFileDescriptors()) {
7589                        throw new IllegalArgumentException("File descriptors passed in Intent");
7590                    }
7591                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7592                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7593                        throw new IllegalArgumentException(
7594                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7595                    }
7596                    intents[i] = new Intent(intent);
7597                }
7598            }
7599            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7600                throw new IllegalArgumentException(
7601                        "Intent array length does not match resolvedTypes length");
7602            }
7603        }
7604        if (bOptions != null) {
7605            if (bOptions.hasFileDescriptors()) {
7606                throw new IllegalArgumentException("File descriptors passed in options");
7607            }
7608        }
7609
7610        synchronized(this) {
7611            int callingUid = Binder.getCallingUid();
7612            int origUserId = userId;
7613            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7614                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7615                    ALLOW_NON_FULL, "getIntentSender", null);
7616            if (origUserId == UserHandle.USER_CURRENT) {
7617                // We don't want to evaluate this until the pending intent is
7618                // actually executed.  However, we do want to always do the
7619                // security checking for it above.
7620                userId = UserHandle.USER_CURRENT;
7621            }
7622            try {
7623                if (callingUid != 0 && callingUid != SYSTEM_UID) {
7624                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7625                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7626                    if (!UserHandle.isSameApp(callingUid, uid)) {
7627                        String msg = "Permission Denial: getIntentSender() from pid="
7628                            + Binder.getCallingPid()
7629                            + ", uid=" + Binder.getCallingUid()
7630                            + ", (need uid=" + uid + ")"
7631                            + " is not allowed to send as package " + packageName;
7632                        Slog.w(TAG, msg);
7633                        throw new SecurityException(msg);
7634                    }
7635                }
7636
7637                return getIntentSenderLocked(type, packageName, callingUid, userId,
7638                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7639
7640            } catch (RemoteException e) {
7641                throw new SecurityException(e);
7642            }
7643        }
7644    }
7645
7646    IIntentSender getIntentSenderLocked(int type, String packageName,
7647            int callingUid, int userId, IBinder token, String resultWho,
7648            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7649            Bundle bOptions) {
7650        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7651        ActivityRecord activity = null;
7652        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7653            activity = ActivityRecord.isInStackLocked(token);
7654            if (activity == null) {
7655                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7656                return null;
7657            }
7658            if (activity.finishing) {
7659                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7660                return null;
7661            }
7662        }
7663
7664        // We're going to be splicing together extras before sending, so we're
7665        // okay poking into any contained extras.
7666        if (intents != null) {
7667            for (int i = 0; i < intents.length; i++) {
7668                intents[i].setDefusable(true);
7669            }
7670        }
7671        Bundle.setDefusable(bOptions, true);
7672
7673        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7674        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7675        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7676        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7677                |PendingIntent.FLAG_UPDATE_CURRENT);
7678
7679        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7680                type, packageName, activity, resultWho,
7681                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7682        WeakReference<PendingIntentRecord> ref;
7683        ref = mIntentSenderRecords.get(key);
7684        PendingIntentRecord rec = ref != null ? ref.get() : null;
7685        if (rec != null) {
7686            if (!cancelCurrent) {
7687                if (updateCurrent) {
7688                    if (rec.key.requestIntent != null) {
7689                        rec.key.requestIntent.replaceExtras(intents != null ?
7690                                intents[intents.length - 1] : null);
7691                    }
7692                    if (intents != null) {
7693                        intents[intents.length-1] = rec.key.requestIntent;
7694                        rec.key.allIntents = intents;
7695                        rec.key.allResolvedTypes = resolvedTypes;
7696                    } else {
7697                        rec.key.allIntents = null;
7698                        rec.key.allResolvedTypes = null;
7699                    }
7700                }
7701                return rec;
7702            }
7703            makeIntentSenderCanceledLocked(rec);
7704            mIntentSenderRecords.remove(key);
7705        }
7706        if (noCreate) {
7707            return rec;
7708        }
7709        rec = new PendingIntentRecord(this, key, callingUid);
7710        mIntentSenderRecords.put(key, rec.ref);
7711        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7712            if (activity.pendingResults == null) {
7713                activity.pendingResults
7714                        = new HashSet<WeakReference<PendingIntentRecord>>();
7715            }
7716            activity.pendingResults.add(rec.ref);
7717        }
7718        return rec;
7719    }
7720
7721    @Override
7722    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7723            Intent intent, String resolvedType,
7724            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7725        if (target instanceof PendingIntentRecord) {
7726            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7727                    whitelistToken, finishedReceiver, requiredPermission, options);
7728        } else {
7729            if (intent == null) {
7730                // Weird case: someone has given us their own custom IIntentSender, and now
7731                // they have someone else trying to send to it but of course this isn't
7732                // really a PendingIntent, so there is no base Intent, and the caller isn't
7733                // supplying an Intent... but we never want to dispatch a null Intent to
7734                // a receiver, so um...  let's make something up.
7735                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7736                intent = new Intent(Intent.ACTION_MAIN);
7737            }
7738            try {
7739                target.send(code, intent, resolvedType, whitelistToken, null,
7740                        requiredPermission, options);
7741            } catch (RemoteException e) {
7742            }
7743            // Platform code can rely on getting a result back when the send is done, but if
7744            // this intent sender is from outside of the system we can't rely on it doing that.
7745            // So instead we don't give it the result receiver, and instead just directly
7746            // report the finish immediately.
7747            if (finishedReceiver != null) {
7748                try {
7749                    finishedReceiver.performReceive(intent, 0,
7750                            null, null, false, false, UserHandle.getCallingUserId());
7751                } catch (RemoteException e) {
7752                }
7753            }
7754            return 0;
7755        }
7756    }
7757
7758    @Override
7759    public void cancelIntentSender(IIntentSender sender) {
7760        if (!(sender instanceof PendingIntentRecord)) {
7761            return;
7762        }
7763        synchronized(this) {
7764            PendingIntentRecord rec = (PendingIntentRecord)sender;
7765            try {
7766                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7767                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7768                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7769                    String msg = "Permission Denial: cancelIntentSender() from pid="
7770                        + Binder.getCallingPid()
7771                        + ", uid=" + Binder.getCallingUid()
7772                        + " is not allowed to cancel package "
7773                        + rec.key.packageName;
7774                    Slog.w(TAG, msg);
7775                    throw new SecurityException(msg);
7776                }
7777            } catch (RemoteException e) {
7778                throw new SecurityException(e);
7779            }
7780            cancelIntentSenderLocked(rec, true);
7781        }
7782    }
7783
7784    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7785        makeIntentSenderCanceledLocked(rec);
7786        mIntentSenderRecords.remove(rec.key);
7787        if (cleanActivity && rec.key.activity != null) {
7788            rec.key.activity.pendingResults.remove(rec.ref);
7789        }
7790    }
7791
7792    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7793        rec.canceled = true;
7794        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7795        if (callbacks != null) {
7796            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7797        }
7798    }
7799
7800    @Override
7801    public String getPackageForIntentSender(IIntentSender pendingResult) {
7802        if (!(pendingResult instanceof PendingIntentRecord)) {
7803            return null;
7804        }
7805        try {
7806            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7807            return res.key.packageName;
7808        } catch (ClassCastException e) {
7809        }
7810        return null;
7811    }
7812
7813    @Override
7814    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7815        if (!(sender instanceof PendingIntentRecord)) {
7816            return;
7817        }
7818        synchronized(this) {
7819            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7820        }
7821    }
7822
7823    @Override
7824    public void unregisterIntentSenderCancelListener(IIntentSender sender,
7825            IResultReceiver receiver) {
7826        if (!(sender instanceof PendingIntentRecord)) {
7827            return;
7828        }
7829        synchronized(this) {
7830            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7831        }
7832    }
7833
7834    @Override
7835    public int getUidForIntentSender(IIntentSender sender) {
7836        if (sender instanceof PendingIntentRecord) {
7837            try {
7838                PendingIntentRecord res = (PendingIntentRecord)sender;
7839                return res.uid;
7840            } catch (ClassCastException e) {
7841            }
7842        }
7843        return -1;
7844    }
7845
7846    @Override
7847    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7848        if (!(pendingResult instanceof PendingIntentRecord)) {
7849            return false;
7850        }
7851        try {
7852            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7853            if (res.key.allIntents == null) {
7854                return false;
7855            }
7856            for (int i=0; i<res.key.allIntents.length; i++) {
7857                Intent intent = res.key.allIntents[i];
7858                if (intent.getPackage() != null && intent.getComponent() != null) {
7859                    return false;
7860                }
7861            }
7862            return true;
7863        } catch (ClassCastException e) {
7864        }
7865        return false;
7866    }
7867
7868    @Override
7869    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7870        if (!(pendingResult instanceof PendingIntentRecord)) {
7871            return false;
7872        }
7873        try {
7874            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7875            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7876                return true;
7877            }
7878            return false;
7879        } catch (ClassCastException e) {
7880        }
7881        return false;
7882    }
7883
7884    @Override
7885    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7886        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7887                "getIntentForIntentSender()");
7888        if (!(pendingResult instanceof PendingIntentRecord)) {
7889            return null;
7890        }
7891        try {
7892            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7893            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7894        } catch (ClassCastException e) {
7895        }
7896        return null;
7897    }
7898
7899    @Override
7900    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7901        if (!(pendingResult instanceof PendingIntentRecord)) {
7902            return null;
7903        }
7904        try {
7905            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7906            synchronized (this) {
7907                return getTagForIntentSenderLocked(res, prefix);
7908            }
7909        } catch (ClassCastException e) {
7910        }
7911        return null;
7912    }
7913
7914    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7915        final Intent intent = res.key.requestIntent;
7916        if (intent != null) {
7917            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7918                    || res.lastTagPrefix.equals(prefix))) {
7919                return res.lastTag;
7920            }
7921            res.lastTagPrefix = prefix;
7922            final StringBuilder sb = new StringBuilder(128);
7923            if (prefix != null) {
7924                sb.append(prefix);
7925            }
7926            if (intent.getAction() != null) {
7927                sb.append(intent.getAction());
7928            } else if (intent.getComponent() != null) {
7929                intent.getComponent().appendShortString(sb);
7930            } else {
7931                sb.append("?");
7932            }
7933            return res.lastTag = sb.toString();
7934        }
7935        return null;
7936    }
7937
7938    @Override
7939    public void setProcessLimit(int max) {
7940        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7941                "setProcessLimit()");
7942        synchronized (this) {
7943            mConstants.setOverrideMaxCachedProcesses(max);
7944        }
7945        trimApplications();
7946    }
7947
7948    @Override
7949    public int getProcessLimit() {
7950        synchronized (this) {
7951            return mConstants.getOverrideMaxCachedProcesses();
7952        }
7953    }
7954
7955    void importanceTokenDied(ImportanceToken token) {
7956        synchronized (ActivityManagerService.this) {
7957            synchronized (mPidsSelfLocked) {
7958                ImportanceToken cur
7959                    = mImportantProcesses.get(token.pid);
7960                if (cur != token) {
7961                    return;
7962                }
7963                mImportantProcesses.remove(token.pid);
7964                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7965                if (pr == null) {
7966                    return;
7967                }
7968                pr.forcingToImportant = null;
7969                updateProcessForegroundLocked(pr, false, false);
7970            }
7971            updateOomAdjLocked();
7972        }
7973    }
7974
7975    @Override
7976    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7977        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7978                "setProcessImportant()");
7979        synchronized(this) {
7980            boolean changed = false;
7981
7982            synchronized (mPidsSelfLocked) {
7983                ProcessRecord pr = mPidsSelfLocked.get(pid);
7984                if (pr == null && isForeground) {
7985                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7986                    return;
7987                }
7988                ImportanceToken oldToken = mImportantProcesses.get(pid);
7989                if (oldToken != null) {
7990                    oldToken.token.unlinkToDeath(oldToken, 0);
7991                    mImportantProcesses.remove(pid);
7992                    if (pr != null) {
7993                        pr.forcingToImportant = null;
7994                    }
7995                    changed = true;
7996                }
7997                if (isForeground && token != null) {
7998                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7999                        @Override
8000                        public void binderDied() {
8001                            importanceTokenDied(this);
8002                        }
8003                    };
8004                    try {
8005                        token.linkToDeath(newToken, 0);
8006                        mImportantProcesses.put(pid, newToken);
8007                        pr.forcingToImportant = newToken;
8008                        changed = true;
8009                    } catch (RemoteException e) {
8010                        // If the process died while doing this, we will later
8011                        // do the cleanup with the process death link.
8012                    }
8013                }
8014            }
8015
8016            if (changed) {
8017                updateOomAdjLocked();
8018            }
8019        }
8020    }
8021
8022    @Override
8023    public boolean isAppForeground(int uid) throws RemoteException {
8024        synchronized (this) {
8025            UidRecord uidRec = mActiveUids.get(uid);
8026            if (uidRec == null || uidRec.idle) {
8027                return false;
8028            }
8029            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8030        }
8031    }
8032
8033    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8034    // be guarded by permission checking.
8035    int getUidState(int uid) {
8036        synchronized (this) {
8037            return getUidStateLocked(uid);
8038        }
8039    }
8040
8041    int getUidStateLocked(int uid) {
8042        UidRecord uidRec = mActiveUids.get(uid);
8043        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8044    }
8045
8046    @Override
8047    public boolean isInMultiWindowMode(IBinder token) {
8048        final long origId = Binder.clearCallingIdentity();
8049        try {
8050            synchronized(this) {
8051                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8052                if (r == null) {
8053                    return false;
8054                }
8055                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8056                return !r.getTask().mFullscreen;
8057            }
8058        } finally {
8059            Binder.restoreCallingIdentity(origId);
8060        }
8061    }
8062
8063    @Override
8064    public boolean isInPictureInPictureMode(IBinder token) {
8065        final long origId = Binder.clearCallingIdentity();
8066        try {
8067            synchronized(this) {
8068                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8069            }
8070        } finally {
8071            Binder.restoreCallingIdentity(origId);
8072        }
8073    }
8074
8075    private boolean isInPictureInPictureMode(ActivityRecord r) {
8076        if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8077                r.getStack().isInStackLocked(r) == null) {
8078            return false;
8079        }
8080
8081        // If we are animating to fullscreen then we have already dispatched the PIP mode
8082        // changed, so we should reflect that check here as well.
8083        final PinnedActivityStack stack = r.getStack();
8084        final PinnedStackWindowController windowController = stack.getWindowContainerController();
8085        return !windowController.isAnimatingBoundsToFullscreen();
8086    }
8087
8088    @Override
8089    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8090        final long origId = Binder.clearCallingIdentity();
8091        try {
8092            synchronized(this) {
8093                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8094                        "enterPictureInPictureMode", token, params);
8095
8096                // If the activity is already in picture in picture mode, then just return early
8097                if (isInPictureInPictureMode(r)) {
8098                    return true;
8099                }
8100
8101                // Activity supports picture-in-picture, now check that we can enter PiP at this
8102                // point, if it is
8103                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8104                        false /* beforeStopping */)) {
8105                    return false;
8106                }
8107
8108                final Runnable enterPipRunnable = () -> {
8109                    // Only update the saved args from the args that are set
8110                    r.pictureInPictureArgs.copyOnlySet(params);
8111                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8112                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8113                    // Adjust the source bounds by the insets for the transition down
8114                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8115                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8116                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8117                    final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8118                    stack.setPictureInPictureAspectRatio(aspectRatio);
8119                    stack.setPictureInPictureActions(actions);
8120
8121                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8122                            r.supportsEnterPipOnTaskSwitch);
8123                    logPictureInPictureArgs(params);
8124                };
8125
8126                if (isKeyguardLocked()) {
8127                    // If the keyguard is showing or occluded, then try and dismiss it before
8128                    // entering picture-in-picture (this will prompt the user to authenticate if the
8129                    // device is currently locked).
8130                    try {
8131                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8132                            @Override
8133                            public void onDismissError() throws RemoteException {
8134                                // Do nothing
8135                            }
8136
8137                            @Override
8138                            public void onDismissSucceeded() throws RemoteException {
8139                                mHandler.post(enterPipRunnable);
8140                            }
8141
8142                            @Override
8143                            public void onDismissCancelled() throws RemoteException {
8144                                // Do nothing
8145                            }
8146                        });
8147                    } catch (RemoteException e) {
8148                        // Local call
8149                    }
8150                } else {
8151                    // Enter picture in picture immediately otherwise
8152                    enterPipRunnable.run();
8153                }
8154                return true;
8155            }
8156        } finally {
8157            Binder.restoreCallingIdentity(origId);
8158        }
8159    }
8160
8161    @Override
8162    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8163        final long origId = Binder.clearCallingIdentity();
8164        try {
8165            synchronized(this) {
8166                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8167                        "setPictureInPictureParams", token, params);
8168
8169                // Only update the saved args from the args that are set
8170                r.pictureInPictureArgs.copyOnlySet(params);
8171                if (r.getStack().getStackId() == PINNED_STACK_ID) {
8172                    // If the activity is already in picture-in-picture, update the pinned stack now
8173                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8174                    // be used the next time the activity enters PiP
8175                    final PinnedActivityStack stack = r.getStack();
8176                    if (!stack.isAnimatingBoundsToFullscreen()) {
8177                        stack.setPictureInPictureAspectRatio(
8178                                r.pictureInPictureArgs.getAspectRatio());
8179                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8180                    }
8181                }
8182                logPictureInPictureArgs(params);
8183            }
8184        } finally {
8185            Binder.restoreCallingIdentity(origId);
8186        }
8187    }
8188
8189    @Override
8190    public int getMaxNumPictureInPictureActions(IBinder token) {
8191        // Currently, this is a static constant, but later, we may change this to be dependent on
8192        // the context of the activity
8193        return 3;
8194    }
8195
8196    private void logPictureInPictureArgs(PictureInPictureParams params) {
8197        if (params.hasSetActions()) {
8198            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8199                    params.getActions().size());
8200        }
8201        if (params.hasSetAspectRatio()) {
8202            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8203            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8204            MetricsLogger.action(lm);
8205        }
8206    }
8207
8208    /**
8209     * Checks the state of the system and the activity associated with the given {@param token} to
8210     * verify that picture-in-picture is supported for that activity.
8211     *
8212     * @return the activity record for the given {@param token} if all the checks pass.
8213     */
8214    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8215            IBinder token, PictureInPictureParams params) {
8216        if (!mSupportsPictureInPicture) {
8217            throw new IllegalStateException(caller
8218                    + ": Device doesn't support picture-in-picture mode.");
8219        }
8220
8221        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8222        if (r == null) {
8223            throw new IllegalStateException(caller
8224                    + ": Can't find activity for token=" + token);
8225        }
8226
8227        if (!r.supportsPictureInPicture()) {
8228            throw new IllegalStateException(caller
8229                    + ": Current activity does not support picture-in-picture.");
8230        }
8231
8232        if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8233            throw new IllegalStateException(caller
8234                    + ": Activities on the home, assistant, or recents stack not supported");
8235        }
8236
8237        if (params.hasSetAspectRatio()
8238                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8239                        params.getAspectRatio())) {
8240            final float minAspectRatio = mContext.getResources().getFloat(
8241                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8242            final float maxAspectRatio = mContext.getResources().getFloat(
8243                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8244            throw new IllegalArgumentException(String.format(caller
8245                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8246                            minAspectRatio, maxAspectRatio));
8247        }
8248
8249        // Truncate the number of actions if necessary
8250        params.truncateActions(getMaxNumPictureInPictureActions(token));
8251
8252        return r;
8253    }
8254
8255    // =========================================================
8256    // PROCESS INFO
8257    // =========================================================
8258
8259    static class ProcessInfoService extends IProcessInfoService.Stub {
8260        final ActivityManagerService mActivityManagerService;
8261        ProcessInfoService(ActivityManagerService activityManagerService) {
8262            mActivityManagerService = activityManagerService;
8263        }
8264
8265        @Override
8266        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8267            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8268                    /*in*/ pids, /*out*/ states, null);
8269        }
8270
8271        @Override
8272        public void getProcessStatesAndOomScoresFromPids(
8273                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8274            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8275                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8276        }
8277    }
8278
8279    /**
8280     * For each PID in the given input array, write the current process state
8281     * for that process into the states array, or -1 to indicate that no
8282     * process with the given PID exists. If scores array is provided, write
8283     * the oom score for the process into the scores array, with INVALID_ADJ
8284     * indicating the PID doesn't exist.
8285     */
8286    public void getProcessStatesAndOomScoresForPIDs(
8287            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8288        if (scores != null) {
8289            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8290                    "getProcessStatesAndOomScoresForPIDs()");
8291        }
8292
8293        if (pids == null) {
8294            throw new NullPointerException("pids");
8295        } else if (states == null) {
8296            throw new NullPointerException("states");
8297        } else if (pids.length != states.length) {
8298            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8299        } else if (scores != null && pids.length != scores.length) {
8300            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8301        }
8302
8303        synchronized (mPidsSelfLocked) {
8304            for (int i = 0; i < pids.length; i++) {
8305                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8306                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8307                        pr.curProcState;
8308                if (scores != null) {
8309                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8310                }
8311            }
8312        }
8313    }
8314
8315    // =========================================================
8316    // PERMISSIONS
8317    // =========================================================
8318
8319    static class PermissionController extends IPermissionController.Stub {
8320        ActivityManagerService mActivityManagerService;
8321        PermissionController(ActivityManagerService activityManagerService) {
8322            mActivityManagerService = activityManagerService;
8323        }
8324
8325        @Override
8326        public boolean checkPermission(String permission, int pid, int uid) {
8327            return mActivityManagerService.checkPermission(permission, pid,
8328                    uid) == PackageManager.PERMISSION_GRANTED;
8329        }
8330
8331        @Override
8332        public String[] getPackagesForUid(int uid) {
8333            return mActivityManagerService.mContext.getPackageManager()
8334                    .getPackagesForUid(uid);
8335        }
8336
8337        @Override
8338        public boolean isRuntimePermission(String permission) {
8339            try {
8340                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8341                        .getPermissionInfo(permission, 0);
8342                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8343                        == PermissionInfo.PROTECTION_DANGEROUS;
8344            } catch (NameNotFoundException nnfe) {
8345                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8346            }
8347            return false;
8348        }
8349    }
8350
8351    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8352        @Override
8353        public int checkComponentPermission(String permission, int pid, int uid,
8354                int owningUid, boolean exported) {
8355            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8356                    owningUid, exported);
8357        }
8358
8359        @Override
8360        public Object getAMSLock() {
8361            return ActivityManagerService.this;
8362        }
8363    }
8364
8365    /**
8366     * This can be called with or without the global lock held.
8367     */
8368    int checkComponentPermission(String permission, int pid, int uid,
8369            int owningUid, boolean exported) {
8370        if (pid == MY_PID) {
8371            return PackageManager.PERMISSION_GRANTED;
8372        }
8373        return ActivityManager.checkComponentPermission(permission, uid,
8374                owningUid, exported);
8375    }
8376
8377    /**
8378     * As the only public entry point for permissions checking, this method
8379     * can enforce the semantic that requesting a check on a null global
8380     * permission is automatically denied.  (Internally a null permission
8381     * string is used when calling {@link #checkComponentPermission} in cases
8382     * when only uid-based security is needed.)
8383     *
8384     * This can be called with or without the global lock held.
8385     */
8386    @Override
8387    public int checkPermission(String permission, int pid, int uid) {
8388        if (permission == null) {
8389            return PackageManager.PERMISSION_DENIED;
8390        }
8391        return checkComponentPermission(permission, pid, uid, -1, true);
8392    }
8393
8394    @Override
8395    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8396        if (permission == null) {
8397            return PackageManager.PERMISSION_DENIED;
8398        }
8399
8400        // We might be performing an operation on behalf of an indirect binder
8401        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8402        // client identity accordingly before proceeding.
8403        Identity tlsIdentity = sCallerIdentity.get();
8404        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8405            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8406                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8407            uid = tlsIdentity.uid;
8408            pid = tlsIdentity.pid;
8409        }
8410
8411        return checkComponentPermission(permission, pid, uid, -1, true);
8412    }
8413
8414    /**
8415     * Binder IPC calls go through the public entry point.
8416     * This can be called with or without the global lock held.
8417     */
8418    int checkCallingPermission(String permission) {
8419        return checkPermission(permission,
8420                Binder.getCallingPid(),
8421                UserHandle.getAppId(Binder.getCallingUid()));
8422    }
8423
8424    /**
8425     * This can be called with or without the global lock held.
8426     */
8427    void enforceCallingPermission(String permission, String func) {
8428        if (checkCallingPermission(permission)
8429                == PackageManager.PERMISSION_GRANTED) {
8430            return;
8431        }
8432
8433        String msg = "Permission Denial: " + func + " from pid="
8434                + Binder.getCallingPid()
8435                + ", uid=" + Binder.getCallingUid()
8436                + " requires " + permission;
8437        Slog.w(TAG, msg);
8438        throw new SecurityException(msg);
8439    }
8440
8441    /**
8442     * Determine if UID is holding permissions required to access {@link Uri} in
8443     * the given {@link ProviderInfo}. Final permission checking is always done
8444     * in {@link ContentProvider}.
8445     */
8446    private final boolean checkHoldingPermissionsLocked(
8447            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8448        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8449                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8450        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8451            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8452                    != PERMISSION_GRANTED) {
8453                return false;
8454            }
8455        }
8456        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8457    }
8458
8459    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8460            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8461        if (pi.applicationInfo.uid == uid) {
8462            return true;
8463        } else if (!pi.exported) {
8464            return false;
8465        }
8466
8467        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8468        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8469        try {
8470            // check if target holds top-level <provider> permissions
8471            if (!readMet && pi.readPermission != null && considerUidPermissions
8472                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8473                readMet = true;
8474            }
8475            if (!writeMet && pi.writePermission != null && considerUidPermissions
8476                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8477                writeMet = true;
8478            }
8479
8480            // track if unprotected read/write is allowed; any denied
8481            // <path-permission> below removes this ability
8482            boolean allowDefaultRead = pi.readPermission == null;
8483            boolean allowDefaultWrite = pi.writePermission == null;
8484
8485            // check if target holds any <path-permission> that match uri
8486            final PathPermission[] pps = pi.pathPermissions;
8487            if (pps != null) {
8488                final String path = grantUri.uri.getPath();
8489                int i = pps.length;
8490                while (i > 0 && (!readMet || !writeMet)) {
8491                    i--;
8492                    PathPermission pp = pps[i];
8493                    if (pp.match(path)) {
8494                        if (!readMet) {
8495                            final String pprperm = pp.getReadPermission();
8496                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8497                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8498                                    + ": match=" + pp.match(path)
8499                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8500                            if (pprperm != null) {
8501                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8502                                        == PERMISSION_GRANTED) {
8503                                    readMet = true;
8504                                } else {
8505                                    allowDefaultRead = false;
8506                                }
8507                            }
8508                        }
8509                        if (!writeMet) {
8510                            final String ppwperm = pp.getWritePermission();
8511                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8512                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8513                                    + ": match=" + pp.match(path)
8514                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8515                            if (ppwperm != null) {
8516                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8517                                        == PERMISSION_GRANTED) {
8518                                    writeMet = true;
8519                                } else {
8520                                    allowDefaultWrite = false;
8521                                }
8522                            }
8523                        }
8524                    }
8525                }
8526            }
8527
8528            // grant unprotected <provider> read/write, if not blocked by
8529            // <path-permission> above
8530            if (allowDefaultRead) readMet = true;
8531            if (allowDefaultWrite) writeMet = true;
8532
8533        } catch (RemoteException e) {
8534            return false;
8535        }
8536
8537        return readMet && writeMet;
8538    }
8539
8540    public boolean isAppStartModeDisabled(int uid, String packageName) {
8541        synchronized (this) {
8542            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8543                    == ActivityManager.APP_START_MODE_DISABLED;
8544        }
8545    }
8546
8547    // Unified app-op and target sdk check
8548    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8549        // Apps that target O+ are always subject to background check
8550        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8551            if (DEBUG_BACKGROUND_CHECK) {
8552                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8553            }
8554            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8555        }
8556        // ...and legacy apps get an AppOp check
8557        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8558                uid, packageName);
8559        if (DEBUG_BACKGROUND_CHECK) {
8560            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8561        }
8562        switch (appop) {
8563            case AppOpsManager.MODE_ALLOWED:
8564                return ActivityManager.APP_START_MODE_NORMAL;
8565            case AppOpsManager.MODE_IGNORED:
8566                return ActivityManager.APP_START_MODE_DELAYED;
8567            default:
8568                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8569        }
8570    }
8571
8572    // Service launch is available to apps with run-in-background exemptions but
8573    // some other background operations are not.  If we're doing a check
8574    // of service-launch policy, allow those callers to proceed unrestricted.
8575    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8576        // Persistent app?
8577        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8578            if (DEBUG_BACKGROUND_CHECK) {
8579                Slog.i(TAG, "App " + uid + "/" + packageName
8580                        + " is persistent; not restricted in background");
8581            }
8582            return ActivityManager.APP_START_MODE_NORMAL;
8583        }
8584
8585        // Non-persistent but background whitelisted?
8586        if (uidOnBackgroundWhitelist(uid)) {
8587            if (DEBUG_BACKGROUND_CHECK) {
8588                Slog.i(TAG, "App " + uid + "/" + packageName
8589                        + " on background whitelist; not restricted in background");
8590            }
8591            return ActivityManager.APP_START_MODE_NORMAL;
8592        }
8593
8594        // Is this app on the battery whitelist?
8595        if (isOnDeviceIdleWhitelistLocked(uid)) {
8596            if (DEBUG_BACKGROUND_CHECK) {
8597                Slog.i(TAG, "App " + uid + "/" + packageName
8598                        + " on idle whitelist; not restricted in background");
8599            }
8600            return ActivityManager.APP_START_MODE_NORMAL;
8601        }
8602
8603        // None of the service-policy criteria apply, so we apply the common criteria
8604        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8605    }
8606
8607    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8608            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8609        UidRecord uidRec = mActiveUids.get(uid);
8610        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8611                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8612                + (uidRec != null ? uidRec.idle : false));
8613        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8614            boolean ephemeral;
8615            if (uidRec == null) {
8616                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8617                        UserHandle.getUserId(uid), packageName);
8618            } else {
8619                ephemeral = uidRec.ephemeral;
8620            }
8621
8622            if (ephemeral) {
8623                // We are hard-core about ephemeral apps not running in the background.
8624                return ActivityManager.APP_START_MODE_DISABLED;
8625            } else {
8626                if (disabledOnly) {
8627                    // The caller is only interested in whether app starts are completely
8628                    // disabled for the given package (that is, it is an instant app).  So
8629                    // we don't need to go further, which is all just seeing if we should
8630                    // apply a "delayed" mode for a regular app.
8631                    return ActivityManager.APP_START_MODE_NORMAL;
8632                }
8633                final int startMode = (alwaysRestrict)
8634                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8635                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8636                                packageTargetSdk);
8637                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8638                        + " pkg=" + packageName + " startMode=" + startMode
8639                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8640                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8641                    // This is an old app that has been forced into a "compatible as possible"
8642                    // mode of background check.  To increase compatibility, we will allow other
8643                    // foreground apps to cause its services to start.
8644                    if (callingPid >= 0) {
8645                        ProcessRecord proc;
8646                        synchronized (mPidsSelfLocked) {
8647                            proc = mPidsSelfLocked.get(callingPid);
8648                        }
8649                        if (proc != null &&
8650                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
8651                            // Whoever is instigating this is in the foreground, so we will allow it
8652                            // to go through.
8653                            return ActivityManager.APP_START_MODE_NORMAL;
8654                        }
8655                    }
8656                }
8657                return startMode;
8658            }
8659        }
8660        return ActivityManager.APP_START_MODE_NORMAL;
8661    }
8662
8663    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8664        final int appId = UserHandle.getAppId(uid);
8665        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8666                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8667                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8668    }
8669
8670    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8671        ProviderInfo pi = null;
8672        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8673        if (cpr != null) {
8674            pi = cpr.info;
8675        } else {
8676            try {
8677                pi = AppGlobals.getPackageManager().resolveContentProvider(
8678                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8679                        userHandle);
8680            } catch (RemoteException ex) {
8681            }
8682        }
8683        return pi;
8684    }
8685
8686    void grantEphemeralAccessLocked(int userId, Intent intent,
8687            int targetAppId, int ephemeralAppId) {
8688        getPackageManagerInternalLocked().
8689                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8690    }
8691
8692    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8693        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8694        if (targetUris != null) {
8695            return targetUris.get(grantUri);
8696        }
8697        return null;
8698    }
8699
8700    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8701            String targetPkg, int targetUid, GrantUri grantUri) {
8702        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8703        if (targetUris == null) {
8704            targetUris = Maps.newArrayMap();
8705            mGrantedUriPermissions.put(targetUid, targetUris);
8706        }
8707
8708        UriPermission perm = targetUris.get(grantUri);
8709        if (perm == null) {
8710            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8711            targetUris.put(grantUri, perm);
8712        }
8713
8714        return perm;
8715    }
8716
8717    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8718            final int modeFlags) {
8719        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8720        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8721                : UriPermission.STRENGTH_OWNED;
8722
8723        // Root gets to do everything.
8724        if (uid == 0) {
8725            return true;
8726        }
8727
8728        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8729        if (perms == null) return false;
8730
8731        // First look for exact match
8732        final UriPermission exactPerm = perms.get(grantUri);
8733        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8734            return true;
8735        }
8736
8737        // No exact match, look for prefixes
8738        final int N = perms.size();
8739        for (int i = 0; i < N; i++) {
8740            final UriPermission perm = perms.valueAt(i);
8741            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8742                    && perm.getStrength(modeFlags) >= minStrength) {
8743                return true;
8744            }
8745        }
8746
8747        return false;
8748    }
8749
8750    /**
8751     * @param uri This uri must NOT contain an embedded userId.
8752     * @param userId The userId in which the uri is to be resolved.
8753     */
8754    @Override
8755    public int checkUriPermission(Uri uri, int pid, int uid,
8756            final int modeFlags, int userId, IBinder callerToken) {
8757        enforceNotIsolatedCaller("checkUriPermission");
8758
8759        // Another redirected-binder-call permissions check as in
8760        // {@link checkPermissionWithToken}.
8761        Identity tlsIdentity = sCallerIdentity.get();
8762        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8763            uid = tlsIdentity.uid;
8764            pid = tlsIdentity.pid;
8765        }
8766
8767        // Our own process gets to do everything.
8768        if (pid == MY_PID) {
8769            return PackageManager.PERMISSION_GRANTED;
8770        }
8771        synchronized (this) {
8772            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8773                    ? PackageManager.PERMISSION_GRANTED
8774                    : PackageManager.PERMISSION_DENIED;
8775        }
8776    }
8777
8778    /**
8779     * Check if the targetPkg can be granted permission to access uri by
8780     * the callingUid using the given modeFlags.  Throws a security exception
8781     * if callingUid is not allowed to do this.  Returns the uid of the target
8782     * if the URI permission grant should be performed; returns -1 if it is not
8783     * needed (for example targetPkg already has permission to access the URI).
8784     * If you already know the uid of the target, you can supply it in
8785     * lastTargetUid else set that to -1.
8786     */
8787    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8788            final int modeFlags, int lastTargetUid) {
8789        if (!Intent.isAccessUriMode(modeFlags)) {
8790            return -1;
8791        }
8792
8793        if (targetPkg != null) {
8794            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8795                    "Checking grant " + targetPkg + " permission to " + grantUri);
8796        }
8797
8798        final IPackageManager pm = AppGlobals.getPackageManager();
8799
8800        // If this is not a content: uri, we can't do anything with it.
8801        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8802            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8803                    "Can't grant URI permission for non-content URI: " + grantUri);
8804            return -1;
8805        }
8806
8807        // Bail early if system is trying to hand out permissions directly; it
8808        // must always grant permissions on behalf of someone explicit.
8809        final int callingAppId = UserHandle.getAppId(callingUid);
8810        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8811            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8812                // Exempted authority for cropping user photos in Settings app
8813            } else {
8814                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8815                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8816                return -1;
8817            }
8818        }
8819
8820        final String authority = grantUri.uri.getAuthority();
8821        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8822                MATCH_DEBUG_TRIAGED_MISSING);
8823        if (pi == null) {
8824            Slog.w(TAG, "No content provider found for permission check: " +
8825                    grantUri.uri.toSafeString());
8826            return -1;
8827        }
8828
8829        int targetUid = lastTargetUid;
8830        if (targetUid < 0 && targetPkg != null) {
8831            try {
8832                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8833                        UserHandle.getUserId(callingUid));
8834                if (targetUid < 0) {
8835                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8836                            "Can't grant URI permission no uid for: " + targetPkg);
8837                    return -1;
8838                }
8839            } catch (RemoteException ex) {
8840                return -1;
8841            }
8842        }
8843
8844        // If we're extending a persistable grant, then we always need to create
8845        // the grant data structure so that take/release APIs work
8846        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8847            return targetUid;
8848        }
8849
8850        if (targetUid >= 0) {
8851            // First...  does the target actually need this permission?
8852            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8853                // No need to grant the target this permission.
8854                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8855                        "Target " + targetPkg + " already has full permission to " + grantUri);
8856                return -1;
8857            }
8858        } else {
8859            // First...  there is no target package, so can anyone access it?
8860            boolean allowed = pi.exported;
8861            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8862                if (pi.readPermission != null) {
8863                    allowed = false;
8864                }
8865            }
8866            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8867                if (pi.writePermission != null) {
8868                    allowed = false;
8869                }
8870            }
8871            if (allowed) {
8872                return -1;
8873            }
8874        }
8875
8876        /* There is a special cross user grant if:
8877         * - The target is on another user.
8878         * - Apps on the current user can access the uri without any uid permissions.
8879         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8880         * grant uri permissions.
8881         */
8882        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8883                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8884                modeFlags, false /*without considering the uid permissions*/);
8885
8886        // Second...  is the provider allowing granting of URI permissions?
8887        if (!specialCrossUserGrant) {
8888            if (!pi.grantUriPermissions) {
8889                throw new SecurityException("Provider " + pi.packageName
8890                        + "/" + pi.name
8891                        + " does not allow granting of Uri permissions (uri "
8892                        + grantUri + ")");
8893            }
8894            if (pi.uriPermissionPatterns != null) {
8895                final int N = pi.uriPermissionPatterns.length;
8896                boolean allowed = false;
8897                for (int i=0; i<N; i++) {
8898                    if (pi.uriPermissionPatterns[i] != null
8899                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8900                        allowed = true;
8901                        break;
8902                    }
8903                }
8904                if (!allowed) {
8905                    throw new SecurityException("Provider " + pi.packageName
8906                            + "/" + pi.name
8907                            + " does not allow granting of permission to path of Uri "
8908                            + grantUri);
8909                }
8910            }
8911        }
8912
8913        // Third...  does the caller itself have permission to access
8914        // this uri?
8915        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8916            // Require they hold a strong enough Uri permission
8917            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8918                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8919                    throw new SecurityException(
8920                            "UID " + callingUid + " does not have permission to " + grantUri
8921                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8922                                    + "or related APIs");
8923                } else {
8924                    throw new SecurityException(
8925                            "UID " + callingUid + " does not have permission to " + grantUri);
8926                }
8927            }
8928        }
8929        return targetUid;
8930    }
8931
8932    /**
8933     * @param uri This uri must NOT contain an embedded userId.
8934     * @param userId The userId in which the uri is to be resolved.
8935     */
8936    @Override
8937    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8938            final int modeFlags, int userId) {
8939        enforceNotIsolatedCaller("checkGrantUriPermission");
8940        synchronized(this) {
8941            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8942                    new GrantUri(userId, uri, false), modeFlags, -1);
8943        }
8944    }
8945
8946    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8947            final int modeFlags, UriPermissionOwner owner) {
8948        if (!Intent.isAccessUriMode(modeFlags)) {
8949            return;
8950        }
8951
8952        // So here we are: the caller has the assumed permission
8953        // to the uri, and the target doesn't.  Let's now give this to
8954        // the target.
8955
8956        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8957                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8958
8959        final String authority = grantUri.uri.getAuthority();
8960        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8961                MATCH_DEBUG_TRIAGED_MISSING);
8962        if (pi == null) {
8963            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8964            return;
8965        }
8966
8967        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8968            grantUri.prefix = true;
8969        }
8970        final UriPermission perm = findOrCreateUriPermissionLocked(
8971                pi.packageName, targetPkg, targetUid, grantUri);
8972        perm.grantModes(modeFlags, owner);
8973    }
8974
8975    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8976            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8977        if (targetPkg == null) {
8978            throw new NullPointerException("targetPkg");
8979        }
8980        int targetUid;
8981        final IPackageManager pm = AppGlobals.getPackageManager();
8982        try {
8983            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8984        } catch (RemoteException ex) {
8985            return;
8986        }
8987
8988        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8989                targetUid);
8990        if (targetUid < 0) {
8991            return;
8992        }
8993
8994        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8995                owner);
8996    }
8997
8998    static class NeededUriGrants extends ArrayList<GrantUri> {
8999        final String targetPkg;
9000        final int targetUid;
9001        final int flags;
9002
9003        NeededUriGrants(String targetPkg, int targetUid, int flags) {
9004            this.targetPkg = targetPkg;
9005            this.targetUid = targetUid;
9006            this.flags = flags;
9007        }
9008    }
9009
9010    /**
9011     * Like checkGrantUriPermissionLocked, but takes an Intent.
9012     */
9013    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9014            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9015        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9016                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9017                + " clip=" + (intent != null ? intent.getClipData() : null)
9018                + " from " + intent + "; flags=0x"
9019                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9020
9021        if (targetPkg == null) {
9022            throw new NullPointerException("targetPkg");
9023        }
9024
9025        if (intent == null) {
9026            return null;
9027        }
9028        Uri data = intent.getData();
9029        ClipData clip = intent.getClipData();
9030        if (data == null && clip == null) {
9031            return null;
9032        }
9033        // Default userId for uris in the intent (if they don't specify it themselves)
9034        int contentUserHint = intent.getContentUserHint();
9035        if (contentUserHint == UserHandle.USER_CURRENT) {
9036            contentUserHint = UserHandle.getUserId(callingUid);
9037        }
9038        final IPackageManager pm = AppGlobals.getPackageManager();
9039        int targetUid;
9040        if (needed != null) {
9041            targetUid = needed.targetUid;
9042        } else {
9043            try {
9044                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9045                        targetUserId);
9046            } catch (RemoteException ex) {
9047                return null;
9048            }
9049            if (targetUid < 0) {
9050                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9051                        "Can't grant URI permission no uid for: " + targetPkg
9052                        + " on user " + targetUserId);
9053                return null;
9054            }
9055        }
9056        if (data != null) {
9057            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9058            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9059                    targetUid);
9060            if (targetUid > 0) {
9061                if (needed == null) {
9062                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
9063                }
9064                needed.add(grantUri);
9065            }
9066        }
9067        if (clip != null) {
9068            for (int i=0; i<clip.getItemCount(); i++) {
9069                Uri uri = clip.getItemAt(i).getUri();
9070                if (uri != null) {
9071                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9072                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9073                            targetUid);
9074                    if (targetUid > 0) {
9075                        if (needed == null) {
9076                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
9077                        }
9078                        needed.add(grantUri);
9079                    }
9080                } else {
9081                    Intent clipIntent = clip.getItemAt(i).getIntent();
9082                    if (clipIntent != null) {
9083                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9084                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9085                        if (newNeeded != null) {
9086                            needed = newNeeded;
9087                        }
9088                    }
9089                }
9090            }
9091        }
9092
9093        return needed;
9094    }
9095
9096    /**
9097     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9098     */
9099    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9100            UriPermissionOwner owner) {
9101        if (needed != null) {
9102            for (int i=0; i<needed.size(); i++) {
9103                GrantUri grantUri = needed.get(i);
9104                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9105                        grantUri, needed.flags, owner);
9106            }
9107        }
9108    }
9109
9110    void grantUriPermissionFromIntentLocked(int callingUid,
9111            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9112        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9113                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9114        if (needed == null) {
9115            return;
9116        }
9117
9118        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9119    }
9120
9121    /**
9122     * @param uri This uri must NOT contain an embedded userId.
9123     * @param userId The userId in which the uri is to be resolved.
9124     */
9125    @Override
9126    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9127            final int modeFlags, int userId) {
9128        enforceNotIsolatedCaller("grantUriPermission");
9129        GrantUri grantUri = new GrantUri(userId, uri, false);
9130        synchronized(this) {
9131            final ProcessRecord r = getRecordForAppLocked(caller);
9132            if (r == null) {
9133                throw new SecurityException("Unable to find app for caller "
9134                        + caller
9135                        + " when granting permission to uri " + grantUri);
9136            }
9137            if (targetPkg == null) {
9138                throw new IllegalArgumentException("null target");
9139            }
9140            if (grantUri == null) {
9141                throw new IllegalArgumentException("null uri");
9142            }
9143
9144            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9145                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9146                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9147                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9148
9149            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9150                    UserHandle.getUserId(r.uid));
9151        }
9152    }
9153
9154    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9155        if (perm.modeFlags == 0) {
9156            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9157                    perm.targetUid);
9158            if (perms != null) {
9159                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9160                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9161
9162                perms.remove(perm.uri);
9163                if (perms.isEmpty()) {
9164                    mGrantedUriPermissions.remove(perm.targetUid);
9165                }
9166            }
9167        }
9168    }
9169
9170    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9171            final int modeFlags) {
9172        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9173                "Revoking all granted permissions to " + grantUri);
9174
9175        final IPackageManager pm = AppGlobals.getPackageManager();
9176        final String authority = grantUri.uri.getAuthority();
9177        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9178                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9179        if (pi == null) {
9180            Slog.w(TAG, "No content provider found for permission revoke: "
9181                    + grantUri.toSafeString());
9182            return;
9183        }
9184
9185        // Does the caller have this permission on the URI?
9186        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9187            // If they don't have direct access to the URI, then revoke any
9188            // ownerless URI permissions that have been granted to them.
9189            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9190            if (perms != null) {
9191                boolean persistChanged = false;
9192                for (int i = perms.size()-1; i >= 0; i--) {
9193                    final UriPermission perm = perms.valueAt(i);
9194                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9195                        continue;
9196                    }
9197                    if (perm.uri.sourceUserId == grantUri.sourceUserId
9198                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9199                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9200                                "Revoking non-owned " + perm.targetUid
9201                                + " permission to " + perm.uri);
9202                        persistChanged |= perm.revokeModes(
9203                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9204                        if (perm.modeFlags == 0) {
9205                            perms.removeAt(i);
9206                        }
9207                    }
9208                }
9209                if (perms.isEmpty()) {
9210                    mGrantedUriPermissions.remove(callingUid);
9211                }
9212                if (persistChanged) {
9213                    schedulePersistUriGrants();
9214                }
9215            }
9216            return;
9217        }
9218
9219        boolean persistChanged = false;
9220
9221        // Go through all of the permissions and remove any that match.
9222        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9223            final int targetUid = mGrantedUriPermissions.keyAt(i);
9224            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9225
9226            for (int j = perms.size()-1; j >= 0; j--) {
9227                final UriPermission perm = perms.valueAt(j);
9228                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9229                    continue;
9230                }
9231                if (perm.uri.sourceUserId == grantUri.sourceUserId
9232                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9233                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9234                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9235                    persistChanged |= perm.revokeModes(
9236                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9237                            targetPackage == null);
9238                    if (perm.modeFlags == 0) {
9239                        perms.removeAt(j);
9240                    }
9241                }
9242            }
9243
9244            if (perms.isEmpty()) {
9245                mGrantedUriPermissions.removeAt(i);
9246            }
9247        }
9248
9249        if (persistChanged) {
9250            schedulePersistUriGrants();
9251        }
9252    }
9253
9254    /**
9255     * @param uri This uri must NOT contain an embedded userId.
9256     * @param userId The userId in which the uri is to be resolved.
9257     */
9258    @Override
9259    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9260            final int modeFlags, int userId) {
9261        enforceNotIsolatedCaller("revokeUriPermission");
9262        synchronized(this) {
9263            final ProcessRecord r = getRecordForAppLocked(caller);
9264            if (r == null) {
9265                throw new SecurityException("Unable to find app for caller "
9266                        + caller
9267                        + " when revoking permission to uri " + uri);
9268            }
9269            if (uri == null) {
9270                Slog.w(TAG, "revokeUriPermission: null uri");
9271                return;
9272            }
9273
9274            if (!Intent.isAccessUriMode(modeFlags)) {
9275                return;
9276            }
9277
9278            final String authority = uri.getAuthority();
9279            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9280                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9281            if (pi == null) {
9282                Slog.w(TAG, "No content provider found for permission revoke: "
9283                        + uri.toSafeString());
9284                return;
9285            }
9286
9287            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9288                    modeFlags);
9289        }
9290    }
9291
9292    /**
9293     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9294     * given package.
9295     *
9296     * @param packageName Package name to match, or {@code null} to apply to all
9297     *            packages.
9298     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9299     *            to all users.
9300     * @param persistable If persistable grants should be removed.
9301     */
9302    private void removeUriPermissionsForPackageLocked(
9303            String packageName, int userHandle, boolean persistable) {
9304        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9305            throw new IllegalArgumentException("Must narrow by either package or user");
9306        }
9307
9308        boolean persistChanged = false;
9309
9310        int N = mGrantedUriPermissions.size();
9311        for (int i = 0; i < N; i++) {
9312            final int targetUid = mGrantedUriPermissions.keyAt(i);
9313            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9314
9315            // Only inspect grants matching user
9316            if (userHandle == UserHandle.USER_ALL
9317                    || userHandle == UserHandle.getUserId(targetUid)) {
9318                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9319                    final UriPermission perm = it.next();
9320
9321                    // Only inspect grants matching package
9322                    if (packageName == null || perm.sourcePkg.equals(packageName)
9323                            || perm.targetPkg.equals(packageName)) {
9324                        // Hacky solution as part of fixing a security bug; ignore
9325                        // grants associated with DownloadManager so we don't have
9326                        // to immediately launch it to regrant the permissions
9327                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9328                                && !persistable) continue;
9329
9330                        persistChanged |= perm.revokeModes(persistable
9331                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9332
9333                        // Only remove when no modes remain; any persisted grants
9334                        // will keep this alive.
9335                        if (perm.modeFlags == 0) {
9336                            it.remove();
9337                        }
9338                    }
9339                }
9340
9341                if (perms.isEmpty()) {
9342                    mGrantedUriPermissions.remove(targetUid);
9343                    N--;
9344                    i--;
9345                }
9346            }
9347        }
9348
9349        if (persistChanged) {
9350            schedulePersistUriGrants();
9351        }
9352    }
9353
9354    @Override
9355    public IBinder newUriPermissionOwner(String name) {
9356        enforceNotIsolatedCaller("newUriPermissionOwner");
9357        synchronized(this) {
9358            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9359            return owner.getExternalTokenLocked();
9360        }
9361    }
9362
9363    @Override
9364    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9365        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9366        synchronized(this) {
9367            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9368            if (r == null) {
9369                throw new IllegalArgumentException("Activity does not exist; token="
9370                        + activityToken);
9371            }
9372            return r.getUriPermissionsLocked().getExternalTokenLocked();
9373        }
9374    }
9375    /**
9376     * @param uri This uri must NOT contain an embedded userId.
9377     * @param sourceUserId The userId in which the uri is to be resolved.
9378     * @param targetUserId The userId of the app that receives the grant.
9379     */
9380    @Override
9381    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9382            final int modeFlags, int sourceUserId, int targetUserId) {
9383        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9384                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9385                "grantUriPermissionFromOwner", null);
9386        synchronized(this) {
9387            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9388            if (owner == null) {
9389                throw new IllegalArgumentException("Unknown owner: " + token);
9390            }
9391            if (fromUid != Binder.getCallingUid()) {
9392                if (Binder.getCallingUid() != myUid()) {
9393                    // Only system code can grant URI permissions on behalf
9394                    // of other users.
9395                    throw new SecurityException("nice try");
9396                }
9397            }
9398            if (targetPkg == null) {
9399                throw new IllegalArgumentException("null target");
9400            }
9401            if (uri == null) {
9402                throw new IllegalArgumentException("null uri");
9403            }
9404
9405            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9406                    modeFlags, owner, targetUserId);
9407        }
9408    }
9409
9410    /**
9411     * @param uri This uri must NOT contain an embedded userId.
9412     * @param userId The userId in which the uri is to be resolved.
9413     */
9414    @Override
9415    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9416        synchronized(this) {
9417            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9418            if (owner == null) {
9419                throw new IllegalArgumentException("Unknown owner: " + token);
9420            }
9421
9422            if (uri == null) {
9423                owner.removeUriPermissionsLocked(mode);
9424            } else {
9425                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9426                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9427            }
9428        }
9429    }
9430
9431    private void schedulePersistUriGrants() {
9432        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9433            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9434                    10 * DateUtils.SECOND_IN_MILLIS);
9435        }
9436    }
9437
9438    private void writeGrantedUriPermissions() {
9439        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9440
9441        // Snapshot permissions so we can persist without lock
9442        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9443        synchronized (this) {
9444            final int size = mGrantedUriPermissions.size();
9445            for (int i = 0; i < size; i++) {
9446                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9447                for (UriPermission perm : perms.values()) {
9448                    if (perm.persistedModeFlags != 0) {
9449                        persist.add(perm.snapshot());
9450                    }
9451                }
9452            }
9453        }
9454
9455        FileOutputStream fos = null;
9456        try {
9457            fos = mGrantFile.startWrite();
9458
9459            XmlSerializer out = new FastXmlSerializer();
9460            out.setOutput(fos, StandardCharsets.UTF_8.name());
9461            out.startDocument(null, true);
9462            out.startTag(null, TAG_URI_GRANTS);
9463            for (UriPermission.Snapshot perm : persist) {
9464                out.startTag(null, TAG_URI_GRANT);
9465                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9466                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9467                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9468                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9469                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9470                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9471                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9472                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9473                out.endTag(null, TAG_URI_GRANT);
9474            }
9475            out.endTag(null, TAG_URI_GRANTS);
9476            out.endDocument();
9477
9478            mGrantFile.finishWrite(fos);
9479        } catch (IOException e) {
9480            if (fos != null) {
9481                mGrantFile.failWrite(fos);
9482            }
9483        }
9484    }
9485
9486    private void readGrantedUriPermissionsLocked() {
9487        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9488
9489        final long now = System.currentTimeMillis();
9490
9491        FileInputStream fis = null;
9492        try {
9493            fis = mGrantFile.openRead();
9494            final XmlPullParser in = Xml.newPullParser();
9495            in.setInput(fis, StandardCharsets.UTF_8.name());
9496
9497            int type;
9498            while ((type = in.next()) != END_DOCUMENT) {
9499                final String tag = in.getName();
9500                if (type == START_TAG) {
9501                    if (TAG_URI_GRANT.equals(tag)) {
9502                        final int sourceUserId;
9503                        final int targetUserId;
9504                        final int userHandle = readIntAttribute(in,
9505                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9506                        if (userHandle != UserHandle.USER_NULL) {
9507                            // For backwards compatibility.
9508                            sourceUserId = userHandle;
9509                            targetUserId = userHandle;
9510                        } else {
9511                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9512                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9513                        }
9514                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9515                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9516                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9517                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9518                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9519                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9520
9521                        // Sanity check that provider still belongs to source package
9522                        // Both direct boot aware and unaware packages are fine as we
9523                        // will do filtering at query time to avoid multiple parsing.
9524                        final ProviderInfo pi = getProviderInfoLocked(
9525                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9526                                        | MATCH_DIRECT_BOOT_UNAWARE);
9527                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9528                            int targetUid = -1;
9529                            try {
9530                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9531                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9532                            } catch (RemoteException e) {
9533                            }
9534                            if (targetUid != -1) {
9535                                final UriPermission perm = findOrCreateUriPermissionLocked(
9536                                        sourcePkg, targetPkg, targetUid,
9537                                        new GrantUri(sourceUserId, uri, prefix));
9538                                perm.initPersistedModes(modeFlags, createdTime);
9539                            }
9540                        } else {
9541                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9542                                    + " but instead found " + pi);
9543                        }
9544                    }
9545                }
9546            }
9547        } catch (FileNotFoundException e) {
9548            // Missing grants is okay
9549        } catch (IOException e) {
9550            Slog.wtf(TAG, "Failed reading Uri grants", e);
9551        } catch (XmlPullParserException e) {
9552            Slog.wtf(TAG, "Failed reading Uri grants", e);
9553        } finally {
9554            IoUtils.closeQuietly(fis);
9555        }
9556    }
9557
9558    /**
9559     * @param uri This uri must NOT contain an embedded userId.
9560     * @param userId The userId in which the uri is to be resolved.
9561     */
9562    @Override
9563    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9564        enforceNotIsolatedCaller("takePersistableUriPermission");
9565
9566        Preconditions.checkFlagsArgument(modeFlags,
9567                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9568
9569        synchronized (this) {
9570            final int callingUid = Binder.getCallingUid();
9571            boolean persistChanged = false;
9572            GrantUri grantUri = new GrantUri(userId, uri, false);
9573
9574            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9575                    new GrantUri(userId, uri, false));
9576            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9577                    new GrantUri(userId, uri, true));
9578
9579            final boolean exactValid = (exactPerm != null)
9580                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9581            final boolean prefixValid = (prefixPerm != null)
9582                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9583
9584            if (!(exactValid || prefixValid)) {
9585                throw new SecurityException("No persistable permission grants found for UID "
9586                        + callingUid + " and Uri " + grantUri.toSafeString());
9587            }
9588
9589            if (exactValid) {
9590                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9591            }
9592            if (prefixValid) {
9593                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9594            }
9595
9596            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9597
9598            if (persistChanged) {
9599                schedulePersistUriGrants();
9600            }
9601        }
9602    }
9603
9604    /**
9605     * @param uri This uri must NOT contain an embedded userId.
9606     * @param userId The userId in which the uri is to be resolved.
9607     */
9608    @Override
9609    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9610        enforceNotIsolatedCaller("releasePersistableUriPermission");
9611
9612        Preconditions.checkFlagsArgument(modeFlags,
9613                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9614
9615        synchronized (this) {
9616            final int callingUid = Binder.getCallingUid();
9617            boolean persistChanged = false;
9618
9619            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9620                    new GrantUri(userId, uri, false));
9621            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9622                    new GrantUri(userId, uri, true));
9623            if (exactPerm == null && prefixPerm == null) {
9624                throw new SecurityException("No permission grants found for UID " + callingUid
9625                        + " and Uri " + uri.toSafeString());
9626            }
9627
9628            if (exactPerm != null) {
9629                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9630                removeUriPermissionIfNeededLocked(exactPerm);
9631            }
9632            if (prefixPerm != null) {
9633                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9634                removeUriPermissionIfNeededLocked(prefixPerm);
9635            }
9636
9637            if (persistChanged) {
9638                schedulePersistUriGrants();
9639            }
9640        }
9641    }
9642
9643    /**
9644     * Prune any older {@link UriPermission} for the given UID until outstanding
9645     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9646     *
9647     * @return if any mutations occured that require persisting.
9648     */
9649    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9650        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9651        if (perms == null) return false;
9652        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9653
9654        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9655        for (UriPermission perm : perms.values()) {
9656            if (perm.persistedModeFlags != 0) {
9657                persisted.add(perm);
9658            }
9659        }
9660
9661        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9662        if (trimCount <= 0) return false;
9663
9664        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9665        for (int i = 0; i < trimCount; i++) {
9666            final UriPermission perm = persisted.get(i);
9667
9668            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9669                    "Trimming grant created at " + perm.persistedCreateTime);
9670
9671            perm.releasePersistableModes(~0);
9672            removeUriPermissionIfNeededLocked(perm);
9673        }
9674
9675        return true;
9676    }
9677
9678    @Override
9679    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9680            String packageName, boolean incoming) {
9681        enforceNotIsolatedCaller("getPersistedUriPermissions");
9682        Preconditions.checkNotNull(packageName, "packageName");
9683
9684        final int callingUid = Binder.getCallingUid();
9685        final int callingUserId = UserHandle.getUserId(callingUid);
9686        final IPackageManager pm = AppGlobals.getPackageManager();
9687        try {
9688            final int packageUid = pm.getPackageUid(packageName,
9689                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9690            if (packageUid != callingUid) {
9691                throw new SecurityException(
9692                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9693            }
9694        } catch (RemoteException e) {
9695            throw new SecurityException("Failed to verify package name ownership");
9696        }
9697
9698        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9699        synchronized (this) {
9700            if (incoming) {
9701                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9702                        callingUid);
9703                if (perms == null) {
9704                    Slog.w(TAG, "No permission grants found for " + packageName);
9705                } else {
9706                    for (UriPermission perm : perms.values()) {
9707                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9708                            result.add(perm.buildPersistedPublicApiObject());
9709                        }
9710                    }
9711                }
9712            } else {
9713                final int size = mGrantedUriPermissions.size();
9714                for (int i = 0; i < size; i++) {
9715                    final ArrayMap<GrantUri, UriPermission> perms =
9716                            mGrantedUriPermissions.valueAt(i);
9717                    for (UriPermission perm : perms.values()) {
9718                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9719                            result.add(perm.buildPersistedPublicApiObject());
9720                        }
9721                    }
9722                }
9723            }
9724        }
9725        return new ParceledListSlice<android.content.UriPermission>(result);
9726    }
9727
9728    @Override
9729    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9730            String packageName, int userId) {
9731        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9732                "getGrantedUriPermissions");
9733
9734        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9735        synchronized (this) {
9736            final int size = mGrantedUriPermissions.size();
9737            for (int i = 0; i < size; i++) {
9738                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9739                for (UriPermission perm : perms.values()) {
9740                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9741                            && perm.persistedModeFlags != 0) {
9742                        result.add(perm.buildPersistedPublicApiObject());
9743                    }
9744                }
9745            }
9746        }
9747        return new ParceledListSlice<android.content.UriPermission>(result);
9748    }
9749
9750    @Override
9751    public void clearGrantedUriPermissions(String packageName, int userId) {
9752        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9753                "clearGrantedUriPermissions");
9754        removeUriPermissionsForPackageLocked(packageName, userId, true);
9755    }
9756
9757    @Override
9758    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9759        synchronized (this) {
9760            ProcessRecord app =
9761                who != null ? getRecordForAppLocked(who) : null;
9762            if (app == null) return;
9763
9764            Message msg = Message.obtain();
9765            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9766            msg.obj = app;
9767            msg.arg1 = waiting ? 1 : 0;
9768            mUiHandler.sendMessage(msg);
9769        }
9770    }
9771
9772    @Override
9773    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9774        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9775        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9776        outInfo.availMem = getFreeMemory();
9777        outInfo.totalMem = getTotalMemory();
9778        outInfo.threshold = homeAppMem;
9779        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9780        outInfo.hiddenAppThreshold = cachedAppMem;
9781        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9782                ProcessList.SERVICE_ADJ);
9783        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9784                ProcessList.VISIBLE_APP_ADJ);
9785        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9786                ProcessList.FOREGROUND_APP_ADJ);
9787    }
9788
9789    // =========================================================
9790    // TASK MANAGEMENT
9791    // =========================================================
9792
9793    @Override
9794    public List<IBinder> getAppTasks(String callingPackage) {
9795        int callingUid = Binder.getCallingUid();
9796        long ident = Binder.clearCallingIdentity();
9797
9798        synchronized(this) {
9799            ArrayList<IBinder> list = new ArrayList<IBinder>();
9800            try {
9801                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9802
9803                final int N = mRecentTasks.size();
9804                for (int i = 0; i < N; i++) {
9805                    TaskRecord tr = mRecentTasks.get(i);
9806                    // Skip tasks that do not match the caller.  We don't need to verify
9807                    // callingPackage, because we are also limiting to callingUid and know
9808                    // that will limit to the correct security sandbox.
9809                    if (tr.effectiveUid != callingUid) {
9810                        continue;
9811                    }
9812                    Intent intent = tr.getBaseIntent();
9813                    if (intent == null ||
9814                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9815                        continue;
9816                    }
9817                    ActivityManager.RecentTaskInfo taskInfo =
9818                            createRecentTaskInfoFromTaskRecord(tr);
9819                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9820                    list.add(taskImpl.asBinder());
9821                }
9822            } finally {
9823                Binder.restoreCallingIdentity(ident);
9824            }
9825            return list;
9826        }
9827    }
9828
9829    @Override
9830    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9831        final int callingUid = Binder.getCallingUid();
9832        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9833
9834        synchronized(this) {
9835            if (DEBUG_ALL) Slog.v(
9836                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9837
9838            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9839                    callingUid);
9840
9841            // TODO: Improve with MRU list from all ActivityStacks.
9842            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9843        }
9844
9845        return list;
9846    }
9847
9848    /**
9849     * Creates a new RecentTaskInfo from a TaskRecord.
9850     */
9851    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9852        // Update the task description to reflect any changes in the task stack
9853        tr.updateTaskDescription();
9854
9855        // Compose the recent task info
9856        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9857        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9858        rti.persistentId = tr.taskId;
9859        rti.baseIntent = new Intent(tr.getBaseIntent());
9860        rti.origActivity = tr.origActivity;
9861        rti.realActivity = tr.realActivity;
9862        rti.description = tr.lastDescription;
9863        rti.stackId = tr.getStackId();
9864        rti.userId = tr.userId;
9865        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9866        rti.firstActiveTime = tr.firstActiveTime;
9867        rti.lastActiveTime = tr.lastActiveTime;
9868        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9869        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9870        rti.numActivities = 0;
9871        if (tr.mBounds != null) {
9872            rti.bounds = new Rect(tr.mBounds);
9873        }
9874        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9875        rti.resizeMode = tr.mResizeMode;
9876
9877        ActivityRecord base = null;
9878        ActivityRecord top = null;
9879        ActivityRecord tmp;
9880
9881        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9882            tmp = tr.mActivities.get(i);
9883            if (tmp.finishing) {
9884                continue;
9885            }
9886            base = tmp;
9887            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9888                top = base;
9889            }
9890            rti.numActivities++;
9891        }
9892
9893        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9894        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9895
9896        return rti;
9897    }
9898
9899    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9900        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9901                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9902        if (!allowed) {
9903            if (checkPermission(android.Manifest.permission.GET_TASKS,
9904                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9905                // Temporary compatibility: some existing apps on the system image may
9906                // still be requesting the old permission and not switched to the new
9907                // one; if so, we'll still allow them full access.  This means we need
9908                // to see if they are holding the old permission and are a system app.
9909                try {
9910                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9911                        allowed = true;
9912                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9913                                + " is using old GET_TASKS but privileged; allowing");
9914                    }
9915                } catch (RemoteException e) {
9916                }
9917            }
9918        }
9919        if (!allowed) {
9920            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9921                    + " does not hold REAL_GET_TASKS; limiting output");
9922        }
9923        return allowed;
9924    }
9925
9926    @Override
9927    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9928            int userId) {
9929        final int callingUid = Binder.getCallingUid();
9930        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9931                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9932
9933        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9934        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9935        synchronized (this) {
9936            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9937                    callingUid);
9938            final boolean detailed = checkCallingPermission(
9939                    android.Manifest.permission.GET_DETAILED_TASKS)
9940                    == PackageManager.PERMISSION_GRANTED;
9941
9942            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9943                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9944                return ParceledListSlice.emptyList();
9945            }
9946            mRecentTasks.loadUserRecentsLocked(userId);
9947
9948            final int recentsCount = mRecentTasks.size();
9949            ArrayList<ActivityManager.RecentTaskInfo> res =
9950                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9951
9952            final Set<Integer> includedUsers;
9953            if (includeProfiles) {
9954                includedUsers = mUserController.getProfileIds(userId);
9955            } else {
9956                includedUsers = new HashSet<>();
9957            }
9958            includedUsers.add(Integer.valueOf(userId));
9959
9960            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9961                TaskRecord tr = mRecentTasks.get(i);
9962                // Only add calling user or related users recent tasks
9963                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9964                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9965                    continue;
9966                }
9967
9968                if (tr.realActivitySuspended) {
9969                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9970                    continue;
9971                }
9972
9973                // Return the entry if desired by the caller.  We always return
9974                // the first entry, because callers always expect this to be the
9975                // foreground app.  We may filter others if the caller has
9976                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9977                // we should exclude the entry.
9978
9979                if (i == 0
9980                        || withExcluded
9981                        || (tr.intent == null)
9982                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9983                                == 0)) {
9984                    if (!allowed) {
9985                        // If the caller doesn't have the GET_TASKS permission, then only
9986                        // allow them to see a small subset of tasks -- their own and home.
9987                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9988                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9989                            continue;
9990                        }
9991                    }
9992                    final ActivityStack stack = tr.getStack();
9993                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9994                        if (stack != null && stack.isHomeOrRecentsStack()) {
9995                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9996                                    "Skipping, home or recents stack task: " + tr);
9997                            continue;
9998                        }
9999                    }
10000                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
10001                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
10002                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10003                                    "Skipping, top task in docked stack: " + tr);
10004                            continue;
10005                        }
10006                    }
10007                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10008                        if (stack != null && stack.isPinnedStack()) {
10009                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10010                                    "Skipping, pinned stack task: " + tr);
10011                            continue;
10012                        }
10013                    }
10014                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10015                        // Don't include auto remove tasks that are finished or finishing.
10016                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10017                                "Skipping, auto-remove without activity: " + tr);
10018                        continue;
10019                    }
10020                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10021                            && !tr.isAvailable) {
10022                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10023                                "Skipping, unavail real act: " + tr);
10024                        continue;
10025                    }
10026
10027                    if (!tr.mUserSetupComplete) {
10028                        // Don't include task launched while user is not done setting-up.
10029                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10030                                "Skipping, user setup not complete: " + tr);
10031                        continue;
10032                    }
10033
10034                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10035                    if (!detailed) {
10036                        rti.baseIntent.replaceExtras((Bundle)null);
10037                    }
10038
10039                    res.add(rti);
10040                    maxNum--;
10041                }
10042            }
10043            return new ParceledListSlice<>(res);
10044        }
10045    }
10046
10047    @Override
10048    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10049        synchronized (this) {
10050            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10051                    "getTaskThumbnail()");
10052            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10053                    id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10054            if (tr != null) {
10055                return tr.getTaskThumbnailLocked();
10056            }
10057        }
10058        return null;
10059    }
10060
10061    @Override
10062    public ActivityManager.TaskDescription getTaskDescription(int id) {
10063        synchronized (this) {
10064            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10065                    "getTaskDescription()");
10066            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10067                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10068            if (tr != null) {
10069                return tr.lastTaskDescription;
10070            }
10071        }
10072        return null;
10073    }
10074
10075    @Override
10076    public int addAppTask(IBinder activityToken, Intent intent,
10077            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10078        final int callingUid = Binder.getCallingUid();
10079        final long callingIdent = Binder.clearCallingIdentity();
10080
10081        try {
10082            synchronized (this) {
10083                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10084                if (r == null) {
10085                    throw new IllegalArgumentException("Activity does not exist; token="
10086                            + activityToken);
10087                }
10088                ComponentName comp = intent.getComponent();
10089                if (comp == null) {
10090                    throw new IllegalArgumentException("Intent " + intent
10091                            + " must specify explicit component");
10092                }
10093                if (thumbnail.getWidth() != mThumbnailWidth
10094                        || thumbnail.getHeight() != mThumbnailHeight) {
10095                    throw new IllegalArgumentException("Bad thumbnail size: got "
10096                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10097                            + mThumbnailWidth + "x" + mThumbnailHeight);
10098                }
10099                if (intent.getSelector() != null) {
10100                    intent.setSelector(null);
10101                }
10102                if (intent.getSourceBounds() != null) {
10103                    intent.setSourceBounds(null);
10104                }
10105                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10106                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10107                        // The caller has added this as an auto-remove task...  that makes no
10108                        // sense, so turn off auto-remove.
10109                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10110                    }
10111                }
10112                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10113                    mLastAddedTaskActivity = null;
10114                }
10115                ActivityInfo ainfo = mLastAddedTaskActivity;
10116                if (ainfo == null) {
10117                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10118                            comp, 0, UserHandle.getUserId(callingUid));
10119                    if (ainfo.applicationInfo.uid != callingUid) {
10120                        throw new SecurityException(
10121                                "Can't add task for another application: target uid="
10122                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10123                    }
10124                }
10125
10126                TaskRecord task = new TaskRecord(this,
10127                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10128                        ainfo, intent, description, new TaskThumbnailInfo());
10129
10130                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10131                if (trimIdx >= 0) {
10132                    // If this would have caused a trim, then we'll abort because that
10133                    // means it would be added at the end of the list but then just removed.
10134                    return INVALID_TASK_ID;
10135                }
10136
10137                final int N = mRecentTasks.size();
10138                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10139                    final TaskRecord tr = mRecentTasks.remove(N - 1);
10140                    tr.removedFromRecents();
10141                }
10142
10143                task.inRecents = true;
10144                mRecentTasks.add(task);
10145                r.getStack().addTask(task, false, "addAppTask");
10146
10147                task.setLastThumbnailLocked(thumbnail);
10148                task.freeLastThumbnail();
10149                return task.taskId;
10150            }
10151        } finally {
10152            Binder.restoreCallingIdentity(callingIdent);
10153        }
10154    }
10155
10156    @Override
10157    public Point getAppTaskThumbnailSize() {
10158        synchronized (this) {
10159            return new Point(mThumbnailWidth,  mThumbnailHeight);
10160        }
10161    }
10162
10163    @Override
10164    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10165        synchronized (this) {
10166            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10167            if (r != null) {
10168                r.setTaskDescription(td);
10169                final TaskRecord task = r.getTask();
10170                task.updateTaskDescription();
10171                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10172            }
10173        }
10174    }
10175
10176    @Override
10177    public void setTaskResizeable(int taskId, int resizeableMode) {
10178        synchronized (this) {
10179            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10180                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10181            if (task == null) {
10182                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10183                return;
10184            }
10185            task.setResizeMode(resizeableMode);
10186        }
10187    }
10188
10189    @Override
10190    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10191        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10192        long ident = Binder.clearCallingIdentity();
10193        try {
10194            synchronized (this) {
10195                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10196                if (task == null) {
10197                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10198                    return;
10199                }
10200                // Place the task in the right stack if it isn't there already based on
10201                // the requested bounds.
10202                // The stack transition logic is:
10203                // - a null bounds on a freeform task moves that task to fullscreen
10204                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10205                //   that task to freeform
10206                // - otherwise the task is not moved
10207                int stackId = task.getStackId();
10208                if (!StackId.isTaskResizeAllowed(stackId)) {
10209                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10210                }
10211                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10212                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10213                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10214                    stackId = FREEFORM_WORKSPACE_STACK_ID;
10215                }
10216
10217                // Reparent the task to the right stack if necessary
10218                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10219                if (stackId != task.getStackId()) {
10220                    // Defer resume until the task is resized below
10221                    task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10222                            DEFER_RESUME, "resizeTask");
10223                    preserveWindow = false;
10224                }
10225
10226                // After reparenting (which only resizes the task to the stack bounds), resize the
10227                // task to the actual bounds provided
10228                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10229            }
10230        } finally {
10231            Binder.restoreCallingIdentity(ident);
10232        }
10233    }
10234
10235    @Override
10236    public Rect getTaskBounds(int taskId) {
10237        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10238        long ident = Binder.clearCallingIdentity();
10239        Rect rect = new Rect();
10240        try {
10241            synchronized (this) {
10242                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10243                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10244                if (task == null) {
10245                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10246                    return rect;
10247                }
10248                if (task.getStack() != null) {
10249                    // Return the bounds from window manager since it will be adjusted for various
10250                    // things like the presense of a docked stack for tasks that aren't resizeable.
10251                    task.getWindowContainerBounds(rect);
10252                } else {
10253                    // Task isn't in window manager yet since it isn't associated with a stack.
10254                    // Return the persist value from activity manager
10255                    if (task.mBounds != null) {
10256                        rect.set(task.mBounds);
10257                    } else if (task.mLastNonFullscreenBounds != null) {
10258                        rect.set(task.mLastNonFullscreenBounds);
10259                    }
10260                }
10261            }
10262        } finally {
10263            Binder.restoreCallingIdentity(ident);
10264        }
10265        return rect;
10266    }
10267
10268    @Override
10269    public void cancelTaskWindowTransition(int taskId) {
10270        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10271        final long ident = Binder.clearCallingIdentity();
10272        try {
10273            synchronized (this) {
10274                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10275                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10276                if (task == null) {
10277                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10278                    return;
10279                }
10280                task.cancelWindowTransition();
10281            }
10282        } finally {
10283            Binder.restoreCallingIdentity(ident);
10284        }
10285    }
10286
10287    @Override
10288    public void cancelTaskThumbnailTransition(int taskId) {
10289        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10290        final long ident = Binder.clearCallingIdentity();
10291        try {
10292            synchronized (this) {
10293                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10294                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10295                if (task == null) {
10296                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10297                    return;
10298                }
10299                task.cancelThumbnailTransition();
10300            }
10301        } finally {
10302            Binder.restoreCallingIdentity(ident);
10303        }
10304    }
10305
10306    @Override
10307    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10308        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10309        final long ident = Binder.clearCallingIdentity();
10310        try {
10311            final TaskRecord task;
10312            synchronized (this) {
10313                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10314                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10315                if (task == null) {
10316                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10317                    return null;
10318                }
10319            }
10320            // Don't call this while holding the lock as this operation might hit the disk.
10321            return task.getSnapshot(reducedResolution);
10322        } finally {
10323            Binder.restoreCallingIdentity(ident);
10324        }
10325    }
10326
10327    @Override
10328    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10329        if (userId != UserHandle.getCallingUserId()) {
10330            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10331                    "getTaskDescriptionIcon");
10332        }
10333        final File passedIconFile = new File(filePath);
10334        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10335                passedIconFile.getName());
10336        if (!legitIconFile.getPath().equals(filePath)
10337                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10338            throw new IllegalArgumentException("Bad file path: " + filePath
10339                    + " passed for userId " + userId);
10340        }
10341        return mRecentTasks.getTaskDescriptionIcon(filePath);
10342    }
10343
10344    @Override
10345    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10346            throws RemoteException {
10347        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10348        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10349                activityOptions.getCustomInPlaceResId() == 0) {
10350            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10351                    "with valid animation");
10352        }
10353        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10354        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10355                activityOptions.getCustomInPlaceResId());
10356        mWindowManager.executeAppTransition();
10357    }
10358
10359    private void removeTasksByPackageNameLocked(String packageName, int userId) {
10360        // Remove all tasks with activities in the specified package from the list of recent tasks
10361        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10362            TaskRecord tr = mRecentTasks.get(i);
10363            if (tr.userId != userId) continue;
10364
10365            ComponentName cn = tr.intent.getComponent();
10366            if (cn != null && cn.getPackageName().equals(packageName)) {
10367                // If the package name matches, remove the task.
10368                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10369            }
10370        }
10371    }
10372
10373    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10374            int userId) {
10375
10376        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10377            TaskRecord tr = mRecentTasks.get(i);
10378            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10379                continue;
10380            }
10381
10382            ComponentName cn = tr.intent.getComponent();
10383            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10384                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10385            if (sameComponent) {
10386                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10387            }
10388        }
10389    }
10390
10391    @Override
10392    public void removeStack(int stackId) {
10393        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10394        if (StackId.isHomeOrRecentsStack(stackId)) {
10395            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10396        }
10397
10398        synchronized (this) {
10399            final long ident = Binder.clearCallingIdentity();
10400            try {
10401                mStackSupervisor.removeStackLocked(stackId);
10402            } finally {
10403                Binder.restoreCallingIdentity(ident);
10404            }
10405        }
10406    }
10407
10408    @Override
10409    public void moveStackToDisplay(int stackId, int displayId) {
10410        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10411
10412        synchronized (this) {
10413            final long ident = Binder.clearCallingIdentity();
10414            try {
10415                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10416                        + " to displayId=" + displayId);
10417                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10418            } finally {
10419                Binder.restoreCallingIdentity(ident);
10420            }
10421        }
10422    }
10423
10424    @Override
10425    public boolean removeTask(int taskId) {
10426        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10427        synchronized (this) {
10428            final long ident = Binder.clearCallingIdentity();
10429            try {
10430                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10431            } finally {
10432                Binder.restoreCallingIdentity(ident);
10433            }
10434        }
10435    }
10436
10437    /**
10438     * TODO: Add mController hook
10439     */
10440    @Override
10441    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10442        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10443
10444        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10445        synchronized(this) {
10446            moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10447        }
10448    }
10449
10450    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10451        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10452
10453        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10454                Binder.getCallingUid(), -1, -1, "Task to front")) {
10455            ActivityOptions.abort(options);
10456            return;
10457        }
10458        final long origId = Binder.clearCallingIdentity();
10459        try {
10460            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10461            if (task == null) {
10462                Slog.d(TAG, "Could not find task for id: "+ taskId);
10463                return;
10464            }
10465            if (mStackSupervisor.isLockTaskModeViolation(task)) {
10466                mStackSupervisor.showLockTaskToast();
10467                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10468                return;
10469            }
10470            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10471            if (prev != null) {
10472                task.setTaskToReturnTo(prev);
10473            }
10474            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10475                    false /* forceNonResizable */);
10476
10477            final ActivityRecord topActivity = task.getTopActivity();
10478            if (topActivity != null) {
10479
10480                // We are reshowing a task, use a starting window to hide the initial draw delay
10481                // so the transition can start earlier.
10482                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10483                        true /* taskSwitch */, fromRecents);
10484            }
10485        } finally {
10486            Binder.restoreCallingIdentity(origId);
10487        }
10488        ActivityOptions.abort(options);
10489    }
10490
10491    /**
10492     * Attempts to move a task backwards in z-order (the order of activities within the task is
10493     * unchanged).
10494     *
10495     * There are several possible results of this call:
10496     * - if the task is locked, then we will show the lock toast
10497     * - if there is a task behind the provided task, then that task is made visible and resumed as
10498     *   this task is moved to the back
10499     * - otherwise, if there are no other tasks in the stack:
10500     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10501     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10502     *       (depending on whether it is visible)
10503     *     - otherwise, we simply return home and hide this task
10504     *
10505     * @param token A reference to the activity we wish to move
10506     * @param nonRoot If false then this only works if the activity is the root
10507     *                of a task; if true it will work for any activity in a task.
10508     * @return Returns true if the move completed, false if not.
10509     */
10510    @Override
10511    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10512        enforceNotIsolatedCaller("moveActivityTaskToBack");
10513        synchronized(this) {
10514            final long origId = Binder.clearCallingIdentity();
10515            try {
10516                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10517                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10518                if (task != null) {
10519                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10520                }
10521            } finally {
10522                Binder.restoreCallingIdentity(origId);
10523            }
10524        }
10525        return false;
10526    }
10527
10528    @Override
10529    public void moveTaskBackwards(int task) {
10530        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10531                "moveTaskBackwards()");
10532
10533        synchronized(this) {
10534            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10535                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10536                return;
10537            }
10538            final long origId = Binder.clearCallingIdentity();
10539            moveTaskBackwardsLocked(task);
10540            Binder.restoreCallingIdentity(origId);
10541        }
10542    }
10543
10544    private final void moveTaskBackwardsLocked(int task) {
10545        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10546    }
10547
10548    @Override
10549    public int createStackOnDisplay(int displayId) throws RemoteException {
10550        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10551        synchronized (this) {
10552            final int stackId = mStackSupervisor.getNextStackId();
10553            final ActivityStack stack =
10554                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10555            if (stack == null) {
10556                return INVALID_STACK_ID;
10557            }
10558            return stack.mStackId;
10559        }
10560    }
10561
10562    @Override
10563    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10564        synchronized (this) {
10565            final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10566            if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10567                return stack.mDisplayId;
10568            }
10569            return DEFAULT_DISPLAY;
10570        }
10571    }
10572
10573    @Override
10574    public int getActivityStackId(IBinder token) throws RemoteException {
10575        synchronized (this) {
10576            ActivityStack stack = ActivityRecord.getStackLocked(token);
10577            if (stack == null) {
10578                return INVALID_STACK_ID;
10579            }
10580            return stack.mStackId;
10581        }
10582    }
10583
10584    @Override
10585    public void exitFreeformMode(IBinder token) throws RemoteException {
10586        synchronized (this) {
10587            long ident = Binder.clearCallingIdentity();
10588            try {
10589                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10590                if (r == null) {
10591                    throw new IllegalArgumentException(
10592                            "exitFreeformMode: No activity record matching token=" + token);
10593                }
10594
10595                final ActivityStack stack = r.getStack();
10596                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10597                    throw new IllegalStateException(
10598                            "exitFreeformMode: You can only go fullscreen from freeform.");
10599                }
10600
10601                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10602                r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10603                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10604            } finally {
10605                Binder.restoreCallingIdentity(ident);
10606            }
10607        }
10608    }
10609
10610    @Override
10611    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10612        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10613        if (StackId.isHomeOrRecentsStack(stackId)) {
10614            throw new IllegalArgumentException(
10615                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10616        }
10617        synchronized (this) {
10618            long ident = Binder.clearCallingIdentity();
10619            try {
10620                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10621                if (task == null) {
10622                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10623                    return;
10624                }
10625
10626                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10627                        + " to stackId=" + stackId + " toTop=" + toTop);
10628                if (stackId == DOCKED_STACK_ID) {
10629                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10630                            null /* initialBounds */);
10631                }
10632                task.reparent(stackId, toTop,
10633                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10634            } finally {
10635                Binder.restoreCallingIdentity(ident);
10636            }
10637        }
10638    }
10639
10640    @Override
10641    public void swapDockedAndFullscreenStack() throws RemoteException {
10642        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10643        synchronized (this) {
10644            long ident = Binder.clearCallingIdentity();
10645            try {
10646                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10647                        FULLSCREEN_WORKSPACE_STACK_ID);
10648                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10649                        : null;
10650                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10651                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10652                        : null;
10653                if (topTask == null || tasks == null || tasks.size() == 0) {
10654                    Slog.w(TAG,
10655                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10656                    return;
10657                }
10658
10659                // TODO: App transition
10660                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10661
10662                // Defer the resume until we move all the docked tasks to the fullscreen stack below
10663                topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10664                        DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10665                final int size = tasks.size();
10666                for (int i = 0; i < size; i++) {
10667                    final int id = tasks.get(i).taskId;
10668                    if (id == topTask.taskId) {
10669                        continue;
10670                    }
10671
10672                    // Defer the resume until after all the tasks have been moved
10673                    tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10674                            REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10675                            "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10676                }
10677
10678                // Because we deferred the resume to avoid conflicts with stack switches while
10679                // resuming, we need to do it after all the tasks are moved.
10680                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10681                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10682
10683                mWindowManager.executeAppTransition();
10684            } finally {
10685                Binder.restoreCallingIdentity(ident);
10686            }
10687        }
10688    }
10689
10690    /**
10691     * Moves the input task to the docked stack.
10692     *
10693     * @param taskId Id of task to move.
10694     * @param createMode The mode the docked stack should be created in if it doesn't exist
10695     *                   already. See
10696     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10697     *                   and
10698     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10699     * @param toTop If the task and stack should be moved to the top.
10700     * @param animate Whether we should play an animation for the moving the task
10701     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10702     *                      docked stack. Pass {@code null} to use default bounds.
10703     */
10704    @Override
10705    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10706            Rect initialBounds) {
10707        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10708        synchronized (this) {
10709            long ident = Binder.clearCallingIdentity();
10710            try {
10711                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10712                if (task == null) {
10713                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10714                    return false;
10715                }
10716
10717                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10718                        + " to createMode=" + createMode + " toTop=" + toTop);
10719                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10720
10721                // Defer resuming until we move the home stack to the front below
10722                final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10723                        REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10724                        "moveTaskToDockedStack");
10725                if (moved) {
10726                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10727                }
10728                return moved;
10729            } finally {
10730                Binder.restoreCallingIdentity(ident);
10731            }
10732        }
10733    }
10734
10735    /**
10736     * Moves the top activity in the input stackId to the pinned stack.
10737     *
10738     * @param stackId Id of stack to move the top activity to pinned stack.
10739     * @param bounds Bounds to use for pinned stack.
10740     *
10741     * @return True if the top activity of the input stack was successfully moved to the pinned
10742     *          stack.
10743     */
10744    @Override
10745    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10746        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10747        synchronized (this) {
10748            if (!mSupportsPictureInPicture) {
10749                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10750                        + "Device doesn't support picture-in-picture mode");
10751            }
10752
10753            long ident = Binder.clearCallingIdentity();
10754            try {
10755                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10756            } finally {
10757                Binder.restoreCallingIdentity(ident);
10758            }
10759        }
10760    }
10761
10762    @Override
10763    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10764            boolean preserveWindows, boolean animate, int animationDuration) {
10765        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10766        long ident = Binder.clearCallingIdentity();
10767        try {
10768            synchronized (this) {
10769                if (animate) {
10770                    if (stackId == PINNED_STACK_ID) {
10771                        final PinnedActivityStack pinnedStack =
10772                                mStackSupervisor.getStack(PINNED_STACK_ID);
10773                        if (pinnedStack != null) {
10774                            pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10775                                    destBounds, animationDuration, false /* fromFullscreen */);
10776                        }
10777                    } else {
10778                        throw new IllegalArgumentException("Stack: " + stackId
10779                                + " doesn't support animated resize.");
10780                    }
10781                } else {
10782                    mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10783                            null /* tempTaskInsetBounds */, preserveWindows,
10784                            allowResizeInDockedMode, !DEFER_RESUME);
10785                }
10786            }
10787        } finally {
10788            Binder.restoreCallingIdentity(ident);
10789        }
10790    }
10791
10792    @Override
10793    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10794            Rect tempDockedTaskInsetBounds,
10795            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10796        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10797                "resizeDockedStack()");
10798        long ident = Binder.clearCallingIdentity();
10799        try {
10800            synchronized (this) {
10801                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10802                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10803                        PRESERVE_WINDOWS);
10804            }
10805        } finally {
10806            Binder.restoreCallingIdentity(ident);
10807        }
10808    }
10809
10810    @Override
10811    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10812        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10813                "resizePinnedStack()");
10814        final long ident = Binder.clearCallingIdentity();
10815        try {
10816            synchronized (this) {
10817                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10818            }
10819        } finally {
10820            Binder.restoreCallingIdentity(ident);
10821        }
10822    }
10823
10824    /**
10825     * Try to place task to provided position. The final position might be different depending on
10826     * current user and stacks state. The task will be moved to target stack if it's currently in
10827     * different stack.
10828     */
10829    @Override
10830    public void positionTaskInStack(int taskId, int stackId, int position) {
10831        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10832        if (StackId.isHomeOrRecentsStack(stackId)) {
10833            throw new IllegalArgumentException(
10834                    "positionTaskInStack: Attempt to change the position of task "
10835                    + taskId + " in/to home/recents stack");
10836        }
10837        synchronized (this) {
10838            long ident = Binder.clearCallingIdentity();
10839            try {
10840                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10841                        + taskId + " in stackId=" + stackId + " at position=" + position);
10842                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10843                if (task == null) {
10844                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10845                            + taskId);
10846                }
10847
10848                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10849                        !ON_TOP);
10850
10851                // TODO: Have the callers of this API call a separate reparent method if that is
10852                // what they intended to do vs. having this method also do reparenting.
10853                if (task.getStack() == stack) {
10854                    // Change position in current stack.
10855                    stack.positionChildAt(task, position);
10856                } else {
10857                    // Reparent to new stack.
10858                    task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10859                            !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10860                }
10861            } finally {
10862                Binder.restoreCallingIdentity(ident);
10863            }
10864        }
10865    }
10866
10867    @Override
10868    public List<StackInfo> getAllStackInfos() {
10869        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10870        long ident = Binder.clearCallingIdentity();
10871        try {
10872            synchronized (this) {
10873                return mStackSupervisor.getAllStackInfosLocked();
10874            }
10875        } finally {
10876            Binder.restoreCallingIdentity(ident);
10877        }
10878    }
10879
10880    @Override
10881    public StackInfo getStackInfo(int stackId) {
10882        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10883        long ident = Binder.clearCallingIdentity();
10884        try {
10885            synchronized (this) {
10886                return mStackSupervisor.getStackInfoLocked(stackId);
10887            }
10888        } finally {
10889            Binder.restoreCallingIdentity(ident);
10890        }
10891    }
10892
10893    @Override
10894    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10895        synchronized(this) {
10896            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10897        }
10898    }
10899
10900    @Override
10901    public void updateDeviceOwner(String packageName) {
10902        final int callingUid = Binder.getCallingUid();
10903        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10904            throw new SecurityException("updateDeviceOwner called from non-system process");
10905        }
10906        synchronized (this) {
10907            mDeviceOwnerName = packageName;
10908        }
10909    }
10910
10911    @Override
10912    public void updateLockTaskPackages(int userId, String[] packages) {
10913        final int callingUid = Binder.getCallingUid();
10914        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10915            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10916                    "updateLockTaskPackages()");
10917        }
10918        synchronized (this) {
10919            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10920                    Arrays.toString(packages));
10921            mLockTaskPackages.put(userId, packages);
10922            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10923        }
10924    }
10925
10926
10927    void startLockTaskModeLocked(TaskRecord task) {
10928        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10929        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10930            return;
10931        }
10932
10933        // When a task is locked, dismiss the pinned stack if it exists
10934        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10935                PINNED_STACK_ID);
10936        if (pinnedStack != null) {
10937            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10938        }
10939
10940        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10941        // is initiated by system after the pinning request was shown and locked mode is initiated
10942        // by an authorized app directly
10943        final int callingUid = Binder.getCallingUid();
10944        boolean isSystemInitiated = callingUid == SYSTEM_UID;
10945        long ident = Binder.clearCallingIdentity();
10946        try {
10947            if (!isSystemInitiated) {
10948                task.mLockTaskUid = callingUid;
10949                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10950                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10951                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10952                    StatusBarManagerInternal statusBarManager =
10953                            LocalServices.getService(StatusBarManagerInternal.class);
10954                    if (statusBarManager != null) {
10955                        statusBarManager.showScreenPinningRequest(task.taskId);
10956                    }
10957                    return;
10958                }
10959
10960                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10961                if (stack == null || task != stack.topTask()) {
10962                    throw new IllegalArgumentException("Invalid task, not in foreground");
10963                }
10964            }
10965            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10966                    "Locking fully");
10967            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10968                    ActivityManager.LOCK_TASK_MODE_PINNED :
10969                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10970                    "startLockTask", true);
10971        } finally {
10972            Binder.restoreCallingIdentity(ident);
10973        }
10974    }
10975
10976    @Override
10977    public void startLockTaskModeById(int taskId) {
10978        synchronized (this) {
10979            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10980            if (task != null) {
10981                startLockTaskModeLocked(task);
10982            }
10983        }
10984    }
10985
10986    @Override
10987    public void startLockTaskModeByToken(IBinder token) {
10988        synchronized (this) {
10989            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10990            if (r == null) {
10991                return;
10992            }
10993            final TaskRecord task = r.getTask();
10994            if (task != null) {
10995                startLockTaskModeLocked(task);
10996            }
10997        }
10998    }
10999
11000    @Override
11001    public void startSystemLockTaskMode(int taskId) throws RemoteException {
11002        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11003        // This makes inner call to look as if it was initiated by system.
11004        long ident = Binder.clearCallingIdentity();
11005        try {
11006            synchronized (this) {
11007                startLockTaskModeById(taskId);
11008            }
11009        } finally {
11010            Binder.restoreCallingIdentity(ident);
11011        }
11012    }
11013
11014    @Override
11015    public void stopLockTaskMode() {
11016        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11017        if (lockTask == null) {
11018            // Our work here is done.
11019            return;
11020        }
11021
11022        final int callingUid = Binder.getCallingUid();
11023        final int lockTaskUid = lockTask.mLockTaskUid;
11024        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11025        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11026            // Done.
11027            return;
11028        } else {
11029            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11030            // It is possible lockTaskMode was started by the system process because
11031            // android:lockTaskMode is set to a locking value in the application manifest
11032            // instead of the app calling startLockTaskMode. In this case
11033            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11034            // {@link TaskRecord.effectiveUid} instead. Also caller with
11035            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11036            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11037                    && callingUid != lockTaskUid
11038                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11039                throw new SecurityException("Invalid uid, expected " + lockTaskUid
11040                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11041            }
11042        }
11043        long ident = Binder.clearCallingIdentity();
11044        try {
11045            Log.d(TAG, "stopLockTaskMode");
11046            // Stop lock task
11047            synchronized (this) {
11048                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11049                        "stopLockTask", true);
11050            }
11051            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11052            if (tm != null) {
11053                tm.showInCallScreen(false);
11054            }
11055        } finally {
11056            Binder.restoreCallingIdentity(ident);
11057        }
11058    }
11059
11060    /**
11061     * This API should be called by SystemUI only when user perform certain action to dismiss
11062     * lock task mode. We should only dismiss pinned lock task mode in this case.
11063     */
11064    @Override
11065    public void stopSystemLockTaskMode() throws RemoteException {
11066        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11067            stopLockTaskMode();
11068        } else {
11069            mStackSupervisor.showLockTaskToast();
11070        }
11071    }
11072
11073    @Override
11074    public boolean isInLockTaskMode() {
11075        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11076    }
11077
11078    @Override
11079    public int getLockTaskModeState() {
11080        synchronized (this) {
11081            return mStackSupervisor.getLockTaskModeState();
11082        }
11083    }
11084
11085    @Override
11086    public void showLockTaskEscapeMessage(IBinder token) {
11087        synchronized (this) {
11088            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11089            if (r == null) {
11090                return;
11091            }
11092            mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11093        }
11094    }
11095
11096    @Override
11097    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11098            throws RemoteException {
11099        synchronized (this) {
11100            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11101            if (r == null) {
11102                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11103                        + token);
11104                return;
11105            }
11106            final long origId = Binder.clearCallingIdentity();
11107            try {
11108                r.setDisablePreviewScreenshots(disable);
11109            } finally {
11110                Binder.restoreCallingIdentity(origId);
11111            }
11112        }
11113    }
11114
11115    // =========================================================
11116    // CONTENT PROVIDERS
11117    // =========================================================
11118
11119    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11120        List<ProviderInfo> providers = null;
11121        try {
11122            providers = AppGlobals.getPackageManager()
11123                    .queryContentProviders(app.processName, app.uid,
11124                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11125                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11126                    .getList();
11127        } catch (RemoteException ex) {
11128        }
11129        if (DEBUG_MU) Slog.v(TAG_MU,
11130                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11131        int userId = app.userId;
11132        if (providers != null) {
11133            int N = providers.size();
11134            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11135            for (int i=0; i<N; i++) {
11136                // TODO: keep logic in sync with installEncryptionUnawareProviders
11137                ProviderInfo cpi =
11138                    (ProviderInfo)providers.get(i);
11139                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11140                        cpi.name, cpi.flags);
11141                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11142                    // This is a singleton provider, but a user besides the
11143                    // default user is asking to initialize a process it runs
11144                    // in...  well, no, it doesn't actually run in this process,
11145                    // it runs in the process of the default user.  Get rid of it.
11146                    providers.remove(i);
11147                    N--;
11148                    i--;
11149                    continue;
11150                }
11151
11152                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11153                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11154                if (cpr == null) {
11155                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11156                    mProviderMap.putProviderByClass(comp, cpr);
11157                }
11158                if (DEBUG_MU) Slog.v(TAG_MU,
11159                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11160                app.pubProviders.put(cpi.name, cpr);
11161                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11162                    // Don't add this if it is a platform component that is marked
11163                    // to run in multiple processes, because this is actually
11164                    // part of the framework so doesn't make sense to track as a
11165                    // separate apk in the process.
11166                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11167                            mProcessStats);
11168                }
11169                notifyPackageUse(cpi.applicationInfo.packageName,
11170                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11171            }
11172        }
11173        return providers;
11174    }
11175
11176    /**
11177     * Check if the calling UID has a possible chance at accessing the provider
11178     * at the given authority and user.
11179     */
11180    public String checkContentProviderAccess(String authority, int userId) {
11181        if (userId == UserHandle.USER_ALL) {
11182            mContext.enforceCallingOrSelfPermission(
11183                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11184            userId = UserHandle.getCallingUserId();
11185        }
11186
11187        ProviderInfo cpi = null;
11188        try {
11189            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11190                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11191                            | PackageManager.MATCH_DISABLED_COMPONENTS
11192                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11193                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11194                    userId);
11195        } catch (RemoteException ignored) {
11196        }
11197        if (cpi == null) {
11198            return "Failed to find provider " + authority + " for user " + userId
11199                    + "; expected to find a valid ContentProvider for this authority";
11200        }
11201
11202        ProcessRecord r = null;
11203        synchronized (mPidsSelfLocked) {
11204            r = mPidsSelfLocked.get(Binder.getCallingPid());
11205        }
11206        if (r == null) {
11207            return "Failed to find PID " + Binder.getCallingPid();
11208        }
11209
11210        synchronized (this) {
11211            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11212        }
11213    }
11214
11215    /**
11216     * Check if {@link ProcessRecord} has a possible chance at accessing the
11217     * given {@link ProviderInfo}. Final permission checking is always done
11218     * in {@link ContentProvider}.
11219     */
11220    private final String checkContentProviderPermissionLocked(
11221            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11222        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11223        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11224        boolean checkedGrants = false;
11225        if (checkUser) {
11226            // Looking for cross-user grants before enforcing the typical cross-users permissions
11227            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11228            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11229                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11230                    return null;
11231                }
11232                checkedGrants = true;
11233            }
11234            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11235                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11236            if (userId != tmpTargetUserId) {
11237                // When we actually went to determine the final targer user ID, this ended
11238                // up different than our initial check for the authority.  This is because
11239                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11240                // SELF.  So we need to re-check the grants again.
11241                checkedGrants = false;
11242            }
11243        }
11244        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11245                cpi.applicationInfo.uid, cpi.exported)
11246                == PackageManager.PERMISSION_GRANTED) {
11247            return null;
11248        }
11249        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11250                cpi.applicationInfo.uid, cpi.exported)
11251                == PackageManager.PERMISSION_GRANTED) {
11252            return null;
11253        }
11254
11255        PathPermission[] pps = cpi.pathPermissions;
11256        if (pps != null) {
11257            int i = pps.length;
11258            while (i > 0) {
11259                i--;
11260                PathPermission pp = pps[i];
11261                String pprperm = pp.getReadPermission();
11262                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11263                        cpi.applicationInfo.uid, cpi.exported)
11264                        == PackageManager.PERMISSION_GRANTED) {
11265                    return null;
11266                }
11267                String ppwperm = pp.getWritePermission();
11268                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11269                        cpi.applicationInfo.uid, cpi.exported)
11270                        == PackageManager.PERMISSION_GRANTED) {
11271                    return null;
11272                }
11273            }
11274        }
11275        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11276            return null;
11277        }
11278
11279        final String suffix;
11280        if (!cpi.exported) {
11281            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11282        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11283            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11284        } else {
11285            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11286        }
11287        final String msg = "Permission Denial: opening provider " + cpi.name
11288                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11289                + ", uid=" + callingUid + ")" + suffix;
11290        Slog.w(TAG, msg);
11291        return msg;
11292    }
11293
11294    /**
11295     * Returns if the ContentProvider has granted a uri to callingUid
11296     */
11297    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11298        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11299        if (perms != null) {
11300            for (int i=perms.size()-1; i>=0; i--) {
11301                GrantUri grantUri = perms.keyAt(i);
11302                if (grantUri.sourceUserId == userId || !checkUser) {
11303                    if (matchesProvider(grantUri.uri, cpi)) {
11304                        return true;
11305                    }
11306                }
11307            }
11308        }
11309        return false;
11310    }
11311
11312    /**
11313     * Returns true if the uri authority is one of the authorities specified in the provider.
11314     */
11315    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11316        String uriAuth = uri.getAuthority();
11317        String cpiAuth = cpi.authority;
11318        if (cpiAuth.indexOf(';') == -1) {
11319            return cpiAuth.equals(uriAuth);
11320        }
11321        String[] cpiAuths = cpiAuth.split(";");
11322        int length = cpiAuths.length;
11323        for (int i = 0; i < length; i++) {
11324            if (cpiAuths[i].equals(uriAuth)) return true;
11325        }
11326        return false;
11327    }
11328
11329    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11330            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11331        if (r != null) {
11332            for (int i=0; i<r.conProviders.size(); i++) {
11333                ContentProviderConnection conn = r.conProviders.get(i);
11334                if (conn.provider == cpr) {
11335                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11336                            "Adding provider requested by "
11337                            + r.processName + " from process "
11338                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11339                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11340                    if (stable) {
11341                        conn.stableCount++;
11342                        conn.numStableIncs++;
11343                    } else {
11344                        conn.unstableCount++;
11345                        conn.numUnstableIncs++;
11346                    }
11347                    return conn;
11348                }
11349            }
11350            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11351            if (stable) {
11352                conn.stableCount = 1;
11353                conn.numStableIncs = 1;
11354            } else {
11355                conn.unstableCount = 1;
11356                conn.numUnstableIncs = 1;
11357            }
11358            cpr.connections.add(conn);
11359            r.conProviders.add(conn);
11360            startAssociationLocked(r.uid, r.processName, r.curProcState,
11361                    cpr.uid, cpr.name, cpr.info.processName);
11362            return conn;
11363        }
11364        cpr.addExternalProcessHandleLocked(externalProcessToken);
11365        return null;
11366    }
11367
11368    boolean decProviderCountLocked(ContentProviderConnection conn,
11369            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11370        if (conn != null) {
11371            cpr = conn.provider;
11372            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11373                    "Removing provider requested by "
11374                    + conn.client.processName + " from process "
11375                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11376                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11377            if (stable) {
11378                conn.stableCount--;
11379            } else {
11380                conn.unstableCount--;
11381            }
11382            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11383                cpr.connections.remove(conn);
11384                conn.client.conProviders.remove(conn);
11385                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11386                    // The client is more important than last activity -- note the time this
11387                    // is happening, so we keep the old provider process around a bit as last
11388                    // activity to avoid thrashing it.
11389                    if (cpr.proc != null) {
11390                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11391                    }
11392                }
11393                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11394                return true;
11395            }
11396            return false;
11397        }
11398        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11399        return false;
11400    }
11401
11402    private void checkTime(long startTime, String where) {
11403        long now = SystemClock.uptimeMillis();
11404        if ((now-startTime) > 50) {
11405            // If we are taking more than 50ms, log about it.
11406            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11407        }
11408    }
11409
11410    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11411            PROC_SPACE_TERM,
11412            PROC_SPACE_TERM|PROC_PARENS,
11413            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11414    };
11415
11416    private final long[] mProcessStateStatsLongs = new long[1];
11417
11418    boolean isProcessAliveLocked(ProcessRecord proc) {
11419        if (proc.procStatFile == null) {
11420            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11421        }
11422        mProcessStateStatsLongs[0] = 0;
11423        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11424                mProcessStateStatsLongs, null)) {
11425            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11426            return false;
11427        }
11428        final long state = mProcessStateStatsLongs[0];
11429        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11430                + (char)state);
11431        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11432    }
11433
11434    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11435            String name, IBinder token, boolean stable, int userId) {
11436        ContentProviderRecord cpr;
11437        ContentProviderConnection conn = null;
11438        ProviderInfo cpi = null;
11439
11440        synchronized(this) {
11441            long startTime = SystemClock.uptimeMillis();
11442
11443            ProcessRecord r = null;
11444            if (caller != null) {
11445                r = getRecordForAppLocked(caller);
11446                if (r == null) {
11447                    throw new SecurityException(
11448                            "Unable to find app for caller " + caller
11449                          + " (pid=" + Binder.getCallingPid()
11450                          + ") when getting content provider " + name);
11451                }
11452            }
11453
11454            boolean checkCrossUser = true;
11455
11456            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11457
11458            // First check if this content provider has been published...
11459            cpr = mProviderMap.getProviderByName(name, userId);
11460            // If that didn't work, check if it exists for user 0 and then
11461            // verify that it's a singleton provider before using it.
11462            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11463                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11464                if (cpr != null) {
11465                    cpi = cpr.info;
11466                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11467                            cpi.name, cpi.flags)
11468                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11469                        userId = UserHandle.USER_SYSTEM;
11470                        checkCrossUser = false;
11471                    } else {
11472                        cpr = null;
11473                        cpi = null;
11474                    }
11475                }
11476            }
11477
11478            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11479            if (providerRunning) {
11480                cpi = cpr.info;
11481                String msg;
11482                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11483                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11484                        != null) {
11485                    throw new SecurityException(msg);
11486                }
11487                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11488
11489                if (r != null && cpr.canRunHere(r)) {
11490                    // This provider has been published or is in the process
11491                    // of being published...  but it is also allowed to run
11492                    // in the caller's process, so don't make a connection
11493                    // and just let the caller instantiate its own instance.
11494                    ContentProviderHolder holder = cpr.newHolder(null);
11495                    // don't give caller the provider object, it needs
11496                    // to make its own.
11497                    holder.provider = null;
11498                    return holder;
11499                }
11500                // Don't expose providers between normal apps and instant apps
11501                try {
11502                    if (AppGlobals.getPackageManager()
11503                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11504                        return null;
11505                    }
11506                } catch (RemoteException e) {
11507                }
11508
11509                final long origId = Binder.clearCallingIdentity();
11510
11511                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11512
11513                // In this case the provider instance already exists, so we can
11514                // return it right away.
11515                conn = incProviderCountLocked(r, cpr, token, stable);
11516                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11517                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11518                        // If this is a perceptible app accessing the provider,
11519                        // make sure to count it as being accessed and thus
11520                        // back up on the LRU list.  This is good because
11521                        // content providers are often expensive to start.
11522                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11523                        updateLruProcessLocked(cpr.proc, false, null);
11524                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11525                    }
11526                }
11527
11528                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11529                final int verifiedAdj = cpr.proc.verifiedAdj;
11530                boolean success = updateOomAdjLocked(cpr.proc, true);
11531                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11532                // if the process has been successfully adjusted.  So to reduce races with
11533                // it, we will check whether the process still exists.  Note that this doesn't
11534                // completely get rid of races with LMK killing the process, but should make
11535                // them much smaller.
11536                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11537                    success = false;
11538                }
11539                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11540                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11541                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11542                // NOTE: there is still a race here where a signal could be
11543                // pending on the process even though we managed to update its
11544                // adj level.  Not sure what to do about this, but at least
11545                // the race is now smaller.
11546                if (!success) {
11547                    // Uh oh...  it looks like the provider's process
11548                    // has been killed on us.  We need to wait for a new
11549                    // process to be started, and make sure its death
11550                    // doesn't kill our process.
11551                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11552                            + " is crashing; detaching " + r);
11553                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11554                    checkTime(startTime, "getContentProviderImpl: before appDied");
11555                    appDiedLocked(cpr.proc);
11556                    checkTime(startTime, "getContentProviderImpl: after appDied");
11557                    if (!lastRef) {
11558                        // This wasn't the last ref our process had on
11559                        // the provider...  we have now been killed, bail.
11560                        return null;
11561                    }
11562                    providerRunning = false;
11563                    conn = null;
11564                } else {
11565                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11566                }
11567
11568                Binder.restoreCallingIdentity(origId);
11569            }
11570
11571            if (!providerRunning) {
11572                try {
11573                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11574                    cpi = AppGlobals.getPackageManager().
11575                        resolveContentProvider(name,
11576                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11577                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11578                } catch (RemoteException ex) {
11579                }
11580                if (cpi == null) {
11581                    return null;
11582                }
11583                // If the provider is a singleton AND
11584                // (it's a call within the same user || the provider is a
11585                // privileged app)
11586                // Then allow connecting to the singleton provider
11587                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11588                        cpi.name, cpi.flags)
11589                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11590                if (singleton) {
11591                    userId = UserHandle.USER_SYSTEM;
11592                }
11593                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11594                checkTime(startTime, "getContentProviderImpl: got app info for user");
11595
11596                String msg;
11597                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11598                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11599                        != null) {
11600                    throw new SecurityException(msg);
11601                }
11602                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11603
11604                if (!mProcessesReady
11605                        && !cpi.processName.equals("system")) {
11606                    // If this content provider does not run in the system
11607                    // process, and the system is not yet ready to run other
11608                    // processes, then fail fast instead of hanging.
11609                    throw new IllegalArgumentException(
11610                            "Attempt to launch content provider before system ready");
11611                }
11612
11613                // Make sure that the user who owns this provider is running.  If not,
11614                // we don't want to allow it to run.
11615                if (!mUserController.isUserRunningLocked(userId, 0)) {
11616                    Slog.w(TAG, "Unable to launch app "
11617                            + cpi.applicationInfo.packageName + "/"
11618                            + cpi.applicationInfo.uid + " for provider "
11619                            + name + ": user " + userId + " is stopped");
11620                    return null;
11621                }
11622
11623                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11624                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11625                cpr = mProviderMap.getProviderByClass(comp, userId);
11626                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11627                final boolean firstClass = cpr == null;
11628                if (firstClass) {
11629                    final long ident = Binder.clearCallingIdentity();
11630
11631                    // If permissions need a review before any of the app components can run,
11632                    // we return no provider and launch a review activity if the calling app
11633                    // is in the foreground.
11634                    if (mPermissionReviewRequired) {
11635                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11636                            return null;
11637                        }
11638                    }
11639
11640                    try {
11641                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11642                        ApplicationInfo ai =
11643                            AppGlobals.getPackageManager().
11644                                getApplicationInfo(
11645                                        cpi.applicationInfo.packageName,
11646                                        STOCK_PM_FLAGS, userId);
11647                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11648                        if (ai == null) {
11649                            Slog.w(TAG, "No package info for content provider "
11650                                    + cpi.name);
11651                            return null;
11652                        }
11653                        ai = getAppInfoForUser(ai, userId);
11654                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11655                    } catch (RemoteException ex) {
11656                        // pm is in same process, this will never happen.
11657                    } finally {
11658                        Binder.restoreCallingIdentity(ident);
11659                    }
11660                }
11661
11662                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11663
11664                if (r != null && cpr.canRunHere(r)) {
11665                    // If this is a multiprocess provider, then just return its
11666                    // info and allow the caller to instantiate it.  Only do
11667                    // this if the provider is the same user as the caller's
11668                    // process, or can run as root (so can be in any process).
11669                    return cpr.newHolder(null);
11670                }
11671
11672                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11673                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11674                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11675
11676                // This is single process, and our app is now connecting to it.
11677                // See if we are already in the process of launching this
11678                // provider.
11679                final int N = mLaunchingProviders.size();
11680                int i;
11681                for (i = 0; i < N; i++) {
11682                    if (mLaunchingProviders.get(i) == cpr) {
11683                        break;
11684                    }
11685                }
11686
11687                // If the provider is not already being launched, then get it
11688                // started.
11689                if (i >= N) {
11690                    final long origId = Binder.clearCallingIdentity();
11691
11692                    try {
11693                        // Content provider is now in use, its package can't be stopped.
11694                        try {
11695                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11696                            AppGlobals.getPackageManager().setPackageStoppedState(
11697                                    cpr.appInfo.packageName, false, userId);
11698                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11699                        } catch (RemoteException e) {
11700                        } catch (IllegalArgumentException e) {
11701                            Slog.w(TAG, "Failed trying to unstop package "
11702                                    + cpr.appInfo.packageName + ": " + e);
11703                        }
11704
11705                        // Use existing process if already started
11706                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11707                        ProcessRecord proc = getProcessRecordLocked(
11708                                cpi.processName, cpr.appInfo.uid, false);
11709                        if (proc != null && proc.thread != null && !proc.killed) {
11710                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11711                                    "Installing in existing process " + proc);
11712                            if (!proc.pubProviders.containsKey(cpi.name)) {
11713                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11714                                proc.pubProviders.put(cpi.name, cpr);
11715                                try {
11716                                    proc.thread.scheduleInstallProvider(cpi);
11717                                } catch (RemoteException e) {
11718                                }
11719                            }
11720                        } else {
11721                            checkTime(startTime, "getContentProviderImpl: before start process");
11722                            proc = startProcessLocked(cpi.processName,
11723                                    cpr.appInfo, false, 0, "content provider",
11724                                    new ComponentName(cpi.applicationInfo.packageName,
11725                                            cpi.name), false, false, false);
11726                            checkTime(startTime, "getContentProviderImpl: after start process");
11727                            if (proc == null) {
11728                                Slog.w(TAG, "Unable to launch app "
11729                                        + cpi.applicationInfo.packageName + "/"
11730                                        + cpi.applicationInfo.uid + " for provider "
11731                                        + name + ": process is bad");
11732                                return null;
11733                            }
11734                        }
11735                        cpr.launchingApp = proc;
11736                        mLaunchingProviders.add(cpr);
11737                    } finally {
11738                        Binder.restoreCallingIdentity(origId);
11739                    }
11740                }
11741
11742                checkTime(startTime, "getContentProviderImpl: updating data structures");
11743
11744                // Make sure the provider is published (the same provider class
11745                // may be published under multiple names).
11746                if (firstClass) {
11747                    mProviderMap.putProviderByClass(comp, cpr);
11748                }
11749
11750                mProviderMap.putProviderByName(name, cpr);
11751                conn = incProviderCountLocked(r, cpr, token, stable);
11752                if (conn != null) {
11753                    conn.waiting = true;
11754                }
11755            }
11756            checkTime(startTime, "getContentProviderImpl: done!");
11757
11758            grantEphemeralAccessLocked(userId, null /*intent*/,
11759                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11760        }
11761
11762        // Wait for the provider to be published...
11763        synchronized (cpr) {
11764            while (cpr.provider == null) {
11765                if (cpr.launchingApp == null) {
11766                    Slog.w(TAG, "Unable to launch app "
11767                            + cpi.applicationInfo.packageName + "/"
11768                            + cpi.applicationInfo.uid + " for provider "
11769                            + name + ": launching app became null");
11770                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11771                            UserHandle.getUserId(cpi.applicationInfo.uid),
11772                            cpi.applicationInfo.packageName,
11773                            cpi.applicationInfo.uid, name);
11774                    return null;
11775                }
11776                try {
11777                    if (DEBUG_MU) Slog.v(TAG_MU,
11778                            "Waiting to start provider " + cpr
11779                            + " launchingApp=" + cpr.launchingApp);
11780                    if (conn != null) {
11781                        conn.waiting = true;
11782                    }
11783                    cpr.wait();
11784                } catch (InterruptedException ex) {
11785                } finally {
11786                    if (conn != null) {
11787                        conn.waiting = false;
11788                    }
11789                }
11790            }
11791        }
11792        return cpr != null ? cpr.newHolder(conn) : null;
11793    }
11794
11795    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11796            ProcessRecord r, final int userId) {
11797        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11798                cpi.packageName, userId)) {
11799
11800            final boolean callerForeground = r == null || r.setSchedGroup
11801                    != ProcessList.SCHED_GROUP_BACKGROUND;
11802
11803            // Show a permission review UI only for starting from a foreground app
11804            if (!callerForeground) {
11805                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11806                        + cpi.packageName + " requires a permissions review");
11807                return false;
11808            }
11809
11810            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11811            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11812                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11813            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11814
11815            if (DEBUG_PERMISSIONS_REVIEW) {
11816                Slog.i(TAG, "u" + userId + " Launching permission review "
11817                        + "for package " + cpi.packageName);
11818            }
11819
11820            final UserHandle userHandle = new UserHandle(userId);
11821            mHandler.post(new Runnable() {
11822                @Override
11823                public void run() {
11824                    mContext.startActivityAsUser(intent, userHandle);
11825                }
11826            });
11827
11828            return false;
11829        }
11830
11831        return true;
11832    }
11833
11834    PackageManagerInternal getPackageManagerInternalLocked() {
11835        if (mPackageManagerInt == null) {
11836            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11837        }
11838        return mPackageManagerInt;
11839    }
11840
11841    @Override
11842    public final ContentProviderHolder getContentProvider(
11843            IApplicationThread caller, String name, int userId, boolean stable) {
11844        enforceNotIsolatedCaller("getContentProvider");
11845        if (caller == null) {
11846            String msg = "null IApplicationThread when getting content provider "
11847                    + name;
11848            Slog.w(TAG, msg);
11849            throw new SecurityException(msg);
11850        }
11851        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11852        // with cross-user grant.
11853        return getContentProviderImpl(caller, name, null, stable, userId);
11854    }
11855
11856    public ContentProviderHolder getContentProviderExternal(
11857            String name, int userId, IBinder token) {
11858        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11859            "Do not have permission in call getContentProviderExternal()");
11860        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11861                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11862        return getContentProviderExternalUnchecked(name, token, userId);
11863    }
11864
11865    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11866            IBinder token, int userId) {
11867        return getContentProviderImpl(null, name, token, true, userId);
11868    }
11869
11870    /**
11871     * Drop a content provider from a ProcessRecord's bookkeeping
11872     */
11873    public void removeContentProvider(IBinder connection, boolean stable) {
11874        enforceNotIsolatedCaller("removeContentProvider");
11875        long ident = Binder.clearCallingIdentity();
11876        try {
11877            synchronized (this) {
11878                ContentProviderConnection conn;
11879                try {
11880                    conn = (ContentProviderConnection)connection;
11881                } catch (ClassCastException e) {
11882                    String msg ="removeContentProvider: " + connection
11883                            + " not a ContentProviderConnection";
11884                    Slog.w(TAG, msg);
11885                    throw new IllegalArgumentException(msg);
11886                }
11887                if (conn == null) {
11888                    throw new NullPointerException("connection is null");
11889                }
11890                if (decProviderCountLocked(conn, null, null, stable)) {
11891                    updateOomAdjLocked();
11892                }
11893            }
11894        } finally {
11895            Binder.restoreCallingIdentity(ident);
11896        }
11897    }
11898
11899    public void removeContentProviderExternal(String name, IBinder token) {
11900        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11901            "Do not have permission in call removeContentProviderExternal()");
11902        int userId = UserHandle.getCallingUserId();
11903        long ident = Binder.clearCallingIdentity();
11904        try {
11905            removeContentProviderExternalUnchecked(name, token, userId);
11906        } finally {
11907            Binder.restoreCallingIdentity(ident);
11908        }
11909    }
11910
11911    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11912        synchronized (this) {
11913            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11914            if(cpr == null) {
11915                //remove from mProvidersByClass
11916                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11917                return;
11918            }
11919
11920            //update content provider record entry info
11921            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11922            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11923            if (localCpr.hasExternalProcessHandles()) {
11924                if (localCpr.removeExternalProcessHandleLocked(token)) {
11925                    updateOomAdjLocked();
11926                } else {
11927                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11928                            + " with no external reference for token: "
11929                            + token + ".");
11930                }
11931            } else {
11932                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11933                        + " with no external references.");
11934            }
11935        }
11936    }
11937
11938    public final void publishContentProviders(IApplicationThread caller,
11939            List<ContentProviderHolder> providers) {
11940        if (providers == null) {
11941            return;
11942        }
11943
11944        enforceNotIsolatedCaller("publishContentProviders");
11945        synchronized (this) {
11946            final ProcessRecord r = getRecordForAppLocked(caller);
11947            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11948            if (r == null) {
11949                throw new SecurityException(
11950                        "Unable to find app for caller " + caller
11951                      + " (pid=" + Binder.getCallingPid()
11952                      + ") when publishing content providers");
11953            }
11954
11955            final long origId = Binder.clearCallingIdentity();
11956
11957            final int N = providers.size();
11958            for (int i = 0; i < N; i++) {
11959                ContentProviderHolder src = providers.get(i);
11960                if (src == null || src.info == null || src.provider == null) {
11961                    continue;
11962                }
11963                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11964                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11965                if (dst != null) {
11966                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11967                    mProviderMap.putProviderByClass(comp, dst);
11968                    String names[] = dst.info.authority.split(";");
11969                    for (int j = 0; j < names.length; j++) {
11970                        mProviderMap.putProviderByName(names[j], dst);
11971                    }
11972
11973                    int launchingCount = mLaunchingProviders.size();
11974                    int j;
11975                    boolean wasInLaunchingProviders = false;
11976                    for (j = 0; j < launchingCount; j++) {
11977                        if (mLaunchingProviders.get(j) == dst) {
11978                            mLaunchingProviders.remove(j);
11979                            wasInLaunchingProviders = true;
11980                            j--;
11981                            launchingCount--;
11982                        }
11983                    }
11984                    if (wasInLaunchingProviders) {
11985                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11986                    }
11987                    synchronized (dst) {
11988                        dst.provider = src.provider;
11989                        dst.proc = r;
11990                        dst.notifyAll();
11991                    }
11992                    updateOomAdjLocked(r, true);
11993                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11994                            src.info.authority);
11995                }
11996            }
11997
11998            Binder.restoreCallingIdentity(origId);
11999        }
12000    }
12001
12002    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12003        ContentProviderConnection conn;
12004        try {
12005            conn = (ContentProviderConnection)connection;
12006        } catch (ClassCastException e) {
12007            String msg ="refContentProvider: " + connection
12008                    + " not a ContentProviderConnection";
12009            Slog.w(TAG, msg);
12010            throw new IllegalArgumentException(msg);
12011        }
12012        if (conn == null) {
12013            throw new NullPointerException("connection is null");
12014        }
12015
12016        synchronized (this) {
12017            if (stable > 0) {
12018                conn.numStableIncs += stable;
12019            }
12020            stable = conn.stableCount + stable;
12021            if (stable < 0) {
12022                throw new IllegalStateException("stableCount < 0: " + stable);
12023            }
12024
12025            if (unstable > 0) {
12026                conn.numUnstableIncs += unstable;
12027            }
12028            unstable = conn.unstableCount + unstable;
12029            if (unstable < 0) {
12030                throw new IllegalStateException("unstableCount < 0: " + unstable);
12031            }
12032
12033            if ((stable+unstable) <= 0) {
12034                throw new IllegalStateException("ref counts can't go to zero here: stable="
12035                        + stable + " unstable=" + unstable);
12036            }
12037            conn.stableCount = stable;
12038            conn.unstableCount = unstable;
12039            return !conn.dead;
12040        }
12041    }
12042
12043    public void unstableProviderDied(IBinder connection) {
12044        ContentProviderConnection conn;
12045        try {
12046            conn = (ContentProviderConnection)connection;
12047        } catch (ClassCastException e) {
12048            String msg ="refContentProvider: " + connection
12049                    + " not a ContentProviderConnection";
12050            Slog.w(TAG, msg);
12051            throw new IllegalArgumentException(msg);
12052        }
12053        if (conn == null) {
12054            throw new NullPointerException("connection is null");
12055        }
12056
12057        // Safely retrieve the content provider associated with the connection.
12058        IContentProvider provider;
12059        synchronized (this) {
12060            provider = conn.provider.provider;
12061        }
12062
12063        if (provider == null) {
12064            // Um, yeah, we're way ahead of you.
12065            return;
12066        }
12067
12068        // Make sure the caller is being honest with us.
12069        if (provider.asBinder().pingBinder()) {
12070            // Er, no, still looks good to us.
12071            synchronized (this) {
12072                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12073                        + " says " + conn + " died, but we don't agree");
12074                return;
12075            }
12076        }
12077
12078        // Well look at that!  It's dead!
12079        synchronized (this) {
12080            if (conn.provider.provider != provider) {
12081                // But something changed...  good enough.
12082                return;
12083            }
12084
12085            ProcessRecord proc = conn.provider.proc;
12086            if (proc == null || proc.thread == null) {
12087                // Seems like the process is already cleaned up.
12088                return;
12089            }
12090
12091            // As far as we're concerned, this is just like receiving a
12092            // death notification...  just a bit prematurely.
12093            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12094                    + ") early provider death");
12095            final long ident = Binder.clearCallingIdentity();
12096            try {
12097                appDiedLocked(proc);
12098            } finally {
12099                Binder.restoreCallingIdentity(ident);
12100            }
12101        }
12102    }
12103
12104    @Override
12105    public void appNotRespondingViaProvider(IBinder connection) {
12106        enforceCallingPermission(
12107                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12108
12109        final ContentProviderConnection conn = (ContentProviderConnection) connection;
12110        if (conn == null) {
12111            Slog.w(TAG, "ContentProviderConnection is null");
12112            return;
12113        }
12114
12115        final ProcessRecord host = conn.provider.proc;
12116        if (host == null) {
12117            Slog.w(TAG, "Failed to find hosting ProcessRecord");
12118            return;
12119        }
12120
12121        mHandler.post(new Runnable() {
12122            @Override
12123            public void run() {
12124                mAppErrors.appNotResponding(host, null, null, false,
12125                        "ContentProvider not responding");
12126            }
12127        });
12128    }
12129
12130    public final void installSystemProviders() {
12131        List<ProviderInfo> providers;
12132        synchronized (this) {
12133            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12134            providers = generateApplicationProvidersLocked(app);
12135            if (providers != null) {
12136                for (int i=providers.size()-1; i>=0; i--) {
12137                    ProviderInfo pi = (ProviderInfo)providers.get(i);
12138                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12139                        Slog.w(TAG, "Not installing system proc provider " + pi.name
12140                                + ": not system .apk");
12141                        providers.remove(i);
12142                    }
12143                }
12144            }
12145        }
12146        if (providers != null) {
12147            mSystemThread.installSystemProviders(providers);
12148        }
12149
12150        mConstants.start(mContext.getContentResolver());
12151        mCoreSettingsObserver = new CoreSettingsObserver(this);
12152        mFontScaleSettingObserver = new FontScaleSettingObserver();
12153
12154        // Now that the settings provider is published we can consider sending
12155        // in a rescue party.
12156        RescueParty.onSettingsProviderPublished(mContext);
12157
12158        //mUsageStatsService.monitorPackages();
12159    }
12160
12161    private void startPersistentApps(int matchFlags) {
12162        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12163
12164        synchronized (this) {
12165            try {
12166                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12167                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12168                for (ApplicationInfo app : apps) {
12169                    if (!"android".equals(app.packageName)) {
12170                        addAppLocked(app, null, false, null /* ABI override */);
12171                    }
12172                }
12173            } catch (RemoteException ex) {
12174            }
12175        }
12176    }
12177
12178    /**
12179     * When a user is unlocked, we need to install encryption-unaware providers
12180     * belonging to any running apps.
12181     */
12182    private void installEncryptionUnawareProviders(int userId) {
12183        // We're only interested in providers that are encryption unaware, and
12184        // we don't care about uninstalled apps, since there's no way they're
12185        // running at this point.
12186        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12187
12188        synchronized (this) {
12189            final int NP = mProcessNames.getMap().size();
12190            for (int ip = 0; ip < NP; ip++) {
12191                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12192                final int NA = apps.size();
12193                for (int ia = 0; ia < NA; ia++) {
12194                    final ProcessRecord app = apps.valueAt(ia);
12195                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12196
12197                    final int NG = app.pkgList.size();
12198                    for (int ig = 0; ig < NG; ig++) {
12199                        try {
12200                            final String pkgName = app.pkgList.keyAt(ig);
12201                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12202                                    .getPackageInfo(pkgName, matchFlags, userId);
12203                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12204                                for (ProviderInfo pi : pkgInfo.providers) {
12205                                    // TODO: keep in sync with generateApplicationProvidersLocked
12206                                    final boolean processMatch = Objects.equals(pi.processName,
12207                                            app.processName) || pi.multiprocess;
12208                                    final boolean userMatch = isSingleton(pi.processName,
12209                                            pi.applicationInfo, pi.name, pi.flags)
12210                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12211                                    if (processMatch && userMatch) {
12212                                        Log.v(TAG, "Installing " + pi);
12213                                        app.thread.scheduleInstallProvider(pi);
12214                                    } else {
12215                                        Log.v(TAG, "Skipping " + pi);
12216                                    }
12217                                }
12218                            }
12219                        } catch (RemoteException ignored) {
12220                        }
12221                    }
12222                }
12223            }
12224        }
12225    }
12226
12227    /**
12228     * Allows apps to retrieve the MIME type of a URI.
12229     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12230     * users, then it does not need permission to access the ContentProvider.
12231     * Either, it needs cross-user uri grants.
12232     *
12233     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12234     *
12235     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12236     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12237     */
12238    public String getProviderMimeType(Uri uri, int userId) {
12239        enforceNotIsolatedCaller("getProviderMimeType");
12240        final String name = uri.getAuthority();
12241        int callingUid = Binder.getCallingUid();
12242        int callingPid = Binder.getCallingPid();
12243        long ident = 0;
12244        boolean clearedIdentity = false;
12245        synchronized (this) {
12246            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12247        }
12248        if (canClearIdentity(callingPid, callingUid, userId)) {
12249            clearedIdentity = true;
12250            ident = Binder.clearCallingIdentity();
12251        }
12252        ContentProviderHolder holder = null;
12253        try {
12254            holder = getContentProviderExternalUnchecked(name, null, userId);
12255            if (holder != null) {
12256                return holder.provider.getType(uri);
12257            }
12258        } catch (RemoteException e) {
12259            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12260            return null;
12261        } catch (Exception e) {
12262            Log.w(TAG, "Exception while determining type of " + uri, e);
12263            return null;
12264        } finally {
12265            // We need to clear the identity to call removeContentProviderExternalUnchecked
12266            if (!clearedIdentity) {
12267                ident = Binder.clearCallingIdentity();
12268            }
12269            try {
12270                if (holder != null) {
12271                    removeContentProviderExternalUnchecked(name, null, userId);
12272                }
12273            } finally {
12274                Binder.restoreCallingIdentity(ident);
12275            }
12276        }
12277
12278        return null;
12279    }
12280
12281    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12282        if (UserHandle.getUserId(callingUid) == userId) {
12283            return true;
12284        }
12285        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12286                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12287                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12288                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12289                return true;
12290        }
12291        return false;
12292    }
12293
12294    // =========================================================
12295    // GLOBAL MANAGEMENT
12296    // =========================================================
12297
12298    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12299            boolean isolated, int isolatedUid) {
12300        String proc = customProcess != null ? customProcess : info.processName;
12301        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12302        final int userId = UserHandle.getUserId(info.uid);
12303        int uid = info.uid;
12304        if (isolated) {
12305            if (isolatedUid == 0) {
12306                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12307                while (true) {
12308                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12309                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12310                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12311                    }
12312                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12313                    mNextIsolatedProcessUid++;
12314                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12315                        // No process for this uid, use it.
12316                        break;
12317                    }
12318                    stepsLeft--;
12319                    if (stepsLeft <= 0) {
12320                        return null;
12321                    }
12322                }
12323            } else {
12324                // Special case for startIsolatedProcess (internal only), where
12325                // the uid of the isolated process is specified by the caller.
12326                uid = isolatedUid;
12327            }
12328            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12329
12330            // Register the isolated UID with this application so BatteryStats knows to
12331            // attribute resource usage to the application.
12332            //
12333            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12334            // about the process state of the isolated UID *before* it is registered with the
12335            // owning application.
12336            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12337        }
12338        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12339        if (!mBooted && !mBooting
12340                && userId == UserHandle.USER_SYSTEM
12341                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12342            r.persistent = true;
12343            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12344        }
12345        addProcessNameLocked(r);
12346        return r;
12347    }
12348
12349    private boolean uidOnBackgroundWhitelist(final int uid) {
12350        final int appId = UserHandle.getAppId(uid);
12351        final int[] whitelist = mBackgroundAppIdWhitelist;
12352        final int N = whitelist.length;
12353        for (int i = 0; i < N; i++) {
12354            if (appId == whitelist[i]) {
12355                return true;
12356            }
12357        }
12358        return false;
12359    }
12360
12361    @Override
12362    public void backgroundWhitelistUid(final int uid) {
12363        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12364            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12365        }
12366
12367        if (DEBUG_BACKGROUND_CHECK) {
12368            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12369        }
12370        synchronized (this) {
12371            final int N = mBackgroundAppIdWhitelist.length;
12372            int[] newList = new int[N+1];
12373            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12374            newList[N] = UserHandle.getAppId(uid);
12375            mBackgroundAppIdWhitelist = newList;
12376        }
12377    }
12378
12379    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12380            String abiOverride) {
12381        ProcessRecord app;
12382        if (!isolated) {
12383            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12384                    info.uid, true);
12385        } else {
12386            app = null;
12387        }
12388
12389        if (app == null) {
12390            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12391            updateLruProcessLocked(app, false, null);
12392            updateOomAdjLocked();
12393        }
12394
12395        // This package really, really can not be stopped.
12396        try {
12397            AppGlobals.getPackageManager().setPackageStoppedState(
12398                    info.packageName, false, UserHandle.getUserId(app.uid));
12399        } catch (RemoteException e) {
12400        } catch (IllegalArgumentException e) {
12401            Slog.w(TAG, "Failed trying to unstop package "
12402                    + info.packageName + ": " + e);
12403        }
12404
12405        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12406            app.persistent = true;
12407            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12408        }
12409        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12410            mPersistentStartingProcesses.add(app);
12411            startProcessLocked(app, "added application",
12412                    customProcess != null ? customProcess : app.processName, abiOverride,
12413                    null /* entryPoint */, null /* entryPointArgs */);
12414        }
12415
12416        return app;
12417    }
12418
12419    public void unhandledBack() {
12420        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12421                "unhandledBack()");
12422
12423        synchronized(this) {
12424            final long origId = Binder.clearCallingIdentity();
12425            try {
12426                getFocusedStack().unhandledBackLocked();
12427            } finally {
12428                Binder.restoreCallingIdentity(origId);
12429            }
12430        }
12431    }
12432
12433    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12434        enforceNotIsolatedCaller("openContentUri");
12435        final int userId = UserHandle.getCallingUserId();
12436        final Uri uri = Uri.parse(uriString);
12437        String name = uri.getAuthority();
12438        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12439        ParcelFileDescriptor pfd = null;
12440        if (cph != null) {
12441            // We record the binder invoker's uid in thread-local storage before
12442            // going to the content provider to open the file.  Later, in the code
12443            // that handles all permissions checks, we look for this uid and use
12444            // that rather than the Activity Manager's own uid.  The effect is that
12445            // we do the check against the caller's permissions even though it looks
12446            // to the content provider like the Activity Manager itself is making
12447            // the request.
12448            Binder token = new Binder();
12449            sCallerIdentity.set(new Identity(
12450                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12451            try {
12452                pfd = cph.provider.openFile(null, uri, "r", null, token);
12453            } catch (FileNotFoundException e) {
12454                // do nothing; pfd will be returned null
12455            } finally {
12456                // Ensure that whatever happens, we clean up the identity state
12457                sCallerIdentity.remove();
12458                // Ensure we're done with the provider.
12459                removeContentProviderExternalUnchecked(name, null, userId);
12460            }
12461        } else {
12462            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12463        }
12464        return pfd;
12465    }
12466
12467    // Actually is sleeping or shutting down or whatever else in the future
12468    // is an inactive state.
12469    boolean isSleepingOrShuttingDownLocked() {
12470        return isSleepingLocked() || mShuttingDown;
12471    }
12472
12473    boolean isShuttingDownLocked() {
12474        return mShuttingDown;
12475    }
12476
12477    boolean isSleepingLocked() {
12478        return mSleeping;
12479    }
12480
12481    void onWakefulnessChanged(int wakefulness) {
12482        synchronized(this) {
12483            boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12484            boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12485            mWakefulness = wakefulness;
12486
12487            if (wasAwake != isAwake) {
12488                // Also update state in a special way for running foreground services UI.
12489                mServices.updateScreenStateLocked(isAwake);
12490                sendNotifyVrManagerOfSleepState(!isAwake);
12491            }
12492        }
12493    }
12494
12495    void finishRunningVoiceLocked() {
12496        if (mRunningVoice != null) {
12497            mRunningVoice = null;
12498            mVoiceWakeLock.release();
12499            updateSleepIfNeededLocked();
12500        }
12501    }
12502
12503    void startTimeTrackingFocusedActivityLocked() {
12504        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12505        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12506            mCurAppTimeTracker.start(resumedActivity.packageName);
12507        }
12508    }
12509
12510    void updateSleepIfNeededLocked() {
12511        final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12512        final boolean wasSleeping = mSleeping;
12513
12514        if (!shouldSleep) {
12515            // If wasSleeping is true, we need to wake up activity manager state from when
12516            // we started sleeping. In either case, we need to apply the sleep tokens, which
12517            // will wake up stacks or put them to sleep as appropriate.
12518            if (wasSleeping) {
12519                mSleeping = false;
12520                startTimeTrackingFocusedActivityLocked();
12521                mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12522                mStackSupervisor.comeOutOfSleepIfNeededLocked();
12523            }
12524            mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12525            if (wasSleeping) {
12526                updateOomAdjLocked();
12527            }
12528        } else if (!mSleeping && shouldSleep) {
12529            mSleeping = true;
12530            if (mCurAppTimeTracker != null) {
12531                mCurAppTimeTracker.stop();
12532            }
12533            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12534            mStackSupervisor.goingToSleepLocked();
12535            updateOomAdjLocked();
12536        }
12537    }
12538
12539    /** Pokes the task persister. */
12540    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12541        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12542    }
12543
12544    /**
12545     * Notifies all listeners when the pinned stack animation starts.
12546     */
12547    @Override
12548    public void notifyPinnedStackAnimationStarted() {
12549        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12550    }
12551
12552    /**
12553     * Notifies all listeners when the pinned stack animation ends.
12554     */
12555    @Override
12556    public void notifyPinnedStackAnimationEnded() {
12557        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12558    }
12559
12560    @Override
12561    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12562        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12563    }
12564
12565    @Override
12566    public boolean shutdown(int timeout) {
12567        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12568                != PackageManager.PERMISSION_GRANTED) {
12569            throw new SecurityException("Requires permission "
12570                    + android.Manifest.permission.SHUTDOWN);
12571        }
12572
12573        boolean timedout = false;
12574
12575        synchronized(this) {
12576            mShuttingDown = true;
12577            mStackSupervisor.prepareForShutdownLocked();
12578            updateEventDispatchingLocked();
12579            timedout = mStackSupervisor.shutdownLocked(timeout);
12580        }
12581
12582        mAppOpsService.shutdown();
12583        if (mUsageStatsService != null) {
12584            mUsageStatsService.prepareShutdown();
12585        }
12586        mBatteryStatsService.shutdown();
12587        synchronized (this) {
12588            mProcessStats.shutdownLocked();
12589            notifyTaskPersisterLocked(null, true);
12590        }
12591
12592        return timedout;
12593    }
12594
12595    public final void activitySlept(IBinder token) {
12596        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12597
12598        final long origId = Binder.clearCallingIdentity();
12599
12600        synchronized (this) {
12601            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12602            if (r != null) {
12603                mStackSupervisor.activitySleptLocked(r);
12604            }
12605        }
12606
12607        Binder.restoreCallingIdentity(origId);
12608    }
12609
12610    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12611        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12612        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12613        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12614            boolean wasRunningVoice = mRunningVoice != null;
12615            mRunningVoice = session;
12616            if (!wasRunningVoice) {
12617                mVoiceWakeLock.acquire();
12618                updateSleepIfNeededLocked();
12619            }
12620        }
12621    }
12622
12623    private void updateEventDispatchingLocked() {
12624        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12625    }
12626
12627    @Override
12628    public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12629        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12630                != PackageManager.PERMISSION_GRANTED) {
12631            throw new SecurityException("Requires permission "
12632                    + android.Manifest.permission.DEVICE_POWER);
12633        }
12634
12635        synchronized(this) {
12636            long ident = Binder.clearCallingIdentity();
12637            try {
12638                mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12639            } finally {
12640                Binder.restoreCallingIdentity(ident);
12641            }
12642        }
12643        sendNotifyVrManagerOfKeyguardState(showing);
12644    }
12645
12646    @Override
12647    public void notifyLockedProfile(@UserIdInt int userId) {
12648        try {
12649            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12650                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12651            }
12652        } catch (RemoteException ex) {
12653            throw new SecurityException("Fail to check is caller a privileged app", ex);
12654        }
12655
12656        synchronized (this) {
12657            final long ident = Binder.clearCallingIdentity();
12658            try {
12659                if (mUserController.shouldConfirmCredentials(userId)) {
12660                    if (mKeyguardController.isKeyguardLocked()) {
12661                        // Showing launcher to avoid user entering credential twice.
12662                        final int currentUserId = mUserController.getCurrentUserIdLocked();
12663                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12664                    }
12665                    mStackSupervisor.lockAllProfileTasks(userId);
12666                }
12667            } finally {
12668                Binder.restoreCallingIdentity(ident);
12669            }
12670        }
12671    }
12672
12673    @Override
12674    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12675        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12676        synchronized (this) {
12677            final long ident = Binder.clearCallingIdentity();
12678            try {
12679                mActivityStarter.startConfirmCredentialIntent(intent, options);
12680            } finally {
12681                Binder.restoreCallingIdentity(ident);
12682            }
12683        }
12684    }
12685
12686    @Override
12687    public void stopAppSwitches() {
12688        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12689                != PackageManager.PERMISSION_GRANTED) {
12690            throw new SecurityException("viewquires permission "
12691                    + android.Manifest.permission.STOP_APP_SWITCHES);
12692        }
12693
12694        synchronized(this) {
12695            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12696                    + APP_SWITCH_DELAY_TIME;
12697            mDidAppSwitch = false;
12698            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12699            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12700            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12701        }
12702    }
12703
12704    public void resumeAppSwitches() {
12705        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12706                != PackageManager.PERMISSION_GRANTED) {
12707            throw new SecurityException("Requires permission "
12708                    + android.Manifest.permission.STOP_APP_SWITCHES);
12709        }
12710
12711        synchronized(this) {
12712            // Note that we don't execute any pending app switches... we will
12713            // let those wait until either the timeout, or the next start
12714            // activity request.
12715            mAppSwitchesAllowedTime = 0;
12716        }
12717    }
12718
12719    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12720            int callingPid, int callingUid, String name) {
12721        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12722            return true;
12723        }
12724
12725        int perm = checkComponentPermission(
12726                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12727                sourceUid, -1, true);
12728        if (perm == PackageManager.PERMISSION_GRANTED) {
12729            return true;
12730        }
12731
12732        // If the actual IPC caller is different from the logical source, then
12733        // also see if they are allowed to control app switches.
12734        if (callingUid != -1 && callingUid != sourceUid) {
12735            perm = checkComponentPermission(
12736                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12737                    callingUid, -1, true);
12738            if (perm == PackageManager.PERMISSION_GRANTED) {
12739                return true;
12740            }
12741        }
12742
12743        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12744        return false;
12745    }
12746
12747    public void setDebugApp(String packageName, boolean waitForDebugger,
12748            boolean persistent) {
12749        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12750                "setDebugApp()");
12751
12752        long ident = Binder.clearCallingIdentity();
12753        try {
12754            // Note that this is not really thread safe if there are multiple
12755            // callers into it at the same time, but that's not a situation we
12756            // care about.
12757            if (persistent) {
12758                final ContentResolver resolver = mContext.getContentResolver();
12759                Settings.Global.putString(
12760                    resolver, Settings.Global.DEBUG_APP,
12761                    packageName);
12762                Settings.Global.putInt(
12763                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12764                    waitForDebugger ? 1 : 0);
12765            }
12766
12767            synchronized (this) {
12768                if (!persistent) {
12769                    mOrigDebugApp = mDebugApp;
12770                    mOrigWaitForDebugger = mWaitForDebugger;
12771                }
12772                mDebugApp = packageName;
12773                mWaitForDebugger = waitForDebugger;
12774                mDebugTransient = !persistent;
12775                if (packageName != null) {
12776                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12777                            false, UserHandle.USER_ALL, "set debug app");
12778                }
12779            }
12780        } finally {
12781            Binder.restoreCallingIdentity(ident);
12782        }
12783    }
12784
12785    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12786        synchronized (this) {
12787            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12788            if (!isDebuggable) {
12789                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12790                    throw new SecurityException("Process not debuggable: " + app.packageName);
12791                }
12792            }
12793
12794            mTrackAllocationApp = processName;
12795        }
12796    }
12797
12798    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12799        synchronized (this) {
12800            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12801            if (!isDebuggable) {
12802                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12803                    throw new SecurityException("Process not debuggable: " + app.packageName);
12804                }
12805            }
12806            mProfileApp = processName;
12807
12808            if (mProfilerInfo != null) {
12809                if (mProfilerInfo.profileFd != null) {
12810                    try {
12811                        mProfilerInfo.profileFd.close();
12812                    } catch (IOException e) {
12813                    }
12814                }
12815            }
12816            mProfilerInfo = new ProfilerInfo(profilerInfo);
12817            mProfileType = 0;
12818        }
12819    }
12820
12821    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12822        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12823        if (!isDebuggable) {
12824            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12825                throw new SecurityException("Process not debuggable: " + app.packageName);
12826            }
12827        }
12828        mNativeDebuggingApp = processName;
12829    }
12830
12831    @Override
12832    public void setAlwaysFinish(boolean enabled) {
12833        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12834                "setAlwaysFinish()");
12835
12836        long ident = Binder.clearCallingIdentity();
12837        try {
12838            Settings.Global.putInt(
12839                    mContext.getContentResolver(),
12840                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12841
12842            synchronized (this) {
12843                mAlwaysFinishActivities = enabled;
12844            }
12845        } finally {
12846            Binder.restoreCallingIdentity(ident);
12847        }
12848    }
12849
12850    @Override
12851    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12852        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12853                "setActivityController()");
12854        synchronized (this) {
12855            mController = controller;
12856            mControllerIsAMonkey = imAMonkey;
12857            Watchdog.getInstance().setActivityController(controller);
12858        }
12859    }
12860
12861    @Override
12862    public void setUserIsMonkey(boolean userIsMonkey) {
12863        synchronized (this) {
12864            synchronized (mPidsSelfLocked) {
12865                final int callingPid = Binder.getCallingPid();
12866                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12867                if (proc == null) {
12868                    throw new SecurityException("Unknown process: " + callingPid);
12869                }
12870                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12871                    throw new SecurityException("Only an instrumentation process "
12872                            + "with a UiAutomation can call setUserIsMonkey");
12873                }
12874            }
12875            mUserIsMonkey = userIsMonkey;
12876        }
12877    }
12878
12879    @Override
12880    public boolean isUserAMonkey() {
12881        synchronized (this) {
12882            // If there is a controller also implies the user is a monkey.
12883            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12884        }
12885    }
12886
12887    /**
12888     * @deprecated This method is only used by a few internal components and it will soon be
12889     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12890     * No new code should be calling it.
12891     */
12892    @Deprecated
12893    @Override
12894    public void requestBugReport(int bugreportType) {
12895        String extraOptions = null;
12896        switch (bugreportType) {
12897            case ActivityManager.BUGREPORT_OPTION_FULL:
12898                // Default options.
12899                break;
12900            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12901                extraOptions = "bugreportplus";
12902                break;
12903            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12904                extraOptions = "bugreportremote";
12905                break;
12906            case ActivityManager.BUGREPORT_OPTION_WEAR:
12907                extraOptions = "bugreportwear";
12908                break;
12909            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12910                extraOptions = "bugreporttelephony";
12911                break;
12912            default:
12913                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12914                        + bugreportType);
12915        }
12916        // Always log caller, even if it does not have permission to dump.
12917        String type = extraOptions == null ? "bugreport" : extraOptions;
12918        Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12919
12920        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12921        if (extraOptions != null) {
12922            SystemProperties.set("dumpstate.options", extraOptions);
12923        }
12924        SystemProperties.set("ctl.start", "bugreport");
12925    }
12926
12927    /**
12928     * @deprecated This method is only used by a few internal components and it will soon be
12929     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12930     * No new code should be calling it.
12931     */
12932    @Deprecated
12933    @Override
12934    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12935
12936        if (!TextUtils.isEmpty(shareTitle)) {
12937            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12938                String errorStr = "shareTitle should be less than " +
12939                        MAX_BUGREPORT_TITLE_SIZE + " characters";
12940                throw new IllegalArgumentException(errorStr);
12941            } else {
12942                if (!TextUtils.isEmpty(shareDescription)) {
12943                    int length;
12944                    try {
12945                        length = shareDescription.getBytes("UTF-8").length;
12946                    } catch (UnsupportedEncodingException e) {
12947                        String errorStr = "shareDescription: UnsupportedEncodingException";
12948                        throw new IllegalArgumentException(errorStr);
12949                    }
12950                    if (length > SystemProperties.PROP_VALUE_MAX) {
12951                        String errorStr = "shareTitle should be less than " +
12952                                SystemProperties.PROP_VALUE_MAX + " bytes";
12953                        throw new IllegalArgumentException(errorStr);
12954                    } else {
12955                        SystemProperties.set("dumpstate.options.description", shareDescription);
12956                    }
12957                }
12958                SystemProperties.set("dumpstate.options.title", shareTitle);
12959            }
12960        }
12961
12962        Slog.d(TAG, "Bugreport notification title " + shareTitle
12963                + " description " + shareDescription);
12964        requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12965    }
12966
12967    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12968        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12969    }
12970
12971    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12972        if (r != null && (r.instr != null || r.usingWrapper)) {
12973            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12974        }
12975        return KEY_DISPATCHING_TIMEOUT;
12976    }
12977
12978    @Override
12979    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12980        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12981                != PackageManager.PERMISSION_GRANTED) {
12982            throw new SecurityException("Requires permission "
12983                    + android.Manifest.permission.FILTER_EVENTS);
12984        }
12985        ProcessRecord proc;
12986        long timeout;
12987        synchronized (this) {
12988            synchronized (mPidsSelfLocked) {
12989                proc = mPidsSelfLocked.get(pid);
12990            }
12991            timeout = getInputDispatchingTimeoutLocked(proc);
12992        }
12993
12994        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12995            return -1;
12996        }
12997
12998        return timeout;
12999    }
13000
13001    /**
13002     * Handle input dispatching timeouts.
13003     * Returns whether input dispatching should be aborted or not.
13004     */
13005    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13006            final ActivityRecord activity, final ActivityRecord parent,
13007            final boolean aboveSystem, String reason) {
13008        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13009                != PackageManager.PERMISSION_GRANTED) {
13010            throw new SecurityException("Requires permission "
13011                    + android.Manifest.permission.FILTER_EVENTS);
13012        }
13013
13014        final String annotation;
13015        if (reason == null) {
13016            annotation = "Input dispatching timed out";
13017        } else {
13018            annotation = "Input dispatching timed out (" + reason + ")";
13019        }
13020
13021        if (proc != null) {
13022            synchronized (this) {
13023                if (proc.debugging) {
13024                    return false;
13025                }
13026
13027                if (proc.instr != null) {
13028                    Bundle info = new Bundle();
13029                    info.putString("shortMsg", "keyDispatchingTimedOut");
13030                    info.putString("longMsg", annotation);
13031                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13032                    return true;
13033                }
13034            }
13035            mHandler.post(new Runnable() {
13036                @Override
13037                public void run() {
13038                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13039                }
13040            });
13041        }
13042
13043        return true;
13044    }
13045
13046    @Override
13047    public Bundle getAssistContextExtras(int requestType) {
13048        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13049                null, null, true /* focused */, true /* newSessionId */,
13050                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13051        if (pae == null) {
13052            return null;
13053        }
13054        synchronized (pae) {
13055            while (!pae.haveResult) {
13056                try {
13057                    pae.wait();
13058                } catch (InterruptedException e) {
13059                }
13060            }
13061        }
13062        synchronized (this) {
13063            buildAssistBundleLocked(pae, pae.result);
13064            mPendingAssistExtras.remove(pae);
13065            mUiHandler.removeCallbacks(pae);
13066        }
13067        return pae.extras;
13068    }
13069
13070    @Override
13071    public boolean isAssistDataAllowedOnCurrentActivity() {
13072        int userId;
13073        synchronized (this) {
13074            final ActivityStack focusedStack = getFocusedStack();
13075            if (focusedStack == null || focusedStack.isAssistantStack()) {
13076                return false;
13077            }
13078
13079            final ActivityRecord activity = focusedStack.topActivity();
13080            if (activity == null) {
13081                return false;
13082            }
13083            userId = activity.userId;
13084        }
13085        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13086                Context.DEVICE_POLICY_SERVICE);
13087        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13088    }
13089
13090    @Override
13091    public boolean showAssistFromActivity(IBinder token, Bundle args) {
13092        long ident = Binder.clearCallingIdentity();
13093        try {
13094            synchronized (this) {
13095                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13096                ActivityRecord top = getFocusedStack().topActivity();
13097                if (top != caller) {
13098                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13099                            + " is not current top " + top);
13100                    return false;
13101                }
13102                if (!top.nowVisible) {
13103                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13104                            + " is not visible");
13105                    return false;
13106                }
13107            }
13108            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13109                    token);
13110        } finally {
13111            Binder.restoreCallingIdentity(ident);
13112        }
13113    }
13114
13115    @Override
13116    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13117            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13118        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13119                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13120                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13121    }
13122
13123    @Override
13124    public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13125            IBinder activityToken, int flags) {
13126        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13127                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13128                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13129    }
13130
13131    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13132            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13133            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13134            int flags) {
13135        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13136                "enqueueAssistContext()");
13137
13138        synchronized (this) {
13139            ActivityRecord activity = getFocusedStack().topActivity();
13140            if (activity == null) {
13141                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13142                return null;
13143            }
13144            if (activity.app == null || activity.app.thread == null) {
13145                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13146                return null;
13147            }
13148            if (focused) {
13149                if (activityToken != null) {
13150                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13151                    if (activity != caller) {
13152                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13153                                + " is not current top " + activity);
13154                        return null;
13155                    }
13156                }
13157            } else {
13158                activity = ActivityRecord.forTokenLocked(activityToken);
13159                if (activity == null) {
13160                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13161                            + " couldn't be found");
13162                    return null;
13163                }
13164                if (activity.app == null || activity.app.thread == null) {
13165                    Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13166                    return null;
13167                }
13168            }
13169
13170            PendingAssistExtras pae;
13171            Bundle extras = new Bundle();
13172            if (args != null) {
13173                extras.putAll(args);
13174            }
13175            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13176            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13177
13178            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13179                    userHandle);
13180            pae.isHome = activity.isHomeActivity();
13181
13182            // Increment the sessionId if necessary
13183            if (newSessionId) {
13184                mViSessionId++;
13185            }
13186            try {
13187                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13188                        mViSessionId, flags);
13189                mPendingAssistExtras.add(pae);
13190                mUiHandler.postDelayed(pae, timeout);
13191            } catch (RemoteException e) {
13192                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13193                return null;
13194            }
13195            return pae;
13196        }
13197    }
13198
13199    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13200        IResultReceiver receiver;
13201        synchronized (this) {
13202            mPendingAssistExtras.remove(pae);
13203            receiver = pae.receiver;
13204        }
13205        if (receiver != null) {
13206            // Caller wants result sent back to them.
13207            Bundle sendBundle = new Bundle();
13208            // At least return the receiver extras
13209            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13210                    pae.receiverExtras);
13211            try {
13212                pae.receiver.send(0, sendBundle);
13213            } catch (RemoteException e) {
13214            }
13215        }
13216    }
13217
13218    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13219        if (result != null) {
13220            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13221        }
13222        if (pae.hint != null) {
13223            pae.extras.putBoolean(pae.hint, true);
13224        }
13225    }
13226
13227    /** Called from an app when assist data is ready. */
13228    @Override
13229    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13230            AssistContent content, Uri referrer) {
13231        PendingAssistExtras pae = (PendingAssistExtras)token;
13232        synchronized (pae) {
13233            pae.result = extras;
13234            pae.structure = structure;
13235            pae.content = content;
13236            if (referrer != null) {
13237                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13238            }
13239            if (structure != null) {
13240                structure.setHomeActivity(pae.isHome);
13241            }
13242            pae.haveResult = true;
13243            pae.notifyAll();
13244            if (pae.intent == null && pae.receiver == null) {
13245                // Caller is just waiting for the result.
13246                return;
13247            }
13248        }
13249        // We are now ready to launch the assist activity.
13250        IResultReceiver sendReceiver = null;
13251        Bundle sendBundle = null;
13252        synchronized (this) {
13253            buildAssistBundleLocked(pae, extras);
13254            boolean exists = mPendingAssistExtras.remove(pae);
13255            mUiHandler.removeCallbacks(pae);
13256            if (!exists) {
13257                // Timed out.
13258                return;
13259            }
13260            if ((sendReceiver=pae.receiver) != null) {
13261                // Caller wants result sent back to them.
13262                sendBundle = new Bundle();
13263                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13264                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13265                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13266                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13267                        pae.receiverExtras);
13268            }
13269        }
13270        if (sendReceiver != null) {
13271            try {
13272                sendReceiver.send(0, sendBundle);
13273            } catch (RemoteException e) {
13274            }
13275            return;
13276        }
13277
13278        final long ident = Binder.clearCallingIdentity();
13279        try {
13280            if (TextUtils.equals(pae.intent.getAction(),
13281                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13282                pae.intent.putExtras(pae.extras);
13283                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13284            } else {
13285                pae.intent.replaceExtras(pae.extras);
13286                pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13287                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
13288                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13289                closeSystemDialogs("assist");
13290
13291                try {
13292                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13293                } catch (ActivityNotFoundException e) {
13294                    Slog.w(TAG, "No activity to handle assist action.", e);
13295                }
13296            }
13297        } finally {
13298            Binder.restoreCallingIdentity(ident);
13299        }
13300    }
13301
13302    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13303            Bundle args) {
13304        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13305                true /* focused */, true /* newSessionId */, userHandle, args,
13306                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13307    }
13308
13309    public void registerProcessObserver(IProcessObserver observer) {
13310        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13311                "registerProcessObserver()");
13312        synchronized (this) {
13313            mProcessObservers.register(observer);
13314        }
13315    }
13316
13317    @Override
13318    public void unregisterProcessObserver(IProcessObserver observer) {
13319        synchronized (this) {
13320            mProcessObservers.unregister(observer);
13321        }
13322    }
13323
13324    @Override
13325    public int getUidProcessState(int uid, String callingPackage) {
13326        if (!hasUsageStatsPermission(callingPackage)) {
13327            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13328                    "getUidProcessState");
13329        }
13330
13331        synchronized (this) {
13332            UidRecord uidRec = mActiveUids.get(uid);
13333            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13334        }
13335    }
13336
13337    @Override
13338    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13339            String callingPackage) {
13340        if (!hasUsageStatsPermission(callingPackage)) {
13341            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13342                    "registerUidObserver");
13343        }
13344        synchronized (this) {
13345            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13346                    callingPackage, which, cutpoint));
13347        }
13348    }
13349
13350    @Override
13351    public void unregisterUidObserver(IUidObserver observer) {
13352        synchronized (this) {
13353            mUidObservers.unregister(observer);
13354        }
13355    }
13356
13357    @Override
13358    public boolean convertFromTranslucent(IBinder token) {
13359        final long origId = Binder.clearCallingIdentity();
13360        try {
13361            synchronized (this) {
13362                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13363                if (r == null) {
13364                    return false;
13365                }
13366                final boolean translucentChanged = r.changeWindowTranslucency(true);
13367                if (translucentChanged) {
13368                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13369                }
13370                mWindowManager.setAppFullscreen(token, true);
13371                return translucentChanged;
13372            }
13373        } finally {
13374            Binder.restoreCallingIdentity(origId);
13375        }
13376    }
13377
13378    @Override
13379    public boolean convertToTranslucent(IBinder token, Bundle options) {
13380        final long origId = Binder.clearCallingIdentity();
13381        try {
13382            synchronized (this) {
13383                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13384                if (r == null) {
13385                    return false;
13386                }
13387                final TaskRecord task = r.getTask();
13388                int index = task.mActivities.lastIndexOf(r);
13389                if (index > 0) {
13390                    ActivityRecord under = task.mActivities.get(index - 1);
13391                    under.returningOptions = ActivityOptions.fromBundle(options);
13392                }
13393                final boolean translucentChanged = r.changeWindowTranslucency(false);
13394                if (translucentChanged) {
13395                    r.getStack().convertActivityToTranslucent(r);
13396                }
13397                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13398                mWindowManager.setAppFullscreen(token, false);
13399                return translucentChanged;
13400            }
13401        } finally {
13402            Binder.restoreCallingIdentity(origId);
13403        }
13404    }
13405
13406    @Override
13407    public Bundle getActivityOptions(IBinder token) {
13408        final long origId = Binder.clearCallingIdentity();
13409        try {
13410            synchronized (this) {
13411                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13412                if (r != null) {
13413                    final ActivityOptions activityOptions = r.takeOptionsLocked();
13414                    return activityOptions == null ? null : activityOptions.toBundle();
13415                }
13416                return null;
13417            }
13418        } finally {
13419            Binder.restoreCallingIdentity(origId);
13420        }
13421    }
13422
13423    @Override
13424    public void setImmersive(IBinder token, boolean immersive) {
13425        synchronized(this) {
13426            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13427            if (r == null) {
13428                throw new IllegalArgumentException();
13429            }
13430            r.immersive = immersive;
13431
13432            // update associated state if we're frontmost
13433            if (r == mStackSupervisor.getResumedActivityLocked()) {
13434                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13435                applyUpdateLockStateLocked(r);
13436            }
13437        }
13438    }
13439
13440    @Override
13441    public boolean isImmersive(IBinder token) {
13442        synchronized (this) {
13443            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13444            if (r == null) {
13445                throw new IllegalArgumentException();
13446            }
13447            return r.immersive;
13448        }
13449    }
13450
13451    @Override
13452    public void setVrThread(int tid) {
13453        enforceSystemHasVrFeature();
13454        synchronized (this) {
13455            synchronized (mPidsSelfLocked) {
13456                final int pid = Binder.getCallingPid();
13457                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13458                mVrController.setVrThreadLocked(tid, pid, proc);
13459            }
13460        }
13461    }
13462
13463    @Override
13464    public void setPersistentVrThread(int tid) {
13465        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13466            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13467                    + Binder.getCallingPid()
13468                    + ", uid=" + Binder.getCallingUid()
13469                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13470            Slog.w(TAG, msg);
13471            throw new SecurityException(msg);
13472        }
13473        enforceSystemHasVrFeature();
13474        synchronized (this) {
13475            synchronized (mPidsSelfLocked) {
13476                final int pid = Binder.getCallingPid();
13477                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13478                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13479            }
13480        }
13481    }
13482
13483    /**
13484     * Schedule the given thread a normal scheduling priority.
13485     *
13486     * @param tid the tid of the thread to adjust the scheduling of.
13487     * @param suppressLogs {@code true} if any error logging should be disabled.
13488     *
13489     * @return {@code true} if this succeeded.
13490     */
13491    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13492        try {
13493            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13494            return true;
13495        } catch (IllegalArgumentException e) {
13496            if (!suppressLogs) {
13497                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13498            }
13499        } catch (SecurityException e) {
13500            if (!suppressLogs) {
13501                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13502            }
13503        }
13504        return false;
13505    }
13506
13507    /**
13508     * Schedule the given thread an FIFO scheduling priority.
13509     *
13510     * @param tid the tid of the thread to adjust the scheduling of.
13511     * @param suppressLogs {@code true} if any error logging should be disabled.
13512     *
13513     * @return {@code true} if this succeeded.
13514     */
13515    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13516        try {
13517            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13518            return true;
13519        } catch (IllegalArgumentException e) {
13520            if (!suppressLogs) {
13521                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13522            }
13523        } catch (SecurityException e) {
13524            if (!suppressLogs) {
13525                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13526            }
13527        }
13528        return false;
13529    }
13530
13531    /**
13532     * Check that we have the features required for VR-related API calls, and throw an exception if
13533     * not.
13534     */
13535    private void enforceSystemHasVrFeature() {
13536        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13537            throw new UnsupportedOperationException("VR mode not supported on this device!");
13538        }
13539    }
13540
13541    @Override
13542    public void setRenderThread(int tid) {
13543        synchronized (this) {
13544            ProcessRecord proc;
13545            int pid = Binder.getCallingPid();
13546            if (pid == Process.myPid()) {
13547                demoteSystemServerRenderThread(tid);
13548                return;
13549            }
13550            synchronized (mPidsSelfLocked) {
13551                proc = mPidsSelfLocked.get(pid);
13552                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13553                    // ensure the tid belongs to the process
13554                    if (!isThreadInProcess(pid, tid)) {
13555                        throw new IllegalArgumentException(
13556                            "Render thread does not belong to process");
13557                    }
13558                    proc.renderThreadTid = tid;
13559                    if (DEBUG_OOM_ADJ) {
13560                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13561                    }
13562                    // promote to FIFO now
13563                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13564                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13565                        if (mUseFifoUiScheduling) {
13566                            setThreadScheduler(proc.renderThreadTid,
13567                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13568                        } else {
13569                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13570                        }
13571                    }
13572                } else {
13573                    if (DEBUG_OOM_ADJ) {
13574                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13575                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13576                               mUseFifoUiScheduling);
13577                    }
13578                }
13579            }
13580        }
13581    }
13582
13583    /**
13584     * We only use RenderThread in system_server to store task snapshots to the disk, which should
13585     * happen in the background. Thus, demote render thread from system_server to a lower priority.
13586     *
13587     * @param tid the tid of the RenderThread
13588     */
13589    private void demoteSystemServerRenderThread(int tid) {
13590        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13591    }
13592
13593    @Override
13594    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13595        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13596            throw new UnsupportedOperationException("VR mode not supported on this device!");
13597        }
13598
13599        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13600
13601        ActivityRecord r;
13602        synchronized (this) {
13603            r = ActivityRecord.isInStackLocked(token);
13604        }
13605
13606        if (r == null) {
13607            throw new IllegalArgumentException();
13608        }
13609
13610        int err;
13611        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13612                VrManagerInternal.NO_ERROR) {
13613            return err;
13614        }
13615
13616        synchronized(this) {
13617            r.requestedVrComponent = (enabled) ? packageName : null;
13618
13619            // Update associated state if this activity is currently focused
13620            if (r == mStackSupervisor.getResumedActivityLocked()) {
13621                applyUpdateVrModeLocked(r);
13622            }
13623            return 0;
13624        }
13625    }
13626
13627    @Override
13628    public boolean isVrModePackageEnabled(ComponentName packageName) {
13629        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13630            throw new UnsupportedOperationException("VR mode not supported on this device!");
13631        }
13632
13633        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13634
13635        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13636                VrManagerInternal.NO_ERROR;
13637    }
13638
13639    public boolean isTopActivityImmersive() {
13640        enforceNotIsolatedCaller("startActivity");
13641        synchronized (this) {
13642            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13643            return (r != null) ? r.immersive : false;
13644        }
13645    }
13646
13647    /**
13648     * @return whether the system should disable UI modes incompatible with VR mode.
13649     */
13650    boolean shouldDisableNonVrUiLocked() {
13651        return mVrController.shouldDisableNonVrUiLocked();
13652    }
13653
13654    @Override
13655    public boolean isTopOfTask(IBinder token) {
13656        synchronized (this) {
13657            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13658            if (r == null) {
13659                throw new IllegalArgumentException();
13660            }
13661            return r.getTask().getTopActivity() == r;
13662        }
13663    }
13664
13665    @Override
13666    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13667        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13668            String msg = "Permission Denial: setHasTopUi() from pid="
13669                    + Binder.getCallingPid()
13670                    + ", uid=" + Binder.getCallingUid()
13671                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13672            Slog.w(TAG, msg);
13673            throw new SecurityException(msg);
13674        }
13675        final int pid = Binder.getCallingPid();
13676        final long origId = Binder.clearCallingIdentity();
13677        try {
13678            synchronized (this) {
13679                boolean changed = false;
13680                ProcessRecord pr;
13681                synchronized (mPidsSelfLocked) {
13682                    pr = mPidsSelfLocked.get(pid);
13683                    if (pr == null) {
13684                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13685                        return;
13686                    }
13687                    if (pr.hasTopUi != hasTopUi) {
13688                        if (DEBUG_OOM_ADJ) {
13689                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13690                        }
13691                        pr.hasTopUi = hasTopUi;
13692                        changed = true;
13693                    }
13694                }
13695                if (changed) {
13696                    updateOomAdjLocked(pr, true);
13697                }
13698            }
13699        } finally {
13700            Binder.restoreCallingIdentity(origId);
13701        }
13702    }
13703
13704    public final void enterSafeMode() {
13705        synchronized(this) {
13706            // It only makes sense to do this before the system is ready
13707            // and started launching other packages.
13708            if (!mSystemReady) {
13709                try {
13710                    AppGlobals.getPackageManager().enterSafeMode();
13711                } catch (RemoteException e) {
13712                }
13713            }
13714
13715            mSafeMode = true;
13716        }
13717    }
13718
13719    public final void showSafeModeOverlay() {
13720        View v = LayoutInflater.from(mContext).inflate(
13721                com.android.internal.R.layout.safe_mode, null);
13722        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13723        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13724        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13725        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13726        lp.gravity = Gravity.BOTTOM | Gravity.START;
13727        lp.format = v.getBackground().getOpacity();
13728        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13729                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13730        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13731        ((WindowManager)mContext.getSystemService(
13732                Context.WINDOW_SERVICE)).addView(v, lp);
13733    }
13734
13735    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13736        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13737            return;
13738        }
13739        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13740        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13741        synchronized (stats) {
13742            if (mBatteryStatsService.isOnBattery()) {
13743                mBatteryStatsService.enforceCallingPermission();
13744                int MY_UID = Binder.getCallingUid();
13745                final int uid;
13746                if (sender == null) {
13747                    uid = sourceUid;
13748                } else {
13749                    uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13750                }
13751                BatteryStatsImpl.Uid.Pkg pkg =
13752                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13753                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13754                pkg.noteWakeupAlarmLocked(tag);
13755            }
13756        }
13757    }
13758
13759    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13760        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13761            return;
13762        }
13763        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13764        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13765        synchronized (stats) {
13766            mBatteryStatsService.enforceCallingPermission();
13767            int MY_UID = Binder.getCallingUid();
13768            final int uid;
13769            if (sender == null) {
13770                uid = sourceUid;
13771            } else {
13772                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13773            }
13774            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13775        }
13776    }
13777
13778    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13779        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13780            return;
13781        }
13782        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13783        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13784        synchronized (stats) {
13785            mBatteryStatsService.enforceCallingPermission();
13786            int MY_UID = Binder.getCallingUid();
13787            final int uid;
13788            if (sender == null) {
13789                uid = sourceUid;
13790            } else {
13791                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13792            }
13793            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13794        }
13795    }
13796
13797    public boolean killPids(int[] pids, String pReason, boolean secure) {
13798        if (Binder.getCallingUid() != SYSTEM_UID) {
13799            throw new SecurityException("killPids only available to the system");
13800        }
13801        String reason = (pReason == null) ? "Unknown" : pReason;
13802        // XXX Note: don't acquire main activity lock here, because the window
13803        // manager calls in with its locks held.
13804
13805        boolean killed = false;
13806        synchronized (mPidsSelfLocked) {
13807            int worstType = 0;
13808            for (int i=0; i<pids.length; i++) {
13809                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13810                if (proc != null) {
13811                    int type = proc.setAdj;
13812                    if (type > worstType) {
13813                        worstType = type;
13814                    }
13815                }
13816            }
13817
13818            // If the worst oom_adj is somewhere in the cached proc LRU range,
13819            // then constrain it so we will kill all cached procs.
13820            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13821                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13822                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13823            }
13824
13825            // If this is not a secure call, don't let it kill processes that
13826            // are important.
13827            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13828                worstType = ProcessList.SERVICE_ADJ;
13829            }
13830
13831            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13832            for (int i=0; i<pids.length; i++) {
13833                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13834                if (proc == null) {
13835                    continue;
13836                }
13837                int adj = proc.setAdj;
13838                if (adj >= worstType && !proc.killedByAm) {
13839                    proc.kill(reason, true);
13840                    killed = true;
13841                }
13842            }
13843        }
13844        return killed;
13845    }
13846
13847    @Override
13848    public void killUid(int appId, int userId, String reason) {
13849        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13850        synchronized (this) {
13851            final long identity = Binder.clearCallingIdentity();
13852            try {
13853                killPackageProcessesLocked(null, appId, userId,
13854                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13855                        reason != null ? reason : "kill uid");
13856            } finally {
13857                Binder.restoreCallingIdentity(identity);
13858            }
13859        }
13860    }
13861
13862    @Override
13863    public boolean killProcessesBelowForeground(String reason) {
13864        if (Binder.getCallingUid() != SYSTEM_UID) {
13865            throw new SecurityException("killProcessesBelowForeground() only available to system");
13866        }
13867
13868        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13869    }
13870
13871    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13872        if (Binder.getCallingUid() != SYSTEM_UID) {
13873            throw new SecurityException("killProcessesBelowAdj() only available to system");
13874        }
13875
13876        boolean killed = false;
13877        synchronized (mPidsSelfLocked) {
13878            final int size = mPidsSelfLocked.size();
13879            for (int i = 0; i < size; i++) {
13880                final int pid = mPidsSelfLocked.keyAt(i);
13881                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13882                if (proc == null) continue;
13883
13884                final int adj = proc.setAdj;
13885                if (adj > belowAdj && !proc.killedByAm) {
13886                    proc.kill(reason, true);
13887                    killed = true;
13888                }
13889            }
13890        }
13891        return killed;
13892    }
13893
13894    @Override
13895    public void hang(final IBinder who, boolean allowRestart) {
13896        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13897                != PackageManager.PERMISSION_GRANTED) {
13898            throw new SecurityException("Requires permission "
13899                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13900        }
13901
13902        final IBinder.DeathRecipient death = new DeathRecipient() {
13903            @Override
13904            public void binderDied() {
13905                synchronized (this) {
13906                    notifyAll();
13907                }
13908            }
13909        };
13910
13911        try {
13912            who.linkToDeath(death, 0);
13913        } catch (RemoteException e) {
13914            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13915            return;
13916        }
13917
13918        synchronized (this) {
13919            Watchdog.getInstance().setAllowRestart(allowRestart);
13920            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13921            synchronized (death) {
13922                while (who.isBinderAlive()) {
13923                    try {
13924                        death.wait();
13925                    } catch (InterruptedException e) {
13926                    }
13927                }
13928            }
13929            Watchdog.getInstance().setAllowRestart(true);
13930        }
13931    }
13932
13933    @Override
13934    public void restart() {
13935        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13936                != PackageManager.PERMISSION_GRANTED) {
13937            throw new SecurityException("Requires permission "
13938                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13939        }
13940
13941        Log.i(TAG, "Sending shutdown broadcast...");
13942
13943        BroadcastReceiver br = new BroadcastReceiver() {
13944            @Override public void onReceive(Context context, Intent intent) {
13945                // Now the broadcast is done, finish up the low-level shutdown.
13946                Log.i(TAG, "Shutting down activity manager...");
13947                shutdown(10000);
13948                Log.i(TAG, "Shutdown complete, restarting!");
13949                killProcess(myPid());
13950                System.exit(10);
13951            }
13952        };
13953
13954        // First send the high-level shut down broadcast.
13955        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13956        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13957        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13958        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13959        mContext.sendOrderedBroadcastAsUser(intent,
13960                UserHandle.ALL, null, br, mHandler, 0, null, null);
13961        */
13962        br.onReceive(mContext, intent);
13963    }
13964
13965    private long getLowRamTimeSinceIdle(long now) {
13966        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13967    }
13968
13969    @Override
13970    public void performIdleMaintenance() {
13971        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13972                != PackageManager.PERMISSION_GRANTED) {
13973            throw new SecurityException("Requires permission "
13974                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13975        }
13976
13977        synchronized (this) {
13978            final long now = SystemClock.uptimeMillis();
13979            final long timeSinceLastIdle = now - mLastIdleTime;
13980            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13981            mLastIdleTime = now;
13982            mLowRamTimeSinceLastIdle = 0;
13983            if (mLowRamStartTime != 0) {
13984                mLowRamStartTime = now;
13985            }
13986
13987            StringBuilder sb = new StringBuilder(128);
13988            sb.append("Idle maintenance over ");
13989            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13990            sb.append(" low RAM for ");
13991            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13992            Slog.i(TAG, sb.toString());
13993
13994            // If at least 1/3 of our time since the last idle period has been spent
13995            // with RAM low, then we want to kill processes.
13996            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13997
13998            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13999                ProcessRecord proc = mLruProcesses.get(i);
14000                if (proc.notCachedSinceIdle) {
14001                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14002                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14003                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14004                        if (doKilling && proc.initialIdlePss != 0
14005                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14006                            sb = new StringBuilder(128);
14007                            sb.append("Kill");
14008                            sb.append(proc.processName);
14009                            sb.append(" in idle maint: pss=");
14010                            sb.append(proc.lastPss);
14011                            sb.append(", swapPss=");
14012                            sb.append(proc.lastSwapPss);
14013                            sb.append(", initialPss=");
14014                            sb.append(proc.initialIdlePss);
14015                            sb.append(", period=");
14016                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14017                            sb.append(", lowRamPeriod=");
14018                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14019                            Slog.wtfQuiet(TAG, sb.toString());
14020                            proc.kill("idle maint (pss " + proc.lastPss
14021                                    + " from " + proc.initialIdlePss + ")", true);
14022                        }
14023                    }
14024                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14025                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14026                    proc.notCachedSinceIdle = true;
14027                    proc.initialIdlePss = 0;
14028                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14029                            mTestPssMode, isSleepingLocked(), now);
14030                }
14031            }
14032
14033            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14034            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14035        }
14036    }
14037
14038    @Override
14039    public void sendIdleJobTrigger() {
14040        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14041                != PackageManager.PERMISSION_GRANTED) {
14042            throw new SecurityException("Requires permission "
14043                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14044        }
14045
14046        final long ident = Binder.clearCallingIdentity();
14047        try {
14048            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14049                    .setPackage("android")
14050                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14051            broadcastIntent(null, intent, null, null, 0, null, null, null,
14052                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14053        } finally {
14054            Binder.restoreCallingIdentity(ident);
14055        }
14056    }
14057
14058    private void retrieveSettings() {
14059        final ContentResolver resolver = mContext.getContentResolver();
14060        final boolean freeformWindowManagement =
14061                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14062                        || Settings.Global.getInt(
14063                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14064
14065        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14066        final boolean supportsPictureInPicture = supportsMultiWindow &&
14067                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14068        final boolean supportsSplitScreenMultiWindow =
14069                ActivityManager.supportsSplitScreenMultiWindow(mContext);
14070        final boolean supportsMultiDisplay = mContext.getPackageManager()
14071                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14072        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14073        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14074        final boolean alwaysFinishActivities =
14075                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14076        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14077        final boolean forceResizable = Settings.Global.getInt(
14078                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14079        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14080                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14081        final boolean supportsLeanbackOnly =
14082                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14083
14084        // Transfer any global setting for forcing RTL layout, into a System Property
14085        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14086
14087        final Configuration configuration = new Configuration();
14088        Settings.System.getConfiguration(resolver, configuration);
14089        if (forceRtl) {
14090            // This will take care of setting the correct layout direction flags
14091            configuration.setLayoutDirection(configuration.locale);
14092        }
14093
14094        synchronized (this) {
14095            mDebugApp = mOrigDebugApp = debugApp;
14096            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14097            mAlwaysFinishActivities = alwaysFinishActivities;
14098            mSupportsLeanbackOnly = supportsLeanbackOnly;
14099            mForceResizableActivities = forceResizable;
14100            final boolean multiWindowFormEnabled = freeformWindowManagement
14101                    || supportsSplitScreenMultiWindow
14102                    || supportsPictureInPicture
14103                    || supportsMultiDisplay;
14104            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14105                mSupportsMultiWindow = true;
14106                mSupportsFreeformWindowManagement = freeformWindowManagement;
14107                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14108                mSupportsPictureInPicture = supportsPictureInPicture;
14109                mSupportsMultiDisplay = supportsMultiDisplay;
14110            } else {
14111                mSupportsMultiWindow = false;
14112                mSupportsFreeformWindowManagement = false;
14113                mSupportsSplitScreenMultiWindow = false;
14114                mSupportsPictureInPicture = false;
14115                mSupportsMultiDisplay = false;
14116            }
14117            mWindowManager.setForceResizableTasks(mForceResizableActivities);
14118            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14119            // This happens before any activities are started, so we can change global configuration
14120            // in-place.
14121            updateConfigurationLocked(configuration, null, true);
14122            final Configuration globalConfig = getGlobalConfiguration();
14123            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14124
14125            // Load resources only after the current configuration has been set.
14126            final Resources res = mContext.getResources();
14127            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14128            mThumbnailWidth = res.getDimensionPixelSize(
14129                    com.android.internal.R.dimen.thumbnail_width);
14130            mThumbnailHeight = res.getDimensionPixelSize(
14131                    com.android.internal.R.dimen.thumbnail_height);
14132            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14133                    com.android.internal.R.string.config_appsNotReportingCrashes));
14134            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14135                    com.android.internal.R.bool.config_customUserSwitchUi);
14136            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14137                mFullscreenThumbnailScale = (float) res
14138                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14139                    (float) globalConfig.screenWidthDp;
14140            } else {
14141                mFullscreenThumbnailScale = res.getFraction(
14142                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14143            }
14144            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14145        }
14146    }
14147
14148    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14149        traceLog.traceBegin("PhaseActivityManagerReady");
14150        synchronized(this) {
14151            if (mSystemReady) {
14152                // If we're done calling all the receivers, run the next "boot phase" passed in
14153                // by the SystemServer
14154                if (goingCallback != null) {
14155                    goingCallback.run();
14156                }
14157                return;
14158            }
14159
14160            mLocalDeviceIdleController
14161                    = LocalServices.getService(DeviceIdleController.LocalService.class);
14162            mAssistUtils = new AssistUtils(mContext);
14163            mVrController.onSystemReady();
14164            // Make sure we have the current profile info, since it is needed for security checks.
14165            mUserController.onSystemReady();
14166            mRecentTasks.onSystemReadyLocked();
14167            mAppOpsService.systemReady();
14168            mSystemReady = true;
14169        }
14170
14171        try {
14172            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14173                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14174                    .getSerial();
14175        } catch (RemoteException e) {}
14176
14177        ArrayList<ProcessRecord> procsToKill = null;
14178        synchronized(mPidsSelfLocked) {
14179            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14180                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14181                if (!isAllowedWhileBooting(proc.info)){
14182                    if (procsToKill == null) {
14183                        procsToKill = new ArrayList<ProcessRecord>();
14184                    }
14185                    procsToKill.add(proc);
14186                }
14187            }
14188        }
14189
14190        synchronized(this) {
14191            if (procsToKill != null) {
14192                for (int i=procsToKill.size()-1; i>=0; i--) {
14193                    ProcessRecord proc = procsToKill.get(i);
14194                    Slog.i(TAG, "Removing system update proc: " + proc);
14195                    removeProcessLocked(proc, true, false, "system update done");
14196                }
14197            }
14198
14199            // Now that we have cleaned up any update processes, we
14200            // are ready to start launching real processes and know that
14201            // we won't trample on them any more.
14202            mProcessesReady = true;
14203        }
14204
14205        Slog.i(TAG, "System now ready");
14206        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14207            SystemClock.uptimeMillis());
14208
14209        synchronized(this) {
14210            // Make sure we have no pre-ready processes sitting around.
14211
14212            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14213                ResolveInfo ri = mContext.getPackageManager()
14214                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14215                                STOCK_PM_FLAGS);
14216                CharSequence errorMsg = null;
14217                if (ri != null) {
14218                    ActivityInfo ai = ri.activityInfo;
14219                    ApplicationInfo app = ai.applicationInfo;
14220                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14221                        mTopAction = Intent.ACTION_FACTORY_TEST;
14222                        mTopData = null;
14223                        mTopComponent = new ComponentName(app.packageName,
14224                                ai.name);
14225                    } else {
14226                        errorMsg = mContext.getResources().getText(
14227                                com.android.internal.R.string.factorytest_not_system);
14228                    }
14229                } else {
14230                    errorMsg = mContext.getResources().getText(
14231                            com.android.internal.R.string.factorytest_no_action);
14232                }
14233                if (errorMsg != null) {
14234                    mTopAction = null;
14235                    mTopData = null;
14236                    mTopComponent = null;
14237                    Message msg = Message.obtain();
14238                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14239                    msg.getData().putCharSequence("msg", errorMsg);
14240                    mUiHandler.sendMessage(msg);
14241                }
14242            }
14243        }
14244
14245        retrieveSettings();
14246        final int currentUserId;
14247        synchronized (this) {
14248            currentUserId = mUserController.getCurrentUserIdLocked();
14249            readGrantedUriPermissionsLocked();
14250        }
14251
14252        if (goingCallback != null) goingCallback.run();
14253        traceLog.traceBegin("ActivityManagerStartApps");
14254        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14255                Integer.toString(currentUserId), currentUserId);
14256        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14257                Integer.toString(currentUserId), currentUserId);
14258        mSystemServiceManager.startUser(currentUserId);
14259
14260        synchronized (this) {
14261            // Only start up encryption-aware persistent apps; once user is
14262            // unlocked we'll come back around and start unaware apps
14263            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14264
14265            // Start up initial activity.
14266            mBooting = true;
14267            // Enable home activity for system user, so that the system can always boot. We don't
14268            // do this when the system user is not setup since the setup wizard should be the one
14269            // to handle home activity in this case.
14270            if (UserManager.isSplitSystemUser() &&
14271                    Settings.Secure.getInt(mContext.getContentResolver(),
14272                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14273                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14274                try {
14275                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14276                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14277                            UserHandle.USER_SYSTEM);
14278                } catch (RemoteException e) {
14279                    throw e.rethrowAsRuntimeException();
14280                }
14281            }
14282            startHomeActivityLocked(currentUserId, "systemReady");
14283
14284            try {
14285                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14286                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14287                            + " data partition or your device will be unstable.");
14288                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14289                }
14290            } catch (RemoteException e) {
14291            }
14292
14293            if (!Build.isBuildConsistent()) {
14294                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14295                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14296            }
14297
14298            long ident = Binder.clearCallingIdentity();
14299            try {
14300                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14301                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14302                        | Intent.FLAG_RECEIVER_FOREGROUND);
14303                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14304                broadcastIntentLocked(null, null, intent,
14305                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14306                        null, false, false, MY_PID, SYSTEM_UID,
14307                        currentUserId);
14308                intent = new Intent(Intent.ACTION_USER_STARTING);
14309                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14310                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14311                broadcastIntentLocked(null, null, intent,
14312                        null, new IIntentReceiver.Stub() {
14313                            @Override
14314                            public void performReceive(Intent intent, int resultCode, String data,
14315                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14316                                    throws RemoteException {
14317                            }
14318                        }, 0, null, null,
14319                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14320                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14321            } catch (Throwable t) {
14322                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14323            } finally {
14324                Binder.restoreCallingIdentity(ident);
14325            }
14326            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14327            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14328            traceLog.traceEnd(); // ActivityManagerStartApps
14329            traceLog.traceEnd(); // PhaseActivityManagerReady
14330        }
14331    }
14332
14333    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14334        synchronized (this) {
14335            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14336        }
14337    }
14338
14339    void skipCurrentReceiverLocked(ProcessRecord app) {
14340        for (BroadcastQueue queue : mBroadcastQueues) {
14341            queue.skipCurrentReceiverLocked(app);
14342        }
14343    }
14344
14345    /**
14346     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14347     * The application process will exit immediately after this call returns.
14348     * @param app object of the crashing app, null for the system server
14349     * @param crashInfo describing the exception
14350     */
14351    public void handleApplicationCrash(IBinder app,
14352            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14353        ProcessRecord r = findAppProcess(app, "Crash");
14354        final String processName = app == null ? "system_server"
14355                : (r == null ? "unknown" : r.processName);
14356
14357        handleApplicationCrashInner("crash", r, processName, crashInfo);
14358    }
14359
14360    /* Native crash reporting uses this inner version because it needs to be somewhat
14361     * decoupled from the AM-managed cleanup lifecycle
14362     */
14363    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14364            ApplicationErrorReport.CrashInfo crashInfo) {
14365        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14366                UserHandle.getUserId(Binder.getCallingUid()), processName,
14367                r == null ? -1 : r.info.flags,
14368                crashInfo.exceptionClassName,
14369                crashInfo.exceptionMessage,
14370                crashInfo.throwFileName,
14371                crashInfo.throwLineNumber);
14372
14373        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14374
14375        mAppErrors.crashApplication(r, crashInfo);
14376    }
14377
14378    public void handleApplicationStrictModeViolation(
14379            IBinder app,
14380            int violationMask,
14381            StrictMode.ViolationInfo info) {
14382        ProcessRecord r = findAppProcess(app, "StrictMode");
14383        if (r == null) {
14384            return;
14385        }
14386
14387        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14388            Integer stackFingerprint = info.hashCode();
14389            boolean logIt = true;
14390            synchronized (mAlreadyLoggedViolatedStacks) {
14391                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14392                    logIt = false;
14393                    // TODO: sub-sample into EventLog for these, with
14394                    // the info.durationMillis?  Then we'd get
14395                    // the relative pain numbers, without logging all
14396                    // the stack traces repeatedly.  We'd want to do
14397                    // likewise in the client code, which also does
14398                    // dup suppression, before the Binder call.
14399                } else {
14400                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14401                        mAlreadyLoggedViolatedStacks.clear();
14402                    }
14403                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14404                }
14405            }
14406            if (logIt) {
14407                logStrictModeViolationToDropBox(r, info);
14408            }
14409        }
14410
14411        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14412            AppErrorResult result = new AppErrorResult();
14413            synchronized (this) {
14414                final long origId = Binder.clearCallingIdentity();
14415
14416                Message msg = Message.obtain();
14417                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14418                HashMap<String, Object> data = new HashMap<String, Object>();
14419                data.put("result", result);
14420                data.put("app", r);
14421                data.put("violationMask", violationMask);
14422                data.put("info", info);
14423                msg.obj = data;
14424                mUiHandler.sendMessage(msg);
14425
14426                Binder.restoreCallingIdentity(origId);
14427            }
14428            int res = result.get();
14429            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14430        }
14431    }
14432
14433    // Depending on the policy in effect, there could be a bunch of
14434    // these in quick succession so we try to batch these together to
14435    // minimize disk writes, number of dropbox entries, and maximize
14436    // compression, by having more fewer, larger records.
14437    private void logStrictModeViolationToDropBox(
14438            ProcessRecord process,
14439            StrictMode.ViolationInfo info) {
14440        if (info == null) {
14441            return;
14442        }
14443        final boolean isSystemApp = process == null ||
14444                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14445                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14446        final String processName = process == null ? "unknown" : process.processName;
14447        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14448        final DropBoxManager dbox = (DropBoxManager)
14449                mContext.getSystemService(Context.DROPBOX_SERVICE);
14450
14451        // Exit early if the dropbox isn't configured to accept this report type.
14452        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14453
14454        boolean bufferWasEmpty;
14455        boolean needsFlush;
14456        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14457        synchronized (sb) {
14458            bufferWasEmpty = sb.length() == 0;
14459            appendDropBoxProcessHeaders(process, processName, sb);
14460            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14461            sb.append("System-App: ").append(isSystemApp).append("\n");
14462            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14463            if (info.violationNumThisLoop != 0) {
14464                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14465            }
14466            if (info.numAnimationsRunning != 0) {
14467                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14468            }
14469            if (info.broadcastIntentAction != null) {
14470                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14471            }
14472            if (info.durationMillis != -1) {
14473                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14474            }
14475            if (info.numInstances != -1) {
14476                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14477            }
14478            if (info.tags != null) {
14479                for (String tag : info.tags) {
14480                    sb.append("Span-Tag: ").append(tag).append("\n");
14481                }
14482            }
14483            sb.append("\n");
14484            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14485                sb.append(info.crashInfo.stackTrace);
14486                sb.append("\n");
14487            }
14488            if (info.message != null) {
14489                sb.append(info.message);
14490                sb.append("\n");
14491            }
14492
14493            // Only buffer up to ~64k.  Various logging bits truncate
14494            // things at 128k.
14495            needsFlush = (sb.length() > 64 * 1024);
14496        }
14497
14498        // Flush immediately if the buffer's grown too large, or this
14499        // is a non-system app.  Non-system apps are isolated with a
14500        // different tag & policy and not batched.
14501        //
14502        // Batching is useful during internal testing with
14503        // StrictMode settings turned up high.  Without batching,
14504        // thousands of separate files could be created on boot.
14505        if (!isSystemApp || needsFlush) {
14506            new Thread("Error dump: " + dropboxTag) {
14507                @Override
14508                public void run() {
14509                    String report;
14510                    synchronized (sb) {
14511                        report = sb.toString();
14512                        sb.delete(0, sb.length());
14513                        sb.trimToSize();
14514                    }
14515                    if (report.length() != 0) {
14516                        dbox.addText(dropboxTag, report);
14517                    }
14518                }
14519            }.start();
14520            return;
14521        }
14522
14523        // System app batching:
14524        if (!bufferWasEmpty) {
14525            // An existing dropbox-writing thread is outstanding, so
14526            // we don't need to start it up.  The existing thread will
14527            // catch the buffer appends we just did.
14528            return;
14529        }
14530
14531        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14532        // (After this point, we shouldn't access AMS internal data structures.)
14533        new Thread("Error dump: " + dropboxTag) {
14534            @Override
14535            public void run() {
14536                // 5 second sleep to let stacks arrive and be batched together
14537                try {
14538                    Thread.sleep(5000);  // 5 seconds
14539                } catch (InterruptedException e) {}
14540
14541                String errorReport;
14542                synchronized (mStrictModeBuffer) {
14543                    errorReport = mStrictModeBuffer.toString();
14544                    if (errorReport.length() == 0) {
14545                        return;
14546                    }
14547                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14548                    mStrictModeBuffer.trimToSize();
14549                }
14550                dbox.addText(dropboxTag, errorReport);
14551            }
14552        }.start();
14553    }
14554
14555    /**
14556     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14557     * @param app object of the crashing app, null for the system server
14558     * @param tag reported by the caller
14559     * @param system whether this wtf is coming from the system
14560     * @param crashInfo describing the context of the error
14561     * @return true if the process should exit immediately (WTF is fatal)
14562     */
14563    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14564            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14565        final int callingUid = Binder.getCallingUid();
14566        final int callingPid = Binder.getCallingPid();
14567
14568        if (system) {
14569            // If this is coming from the system, we could very well have low-level
14570            // system locks held, so we want to do this all asynchronously.  And we
14571            // never want this to become fatal, so there is that too.
14572            mHandler.post(new Runnable() {
14573                @Override public void run() {
14574                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14575                }
14576            });
14577            return false;
14578        }
14579
14580        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14581                crashInfo);
14582
14583        final boolean isFatal = Build.IS_ENG || Settings.Global
14584                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14585        final boolean isSystem = (r == null) || r.persistent;
14586
14587        if (isFatal && !isSystem) {
14588            mAppErrors.crashApplication(r, crashInfo);
14589            return true;
14590        } else {
14591            return false;
14592        }
14593    }
14594
14595    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14596            final ApplicationErrorReport.CrashInfo crashInfo) {
14597        final ProcessRecord r = findAppProcess(app, "WTF");
14598        final String processName = app == null ? "system_server"
14599                : (r == null ? "unknown" : r.processName);
14600
14601        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14602                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14603
14604        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14605
14606        return r;
14607    }
14608
14609    /**
14610     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14611     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14612     */
14613    private ProcessRecord findAppProcess(IBinder app, String reason) {
14614        if (app == null) {
14615            return null;
14616        }
14617
14618        synchronized (this) {
14619            final int NP = mProcessNames.getMap().size();
14620            for (int ip=0; ip<NP; ip++) {
14621                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14622                final int NA = apps.size();
14623                for (int ia=0; ia<NA; ia++) {
14624                    ProcessRecord p = apps.valueAt(ia);
14625                    if (p.thread != null && p.thread.asBinder() == app) {
14626                        return p;
14627                    }
14628                }
14629            }
14630
14631            Slog.w(TAG, "Can't find mystery application for " + reason
14632                    + " from pid=" + Binder.getCallingPid()
14633                    + " uid=" + Binder.getCallingUid() + ": " + app);
14634            return null;
14635        }
14636    }
14637
14638    /**
14639     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14640     * to append various headers to the dropbox log text.
14641     */
14642    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14643            StringBuilder sb) {
14644        // Watchdog thread ends up invoking this function (with
14645        // a null ProcessRecord) to add the stack file to dropbox.
14646        // Do not acquire a lock on this (am) in such cases, as it
14647        // could cause a potential deadlock, if and when watchdog
14648        // is invoked due to unavailability of lock on am and it
14649        // would prevent watchdog from killing system_server.
14650        if (process == null) {
14651            sb.append("Process: ").append(processName).append("\n");
14652            return;
14653        }
14654        // Note: ProcessRecord 'process' is guarded by the service
14655        // instance.  (notably process.pkgList, which could otherwise change
14656        // concurrently during execution of this method)
14657        synchronized (this) {
14658            sb.append("Process: ").append(processName).append("\n");
14659            sb.append("PID: ").append(process.pid).append("\n");
14660            int flags = process.info.flags;
14661            IPackageManager pm = AppGlobals.getPackageManager();
14662            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14663            for (int ip=0; ip<process.pkgList.size(); ip++) {
14664                String pkg = process.pkgList.keyAt(ip);
14665                sb.append("Package: ").append(pkg);
14666                try {
14667                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14668                    if (pi != null) {
14669                        sb.append(" v").append(pi.versionCode);
14670                        if (pi.versionName != null) {
14671                            sb.append(" (").append(pi.versionName).append(")");
14672                        }
14673                    }
14674                } catch (RemoteException e) {
14675                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14676                }
14677                sb.append("\n");
14678            }
14679            if (process.info.isInstantApp()) {
14680                sb.append("Instant-App: true\n");
14681            }
14682        }
14683    }
14684
14685    private static String processClass(ProcessRecord process) {
14686        if (process == null || process.pid == MY_PID) {
14687            return "system_server";
14688        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14689            return "system_app";
14690        } else {
14691            return "data_app";
14692        }
14693    }
14694
14695    private volatile long mWtfClusterStart;
14696    private volatile int mWtfClusterCount;
14697
14698    /**
14699     * Write a description of an error (crash, WTF, ANR) to the drop box.
14700     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14701     * @param process which caused the error, null means the system server
14702     * @param activity which triggered the error, null if unknown
14703     * @param parent activity related to the error, null if unknown
14704     * @param subject line related to the error, null if absent
14705     * @param report in long form describing the error, null if absent
14706     * @param dataFile text file to include in the report, null if none
14707     * @param crashInfo giving an application stack trace, null if absent
14708     */
14709    public void addErrorToDropBox(String eventType,
14710            ProcessRecord process, String processName, ActivityRecord activity,
14711            ActivityRecord parent, String subject,
14712            final String report, final File dataFile,
14713            final ApplicationErrorReport.CrashInfo crashInfo) {
14714        // NOTE -- this must never acquire the ActivityManagerService lock,
14715        // otherwise the watchdog may be prevented from resetting the system.
14716
14717        // Bail early if not published yet
14718        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14719        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14720
14721        // Exit early if the dropbox isn't configured to accept this report type.
14722        final String dropboxTag = processClass(process) + "_" + eventType;
14723        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14724
14725        // Rate-limit how often we're willing to do the heavy lifting below to
14726        // collect and record logs; currently 5 logs per 10 second period.
14727        final long now = SystemClock.elapsedRealtime();
14728        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14729            mWtfClusterStart = now;
14730            mWtfClusterCount = 1;
14731        } else {
14732            if (mWtfClusterCount++ >= 5) return;
14733        }
14734
14735        final StringBuilder sb = new StringBuilder(1024);
14736        appendDropBoxProcessHeaders(process, processName, sb);
14737        if (process != null) {
14738            sb.append("Foreground: ")
14739                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14740                    .append("\n");
14741        }
14742        if (activity != null) {
14743            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14744        }
14745        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14746            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14747        }
14748        if (parent != null && parent != activity) {
14749            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14750        }
14751        if (subject != null) {
14752            sb.append("Subject: ").append(subject).append("\n");
14753        }
14754        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14755        if (Debug.isDebuggerConnected()) {
14756            sb.append("Debugger: Connected\n");
14757        }
14758        sb.append("\n");
14759
14760        // Do the rest in a worker thread to avoid blocking the caller on I/O
14761        // (After this point, we shouldn't access AMS internal data structures.)
14762        Thread worker = new Thread("Error dump: " + dropboxTag) {
14763            @Override
14764            public void run() {
14765                if (report != null) {
14766                    sb.append(report);
14767                }
14768
14769                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14770                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14771                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14772                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14773
14774                if (dataFile != null && maxDataFileSize > 0) {
14775                    try {
14776                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14777                                    "\n\n[[TRUNCATED]]"));
14778                    } catch (IOException e) {
14779                        Slog.e(TAG, "Error reading " + dataFile, e);
14780                    }
14781                }
14782                if (crashInfo != null && crashInfo.stackTrace != null) {
14783                    sb.append(crashInfo.stackTrace);
14784                }
14785
14786                if (lines > 0) {
14787                    sb.append("\n");
14788
14789                    // Merge several logcat streams, and take the last N lines
14790                    InputStreamReader input = null;
14791                    try {
14792                        java.lang.Process logcat = new ProcessBuilder(
14793                                "/system/bin/timeout", "-k", "15s", "10s",
14794                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14795                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14796                                        .redirectErrorStream(true).start();
14797
14798                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14799                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14800                        input = new InputStreamReader(logcat.getInputStream());
14801
14802                        int num;
14803                        char[] buf = new char[8192];
14804                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14805                    } catch (IOException e) {
14806                        Slog.e(TAG, "Error running logcat", e);
14807                    } finally {
14808                        if (input != null) try { input.close(); } catch (IOException e) {}
14809                    }
14810                }
14811
14812                dbox.addText(dropboxTag, sb.toString());
14813            }
14814        };
14815
14816        if (process == null) {
14817            // If process is null, we are being called from some internal code
14818            // and may be about to die -- run this synchronously.
14819            worker.run();
14820        } else {
14821            worker.start();
14822        }
14823    }
14824
14825    @Override
14826    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14827        enforceNotIsolatedCaller("getProcessesInErrorState");
14828        // assume our apps are happy - lazy create the list
14829        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14830
14831        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14832                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14833        int userId = UserHandle.getUserId(Binder.getCallingUid());
14834
14835        synchronized (this) {
14836
14837            // iterate across all processes
14838            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14839                ProcessRecord app = mLruProcesses.get(i);
14840                if (!allUsers && app.userId != userId) {
14841                    continue;
14842                }
14843                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14844                    // This one's in trouble, so we'll generate a report for it
14845                    // crashes are higher priority (in case there's a crash *and* an anr)
14846                    ActivityManager.ProcessErrorStateInfo report = null;
14847                    if (app.crashing) {
14848                        report = app.crashingReport;
14849                    } else if (app.notResponding) {
14850                        report = app.notRespondingReport;
14851                    }
14852
14853                    if (report != null) {
14854                        if (errList == null) {
14855                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14856                        }
14857                        errList.add(report);
14858                    } else {
14859                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14860                                " crashing = " + app.crashing +
14861                                " notResponding = " + app.notResponding);
14862                    }
14863                }
14864            }
14865        }
14866
14867        return errList;
14868    }
14869
14870    static int procStateToImportance(int procState, int memAdj,
14871            ActivityManager.RunningAppProcessInfo currApp,
14872            int clientTargetSdk) {
14873        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14874                procState, clientTargetSdk);
14875        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14876            currApp.lru = memAdj;
14877        } else {
14878            currApp.lru = 0;
14879        }
14880        return imp;
14881    }
14882
14883    private void fillInProcMemInfo(ProcessRecord app,
14884            ActivityManager.RunningAppProcessInfo outInfo,
14885            int clientTargetSdk) {
14886        outInfo.pid = app.pid;
14887        outInfo.uid = app.info.uid;
14888        if (mHeavyWeightProcess == app) {
14889            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14890        }
14891        if (app.persistent) {
14892            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14893        }
14894        if (app.activities.size() > 0) {
14895            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14896        }
14897        outInfo.lastTrimLevel = app.trimMemoryLevel;
14898        int adj = app.curAdj;
14899        int procState = app.curProcState;
14900        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14901        outInfo.importanceReasonCode = app.adjTypeCode;
14902        outInfo.processState = app.curProcState;
14903    }
14904
14905    @Override
14906    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14907        enforceNotIsolatedCaller("getRunningAppProcesses");
14908
14909        final int callingUid = Binder.getCallingUid();
14910        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14911
14912        // Lazy instantiation of list
14913        List<ActivityManager.RunningAppProcessInfo> runList = null;
14914        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14915                callingUid) == PackageManager.PERMISSION_GRANTED;
14916        final int userId = UserHandle.getUserId(callingUid);
14917        final boolean allUids = isGetTasksAllowed(
14918                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14919
14920        synchronized (this) {
14921            // Iterate across all processes
14922            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14923                ProcessRecord app = mLruProcesses.get(i);
14924                if ((!allUsers && app.userId != userId)
14925                        || (!allUids && app.uid != callingUid)) {
14926                    continue;
14927                }
14928                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14929                    // Generate process state info for running application
14930                    ActivityManager.RunningAppProcessInfo currApp =
14931                        new ActivityManager.RunningAppProcessInfo(app.processName,
14932                                app.pid, app.getPackageList());
14933                    fillInProcMemInfo(app, currApp, clientTargetSdk);
14934                    if (app.adjSource instanceof ProcessRecord) {
14935                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14936                        currApp.importanceReasonImportance =
14937                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14938                                        app.adjSourceProcState);
14939                    } else if (app.adjSource instanceof ActivityRecord) {
14940                        ActivityRecord r = (ActivityRecord)app.adjSource;
14941                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14942                    }
14943                    if (app.adjTarget instanceof ComponentName) {
14944                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14945                    }
14946                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14947                    //        + " lru=" + currApp.lru);
14948                    if (runList == null) {
14949                        runList = new ArrayList<>();
14950                    }
14951                    runList.add(currApp);
14952                }
14953            }
14954        }
14955        return runList;
14956    }
14957
14958    @Override
14959    public List<ApplicationInfo> getRunningExternalApplications() {
14960        enforceNotIsolatedCaller("getRunningExternalApplications");
14961        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14962        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14963        if (runningApps != null && runningApps.size() > 0) {
14964            Set<String> extList = new HashSet<String>();
14965            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14966                if (app.pkgList != null) {
14967                    for (String pkg : app.pkgList) {
14968                        extList.add(pkg);
14969                    }
14970                }
14971            }
14972            IPackageManager pm = AppGlobals.getPackageManager();
14973            for (String pkg : extList) {
14974                try {
14975                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14976                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14977                        retList.add(info);
14978                    }
14979                } catch (RemoteException e) {
14980                }
14981            }
14982        }
14983        return retList;
14984    }
14985
14986    @Override
14987    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14988        enforceNotIsolatedCaller("getMyMemoryState");
14989
14990        final int callingUid = Binder.getCallingUid();
14991        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14992
14993        synchronized (this) {
14994            ProcessRecord proc;
14995            synchronized (mPidsSelfLocked) {
14996                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14997            }
14998            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14999        }
15000    }
15001
15002    @Override
15003    public int getMemoryTrimLevel() {
15004        enforceNotIsolatedCaller("getMyMemoryState");
15005        synchronized (this) {
15006            return mLastMemoryLevel;
15007        }
15008    }
15009
15010    @Override
15011    public void onShellCommand(FileDescriptor in, FileDescriptor out,
15012            FileDescriptor err, String[] args, ShellCallback callback,
15013            ResultReceiver resultReceiver) {
15014        (new ActivityManagerShellCommand(this, false)).exec(
15015                this, in, out, err, args, callback, resultReceiver);
15016    }
15017
15018    SleepToken acquireSleepToken(String tag, int displayId) {
15019        synchronized (this) {
15020            final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15021            updateSleepIfNeededLocked();
15022            return token;
15023        }
15024    }
15025
15026    @Override
15027    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15028        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15029
15030        boolean dumpAll = false;
15031        boolean dumpClient = false;
15032        boolean dumpCheckin = false;
15033        boolean dumpCheckinFormat = false;
15034        boolean dumpVisibleStacksOnly = false;
15035        boolean dumpFocusedStackOnly = false;
15036        String dumpPackage = null;
15037
15038        int opti = 0;
15039        while (opti < args.length) {
15040            String opt = args[opti];
15041            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15042                break;
15043            }
15044            opti++;
15045            if ("-a".equals(opt)) {
15046                dumpAll = true;
15047            } else if ("-c".equals(opt)) {
15048                dumpClient = true;
15049            } else if ("-v".equals(opt)) {
15050                dumpVisibleStacksOnly = true;
15051            } else if ("-f".equals(opt)) {
15052                dumpFocusedStackOnly = true;
15053            } else if ("-p".equals(opt)) {
15054                if (opti < args.length) {
15055                    dumpPackage = args[opti];
15056                    opti++;
15057                } else {
15058                    pw.println("Error: -p option requires package argument");
15059                    return;
15060                }
15061                dumpClient = true;
15062            } else if ("--checkin".equals(opt)) {
15063                dumpCheckin = dumpCheckinFormat = true;
15064            } else if ("-C".equals(opt)) {
15065                dumpCheckinFormat = true;
15066            } else if ("-h".equals(opt)) {
15067                ActivityManagerShellCommand.dumpHelp(pw, true);
15068                return;
15069            } else {
15070                pw.println("Unknown argument: " + opt + "; use -h for help");
15071            }
15072        }
15073
15074        long origId = Binder.clearCallingIdentity();
15075        boolean more = false;
15076        // Is the caller requesting to dump a particular piece of data?
15077        if (opti < args.length) {
15078            String cmd = args[opti];
15079            opti++;
15080            if ("activities".equals(cmd) || "a".equals(cmd)) {
15081                synchronized (this) {
15082                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15083                }
15084            } else if ("lastanr".equals(cmd)) {
15085                synchronized (this) {
15086                    dumpLastANRLocked(pw);
15087                }
15088            } else if ("starter".equals(cmd)) {
15089                synchronized (this) {
15090                    dumpActivityStarterLocked(pw, dumpPackage);
15091                }
15092            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15093                synchronized (this) {
15094                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15095                }
15096            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15097                String[] newArgs;
15098                String name;
15099                if (opti >= args.length) {
15100                    name = null;
15101                    newArgs = EMPTY_STRING_ARRAY;
15102                } else {
15103                    dumpPackage = args[opti];
15104                    opti++;
15105                    newArgs = new String[args.length - opti];
15106                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15107                            args.length - opti);
15108                }
15109                synchronized (this) {
15110                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15111                }
15112            } else if ("broadcast-stats".equals(cmd)) {
15113                String[] newArgs;
15114                String name;
15115                if (opti >= args.length) {
15116                    name = null;
15117                    newArgs = EMPTY_STRING_ARRAY;
15118                } else {
15119                    dumpPackage = args[opti];
15120                    opti++;
15121                    newArgs = new String[args.length - opti];
15122                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15123                            args.length - opti);
15124                }
15125                synchronized (this) {
15126                    if (dumpCheckinFormat) {
15127                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15128                                dumpPackage);
15129                    } else {
15130                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15131                    }
15132                }
15133            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15134                String[] newArgs;
15135                String name;
15136                if (opti >= args.length) {
15137                    name = null;
15138                    newArgs = EMPTY_STRING_ARRAY;
15139                } else {
15140                    dumpPackage = args[opti];
15141                    opti++;
15142                    newArgs = new String[args.length - opti];
15143                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15144                            args.length - opti);
15145                }
15146                synchronized (this) {
15147                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15148                }
15149            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15150                String[] newArgs;
15151                String name;
15152                if (opti >= args.length) {
15153                    name = null;
15154                    newArgs = EMPTY_STRING_ARRAY;
15155                } else {
15156                    dumpPackage = args[opti];
15157                    opti++;
15158                    newArgs = new String[args.length - opti];
15159                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15160                            args.length - opti);
15161                }
15162                synchronized (this) {
15163                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15164                }
15165            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15166                synchronized (this) {
15167                    dumpOomLocked(fd, pw, args, opti, true);
15168                }
15169            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15170                synchronized (this) {
15171                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
15172                }
15173            } else if ("provider".equals(cmd)) {
15174                String[] newArgs;
15175                String name;
15176                if (opti >= args.length) {
15177                    name = null;
15178                    newArgs = EMPTY_STRING_ARRAY;
15179                } else {
15180                    name = args[opti];
15181                    opti++;
15182                    newArgs = new String[args.length - opti];
15183                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15184                }
15185                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15186                    pw.println("No providers match: " + name);
15187                    pw.println("Use -h for help.");
15188                }
15189            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15190                synchronized (this) {
15191                    dumpProvidersLocked(fd, pw, args, opti, true, null);
15192                }
15193            } else if ("service".equals(cmd)) {
15194                String[] newArgs;
15195                String name;
15196                if (opti >= args.length) {
15197                    name = null;
15198                    newArgs = EMPTY_STRING_ARRAY;
15199                } else {
15200                    name = args[opti];
15201                    opti++;
15202                    newArgs = new String[args.length - opti];
15203                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15204                            args.length - opti);
15205                }
15206                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15207                    pw.println("No services match: " + name);
15208                    pw.println("Use -h for help.");
15209                }
15210            } else if ("package".equals(cmd)) {
15211                String[] newArgs;
15212                if (opti >= args.length) {
15213                    pw.println("package: no package name specified");
15214                    pw.println("Use -h for help.");
15215                } else {
15216                    dumpPackage = args[opti];
15217                    opti++;
15218                    newArgs = new String[args.length - opti];
15219                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15220                            args.length - opti);
15221                    args = newArgs;
15222                    opti = 0;
15223                    more = true;
15224                }
15225            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15226                synchronized (this) {
15227                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15228                }
15229            } else if ("settings".equals(cmd)) {
15230                synchronized (this) {
15231                    mConstants.dump(pw);
15232                }
15233            } else if ("services".equals(cmd) || "s".equals(cmd)) {
15234                if (dumpClient) {
15235                    ActiveServices.ServiceDumper dumper;
15236                    synchronized (this) {
15237                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15238                                dumpPackage);
15239                    }
15240                    dumper.dumpWithClient();
15241                } else {
15242                    synchronized (this) {
15243                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15244                                dumpPackage).dumpLocked();
15245                    }
15246                }
15247            } else if ("locks".equals(cmd)) {
15248                LockGuard.dump(fd, pw, args);
15249            } else {
15250                // Dumping a single activity?
15251                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15252                        dumpFocusedStackOnly)) {
15253                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15254                    int res = shell.exec(this, null, fd, null, args, null,
15255                            new ResultReceiver(null));
15256                    if (res < 0) {
15257                        pw.println("Bad activity command, or no activities match: " + cmd);
15258                        pw.println("Use -h for help.");
15259                    }
15260                }
15261            }
15262            if (!more) {
15263                Binder.restoreCallingIdentity(origId);
15264                return;
15265            }
15266        }
15267
15268        // No piece of data specified, dump everything.
15269        if (dumpCheckinFormat) {
15270            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15271        } else if (dumpClient) {
15272            ActiveServices.ServiceDumper sdumper;
15273            synchronized (this) {
15274                mConstants.dump(pw);
15275                pw.println();
15276                if (dumpAll) {
15277                    pw.println("-------------------------------------------------------------------------------");
15278                }
15279                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15280                pw.println();
15281                if (dumpAll) {
15282                    pw.println("-------------------------------------------------------------------------------");
15283                }
15284                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15285                pw.println();
15286                if (dumpAll) {
15287                    pw.println("-------------------------------------------------------------------------------");
15288                }
15289                if (dumpAll || dumpPackage != null) {
15290                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15291                    pw.println();
15292                    if (dumpAll) {
15293                        pw.println("-------------------------------------------------------------------------------");
15294                    }
15295                }
15296                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15297                pw.println();
15298                if (dumpAll) {
15299                    pw.println("-------------------------------------------------------------------------------");
15300                }
15301                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15302                pw.println();
15303                if (dumpAll) {
15304                    pw.println("-------------------------------------------------------------------------------");
15305                }
15306                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15307                        dumpPackage);
15308            }
15309            sdumper.dumpWithClient();
15310            pw.println();
15311            synchronized (this) {
15312                if (dumpAll) {
15313                    pw.println("-------------------------------------------------------------------------------");
15314                }
15315                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15316                pw.println();
15317                if (dumpAll) {
15318                    pw.println("-------------------------------------------------------------------------------");
15319                }
15320                dumpLastANRLocked(pw);
15321                pw.println();
15322                if (dumpAll) {
15323                    pw.println("-------------------------------------------------------------------------------");
15324                }
15325                dumpActivityStarterLocked(pw, dumpPackage);
15326                pw.println();
15327                if (dumpAll) {
15328                    pw.println("-------------------------------------------------------------------------------");
15329                }
15330                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15331                if (mAssociations.size() > 0) {
15332                    pw.println();
15333                    if (dumpAll) {
15334                        pw.println("-------------------------------------------------------------------------------");
15335                    }
15336                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15337                }
15338                pw.println();
15339                if (dumpAll) {
15340                    pw.println("-------------------------------------------------------------------------------");
15341                }
15342                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15343            }
15344
15345        } else {
15346            synchronized (this) {
15347                mConstants.dump(pw);
15348                pw.println();
15349                if (dumpAll) {
15350                    pw.println("-------------------------------------------------------------------------------");
15351                }
15352                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15353                pw.println();
15354                if (dumpAll) {
15355                    pw.println("-------------------------------------------------------------------------------");
15356                }
15357                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15358                pw.println();
15359                if (dumpAll) {
15360                    pw.println("-------------------------------------------------------------------------------");
15361                }
15362                if (dumpAll || dumpPackage != null) {
15363                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15364                    pw.println();
15365                    if (dumpAll) {
15366                        pw.println("-------------------------------------------------------------------------------");
15367                    }
15368                }
15369                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15370                pw.println();
15371                if (dumpAll) {
15372                    pw.println("-------------------------------------------------------------------------------");
15373                }
15374                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15375                pw.println();
15376                if (dumpAll) {
15377                    pw.println("-------------------------------------------------------------------------------");
15378                }
15379                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15380                        .dumpLocked();
15381                pw.println();
15382                if (dumpAll) {
15383                    pw.println("-------------------------------------------------------------------------------");
15384                }
15385                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15386                pw.println();
15387                if (dumpAll) {
15388                    pw.println("-------------------------------------------------------------------------------");
15389                }
15390                dumpLastANRLocked(pw);
15391                pw.println();
15392                if (dumpAll) {
15393                    pw.println("-------------------------------------------------------------------------------");
15394                }
15395                dumpActivityStarterLocked(pw, dumpPackage);
15396                pw.println();
15397                if (dumpAll) {
15398                    pw.println("-------------------------------------------------------------------------------");
15399                }
15400                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15401                if (mAssociations.size() > 0) {
15402                    pw.println();
15403                    if (dumpAll) {
15404                        pw.println("-------------------------------------------------------------------------------");
15405                    }
15406                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15407                }
15408                pw.println();
15409                if (dumpAll) {
15410                    pw.println("-------------------------------------------------------------------------------");
15411                }
15412                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15413            }
15414        }
15415        Binder.restoreCallingIdentity(origId);
15416    }
15417
15418    private void dumpLastANRLocked(PrintWriter pw) {
15419        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15420        if (mLastANRState == null) {
15421            pw.println("  <no ANR has occurred since boot>");
15422        } else {
15423            pw.println(mLastANRState);
15424        }
15425    }
15426
15427    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15428        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15429        mActivityStarter.dump(pw, "", dumpPackage);
15430    }
15431
15432    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15433            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15434        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15435                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15436    }
15437
15438    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15439            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15440        pw.println(header);
15441
15442        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15443                dumpPackage);
15444        boolean needSep = printedAnything;
15445
15446        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15447                mStackSupervisor.getResumedActivityLocked(),
15448                dumpPackage, needSep, "  ResumedActivity: ");
15449        if (printed) {
15450            printedAnything = true;
15451            needSep = false;
15452        }
15453
15454        if (dumpPackage == null) {
15455            if (needSep) {
15456                pw.println();
15457            }
15458            printedAnything = true;
15459            mStackSupervisor.dump(pw, "  ");
15460        }
15461
15462        if (!printedAnything) {
15463            pw.println("  (nothing)");
15464        }
15465    }
15466
15467    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15468            int opti, boolean dumpAll, String dumpPackage) {
15469        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15470
15471        boolean printedAnything = false;
15472
15473        if (mRecentTasks != null && mRecentTasks.size() > 0) {
15474            boolean printedHeader = false;
15475
15476            final int N = mRecentTasks.size();
15477            for (int i=0; i<N; i++) {
15478                TaskRecord tr = mRecentTasks.get(i);
15479                if (dumpPackage != null) {
15480                    if (tr.realActivity == null ||
15481                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
15482                        continue;
15483                    }
15484                }
15485                if (!printedHeader) {
15486                    pw.println("  Recent tasks:");
15487                    printedHeader = true;
15488                    printedAnything = true;
15489                }
15490                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15491                        pw.println(tr);
15492                if (dumpAll) {
15493                    mRecentTasks.get(i).dump(pw, "    ");
15494                }
15495            }
15496        }
15497
15498        if (!printedAnything) {
15499            pw.println("  (nothing)");
15500        }
15501    }
15502
15503    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15504            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15505        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15506
15507        int dumpUid = 0;
15508        if (dumpPackage != null) {
15509            IPackageManager pm = AppGlobals.getPackageManager();
15510            try {
15511                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15512            } catch (RemoteException e) {
15513            }
15514        }
15515
15516        boolean printedAnything = false;
15517
15518        final long now = SystemClock.uptimeMillis();
15519
15520        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15521            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15522                    = mAssociations.valueAt(i1);
15523            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15524                SparseArray<ArrayMap<String, Association>> sourceUids
15525                        = targetComponents.valueAt(i2);
15526                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15527                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15528                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15529                        Association ass = sourceProcesses.valueAt(i4);
15530                        if (dumpPackage != null) {
15531                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15532                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15533                                continue;
15534                            }
15535                        }
15536                        printedAnything = true;
15537                        pw.print("  ");
15538                        pw.print(ass.mTargetProcess);
15539                        pw.print("/");
15540                        UserHandle.formatUid(pw, ass.mTargetUid);
15541                        pw.print(" <- ");
15542                        pw.print(ass.mSourceProcess);
15543                        pw.print("/");
15544                        UserHandle.formatUid(pw, ass.mSourceUid);
15545                        pw.println();
15546                        pw.print("    via ");
15547                        pw.print(ass.mTargetComponent.flattenToShortString());
15548                        pw.println();
15549                        pw.print("    ");
15550                        long dur = ass.mTime;
15551                        if (ass.mNesting > 0) {
15552                            dur += now - ass.mStartTime;
15553                        }
15554                        TimeUtils.formatDuration(dur, pw);
15555                        pw.print(" (");
15556                        pw.print(ass.mCount);
15557                        pw.print(" times)");
15558                        pw.print("  ");
15559                        for (int i=0; i<ass.mStateTimes.length; i++) {
15560                            long amt = ass.mStateTimes[i];
15561                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15562                                amt += now - ass.mLastStateUptime;
15563                            }
15564                            if (amt != 0) {
15565                                pw.print(" ");
15566                                pw.print(ProcessList.makeProcStateString(
15567                                            i + ActivityManager.MIN_PROCESS_STATE));
15568                                pw.print("=");
15569                                TimeUtils.formatDuration(amt, pw);
15570                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15571                                    pw.print("*");
15572                                }
15573                            }
15574                        }
15575                        pw.println();
15576                        if (ass.mNesting > 0) {
15577                            pw.print("    Currently active: ");
15578                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15579                            pw.println();
15580                        }
15581                    }
15582                }
15583            }
15584
15585        }
15586
15587        if (!printedAnything) {
15588            pw.println("  (nothing)");
15589        }
15590    }
15591
15592    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15593            String header, boolean needSep) {
15594        boolean printed = false;
15595        int whichAppId = -1;
15596        if (dumpPackage != null) {
15597            try {
15598                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15599                        dumpPackage, 0);
15600                whichAppId = UserHandle.getAppId(info.uid);
15601            } catch (NameNotFoundException e) {
15602                e.printStackTrace();
15603            }
15604        }
15605        for (int i=0; i<uids.size(); i++) {
15606            UidRecord uidRec = uids.valueAt(i);
15607            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15608                continue;
15609            }
15610            if (!printed) {
15611                printed = true;
15612                if (needSep) {
15613                    pw.println();
15614                }
15615                pw.print("  ");
15616                pw.println(header);
15617                needSep = true;
15618            }
15619            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15620            pw.print(": "); pw.println(uidRec);
15621        }
15622        return printed;
15623    }
15624
15625    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15626            int opti, boolean dumpAll, String dumpPackage) {
15627        boolean needSep = false;
15628        boolean printedAnything = false;
15629        int numPers = 0;
15630
15631        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15632
15633        if (dumpAll) {
15634            final int NP = mProcessNames.getMap().size();
15635            for (int ip=0; ip<NP; ip++) {
15636                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15637                final int NA = procs.size();
15638                for (int ia=0; ia<NA; ia++) {
15639                    ProcessRecord r = procs.valueAt(ia);
15640                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15641                        continue;
15642                    }
15643                    if (!needSep) {
15644                        pw.println("  All known processes:");
15645                        needSep = true;
15646                        printedAnything = true;
15647                    }
15648                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15649                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15650                        pw.print(" "); pw.println(r);
15651                    r.dump(pw, "    ");
15652                    if (r.persistent) {
15653                        numPers++;
15654                    }
15655                }
15656            }
15657        }
15658
15659        if (mIsolatedProcesses.size() > 0) {
15660            boolean printed = false;
15661            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15662                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15663                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15664                    continue;
15665                }
15666                if (!printed) {
15667                    if (needSep) {
15668                        pw.println();
15669                    }
15670                    pw.println("  Isolated process list (sorted by uid):");
15671                    printedAnything = true;
15672                    printed = true;
15673                    needSep = true;
15674                }
15675                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15676                pw.println(r);
15677            }
15678        }
15679
15680        if (mActiveInstrumentation.size() > 0) {
15681            boolean printed = false;
15682            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15683                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15684                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15685                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15686                    continue;
15687                }
15688                if (!printed) {
15689                    if (needSep) {
15690                        pw.println();
15691                    }
15692                    pw.println("  Active instrumentation:");
15693                    printedAnything = true;
15694                    printed = true;
15695                    needSep = true;
15696                }
15697                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15698                pw.println(ai);
15699                ai.dump(pw, "      ");
15700            }
15701        }
15702
15703        if (mActiveUids.size() > 0) {
15704            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15705                printedAnything = needSep = true;
15706            }
15707        }
15708        if (dumpAll) {
15709            if (mValidateUids.size() > 0) {
15710                if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15711                    printedAnything = needSep = true;
15712                }
15713            }
15714        }
15715
15716        if (mLruProcesses.size() > 0) {
15717            if (needSep) {
15718                pw.println();
15719            }
15720            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15721                    pw.print(" total, non-act at ");
15722                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15723                    pw.print(", non-svc at ");
15724                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15725                    pw.println("):");
15726            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15727            needSep = true;
15728            printedAnything = true;
15729        }
15730
15731        if (dumpAll || dumpPackage != null) {
15732            synchronized (mPidsSelfLocked) {
15733                boolean printed = false;
15734                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15735                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15736                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15737                        continue;
15738                    }
15739                    if (!printed) {
15740                        if (needSep) pw.println();
15741                        needSep = true;
15742                        pw.println("  PID mappings:");
15743                        printed = true;
15744                        printedAnything = true;
15745                    }
15746                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15747                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15748                }
15749            }
15750        }
15751
15752        if (mImportantProcesses.size() > 0) {
15753            synchronized (mPidsSelfLocked) {
15754                boolean printed = false;
15755                for (int i = 0; i< mImportantProcesses.size(); i++) {
15756                    ProcessRecord r = mPidsSelfLocked.get(
15757                            mImportantProcesses.valueAt(i).pid);
15758                    if (dumpPackage != null && (r == null
15759                            || !r.pkgList.containsKey(dumpPackage))) {
15760                        continue;
15761                    }
15762                    if (!printed) {
15763                        if (needSep) pw.println();
15764                        needSep = true;
15765                        pw.println("  Foreground Processes:");
15766                        printed = true;
15767                        printedAnything = true;
15768                    }
15769                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15770                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15771                }
15772            }
15773        }
15774
15775        if (mPersistentStartingProcesses.size() > 0) {
15776            if (needSep) pw.println();
15777            needSep = true;
15778            printedAnything = true;
15779            pw.println("  Persisent processes that are starting:");
15780            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15781                    "Starting Norm", "Restarting PERS", dumpPackage);
15782        }
15783
15784        if (mRemovedProcesses.size() > 0) {
15785            if (needSep) pw.println();
15786            needSep = true;
15787            printedAnything = true;
15788            pw.println("  Processes that are being removed:");
15789            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15790                    "Removed Norm", "Removed PERS", dumpPackage);
15791        }
15792
15793        if (mProcessesOnHold.size() > 0) {
15794            if (needSep) pw.println();
15795            needSep = true;
15796            printedAnything = true;
15797            pw.println("  Processes that are on old until the system is ready:");
15798            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15799                    "OnHold Norm", "OnHold PERS", dumpPackage);
15800        }
15801
15802        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15803
15804        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15805        if (needSep) {
15806            printedAnything = true;
15807        }
15808
15809        if (dumpPackage == null) {
15810            pw.println();
15811            needSep = false;
15812            mUserController.dump(pw, dumpAll);
15813        }
15814        if (mHomeProcess != null && (dumpPackage == null
15815                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15816            if (needSep) {
15817                pw.println();
15818                needSep = false;
15819            }
15820            pw.println("  mHomeProcess: " + mHomeProcess);
15821        }
15822        if (mPreviousProcess != null && (dumpPackage == null
15823                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15824            if (needSep) {
15825                pw.println();
15826                needSep = false;
15827            }
15828            pw.println("  mPreviousProcess: " + mPreviousProcess);
15829        }
15830        if (dumpAll) {
15831            StringBuilder sb = new StringBuilder(128);
15832            sb.append("  mPreviousProcessVisibleTime: ");
15833            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15834            pw.println(sb);
15835        }
15836        if (mHeavyWeightProcess != null && (dumpPackage == null
15837                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15838            if (needSep) {
15839                pw.println();
15840                needSep = false;
15841            }
15842            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15843        }
15844        if (dumpPackage == null) {
15845            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15846            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15847        }
15848        if (dumpAll) {
15849            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15850            if (mCompatModePackages.getPackages().size() > 0) {
15851                boolean printed = false;
15852                for (Map.Entry<String, Integer> entry
15853                        : mCompatModePackages.getPackages().entrySet()) {
15854                    String pkg = entry.getKey();
15855                    int mode = entry.getValue();
15856                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15857                        continue;
15858                    }
15859                    if (!printed) {
15860                        pw.println("  mScreenCompatPackages:");
15861                        printed = true;
15862                    }
15863                    pw.print("    "); pw.print(pkg); pw.print(": ");
15864                            pw.print(mode); pw.println();
15865                }
15866            }
15867            final int NI = mUidObservers.getRegisteredCallbackCount();
15868            boolean printed = false;
15869            for (int i=0; i<NI; i++) {
15870                final UidObserverRegistration reg = (UidObserverRegistration)
15871                        mUidObservers.getRegisteredCallbackCookie(i);
15872                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15873                    if (!printed) {
15874                        pw.println("  mUidObservers:");
15875                        printed = true;
15876                    }
15877                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15878                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15879                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15880                        pw.print(" IDLE");
15881                    }
15882                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15883                        pw.print(" ACT" );
15884                    }
15885                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15886                        pw.print(" GONE");
15887                    }
15888                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15889                        pw.print(" STATE");
15890                        pw.print(" (cut="); pw.print(reg.cutpoint);
15891                        pw.print(")");
15892                    }
15893                    pw.println();
15894                    if (reg.lastProcStates != null) {
15895                        final int NJ = reg.lastProcStates.size();
15896                        for (int j=0; j<NJ; j++) {
15897                            pw.print("      Last ");
15898                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15899                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15900                        }
15901                    }
15902                }
15903            }
15904            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15905            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15906            if (mPendingTempWhitelist.size() > 0) {
15907                pw.println("  mPendingTempWhitelist:");
15908                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15909                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15910                    pw.print("    ");
15911                    UserHandle.formatUid(pw, ptw.targetUid);
15912                    pw.print(": ");
15913                    TimeUtils.formatDuration(ptw.duration, pw);
15914                    pw.print(" ");
15915                    pw.println(ptw.tag);
15916                }
15917            }
15918        }
15919        if (dumpPackage == null) {
15920            pw.println("  mWakefulness="
15921                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15922            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
15923            pw.println("  mSleeping=" + mSleeping);
15924            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15925            if (mRunningVoice != null) {
15926                pw.println("  mRunningVoice=" + mRunningVoice);
15927                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15928            }
15929        }
15930        pw.println("  mVrController=" + mVrController);
15931        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15932                || mOrigWaitForDebugger) {
15933            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15934                    || dumpPackage.equals(mOrigDebugApp)) {
15935                if (needSep) {
15936                    pw.println();
15937                    needSep = false;
15938                }
15939                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15940                        + " mDebugTransient=" + mDebugTransient
15941                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15942            }
15943        }
15944        if (mCurAppTimeTracker != null) {
15945            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15946        }
15947        if (mMemWatchProcesses.getMap().size() > 0) {
15948            pw.println("  Mem watch processes:");
15949            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15950                    = mMemWatchProcesses.getMap();
15951            for (int i=0; i<procs.size(); i++) {
15952                final String proc = procs.keyAt(i);
15953                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15954                for (int j=0; j<uids.size(); j++) {
15955                    if (needSep) {
15956                        pw.println();
15957                        needSep = false;
15958                    }
15959                    StringBuilder sb = new StringBuilder();
15960                    sb.append("    ").append(proc).append('/');
15961                    UserHandle.formatUid(sb, uids.keyAt(j));
15962                    Pair<Long, String> val = uids.valueAt(j);
15963                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15964                    if (val.second != null) {
15965                        sb.append(", report to ").append(val.second);
15966                    }
15967                    pw.println(sb.toString());
15968                }
15969            }
15970            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15971            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15972            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15973                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15974        }
15975        if (mTrackAllocationApp != null) {
15976            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15977                if (needSep) {
15978                    pw.println();
15979                    needSep = false;
15980                }
15981                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15982            }
15983        }
15984        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
15985                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
15986            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15987                if (needSep) {
15988                    pw.println();
15989                    needSep = false;
15990                }
15991                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15992                if (mProfilerInfo != null) {
15993                    pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
15994                            mProfilerInfo.profileFd);
15995                    pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
15996                            " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
15997                            " mStreamingOutput=" + mProfilerInfo.streamingOutput);
15998                    pw.println("  mProfileType=" + mProfileType);
15999                }
16000            }
16001        }
16002        if (mNativeDebuggingApp != null) {
16003            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16004                if (needSep) {
16005                    pw.println();
16006                    needSep = false;
16007                }
16008                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16009            }
16010        }
16011        if (dumpPackage == null) {
16012            if (mAlwaysFinishActivities) {
16013                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16014            }
16015            if (mController != null) {
16016                pw.println("  mController=" + mController
16017                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16018            }
16019            if (dumpAll) {
16020                pw.println("  Total persistent processes: " + numPers);
16021                pw.println("  mProcessesReady=" + mProcessesReady
16022                        + " mSystemReady=" + mSystemReady
16023                        + " mBooted=" + mBooted
16024                        + " mFactoryTest=" + mFactoryTest);
16025                pw.println("  mBooting=" + mBooting
16026                        + " mCallFinishBooting=" + mCallFinishBooting
16027                        + " mBootAnimationComplete=" + mBootAnimationComplete);
16028                pw.print("  mLastPowerCheckUptime=");
16029                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16030                        pw.println("");
16031                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16032                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16033                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16034                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16035                        + " (" + mLruProcesses.size() + " total)"
16036                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16037                        + " mNumServiceProcs=" + mNumServiceProcs
16038                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16039                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16040                        + " mLastMemoryLevel=" + mLastMemoryLevel
16041                        + " mLastNumProcesses=" + mLastNumProcesses);
16042                long now = SystemClock.uptimeMillis();
16043                pw.print("  mLastIdleTime=");
16044                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
16045                        pw.print(" mLowRamSinceLastIdle=");
16046                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16047                        pw.println();
16048            }
16049        }
16050
16051        if (!printedAnything) {
16052            pw.println("  (nothing)");
16053        }
16054    }
16055
16056    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16057            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16058        if (mProcessesToGc.size() > 0) {
16059            boolean printed = false;
16060            long now = SystemClock.uptimeMillis();
16061            for (int i=0; i<mProcessesToGc.size(); i++) {
16062                ProcessRecord proc = mProcessesToGc.get(i);
16063                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16064                    continue;
16065                }
16066                if (!printed) {
16067                    if (needSep) pw.println();
16068                    needSep = true;
16069                    pw.println("  Processes that are waiting to GC:");
16070                    printed = true;
16071                }
16072                pw.print("    Process "); pw.println(proc);
16073                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16074                        pw.print(", last gced=");
16075                        pw.print(now-proc.lastRequestedGc);
16076                        pw.print(" ms ago, last lowMem=");
16077                        pw.print(now-proc.lastLowMemory);
16078                        pw.println(" ms ago");
16079
16080            }
16081        }
16082        return needSep;
16083    }
16084
16085    void printOomLevel(PrintWriter pw, String name, int adj) {
16086        pw.print("    ");
16087        if (adj >= 0) {
16088            pw.print(' ');
16089            if (adj < 10) pw.print(' ');
16090        } else {
16091            if (adj > -10) pw.print(' ');
16092        }
16093        pw.print(adj);
16094        pw.print(": ");
16095        pw.print(name);
16096        pw.print(" (");
16097        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16098        pw.println(")");
16099    }
16100
16101    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16102            int opti, boolean dumpAll) {
16103        boolean needSep = false;
16104
16105        if (mLruProcesses.size() > 0) {
16106            if (needSep) pw.println();
16107            needSep = true;
16108            pw.println("  OOM levels:");
16109            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16110            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16111            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16112            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16113            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16114            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16115            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16116            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16117            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16118            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16119            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16120            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16121            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16122            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16123
16124            if (needSep) pw.println();
16125            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16126                    pw.print(" total, non-act at ");
16127                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16128                    pw.print(", non-svc at ");
16129                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16130                    pw.println("):");
16131            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16132            needSep = true;
16133        }
16134
16135        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16136
16137        pw.println();
16138        pw.println("  mHomeProcess: " + mHomeProcess);
16139        pw.println("  mPreviousProcess: " + mPreviousProcess);
16140        if (mHeavyWeightProcess != null) {
16141            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16142        }
16143
16144        return true;
16145    }
16146
16147    /**
16148     * There are three ways to call this:
16149     *  - no provider specified: dump all the providers
16150     *  - a flattened component name that matched an existing provider was specified as the
16151     *    first arg: dump that one provider
16152     *  - the first arg isn't the flattened component name of an existing provider:
16153     *    dump all providers whose component contains the first arg as a substring
16154     */
16155    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16156            int opti, boolean dumpAll) {
16157        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16158    }
16159
16160    static class ItemMatcher {
16161        ArrayList<ComponentName> components;
16162        ArrayList<String> strings;
16163        ArrayList<Integer> objects;
16164        boolean all;
16165
16166        ItemMatcher() {
16167            all = true;
16168        }
16169
16170        void build(String name) {
16171            ComponentName componentName = ComponentName.unflattenFromString(name);
16172            if (componentName != null) {
16173                if (components == null) {
16174                    components = new ArrayList<ComponentName>();
16175                }
16176                components.add(componentName);
16177                all = false;
16178            } else {
16179                int objectId = 0;
16180                // Not a '/' separated full component name; maybe an object ID?
16181                try {
16182                    objectId = Integer.parseInt(name, 16);
16183                    if (objects == null) {
16184                        objects = new ArrayList<Integer>();
16185                    }
16186                    objects.add(objectId);
16187                    all = false;
16188                } catch (RuntimeException e) {
16189                    // Not an integer; just do string match.
16190                    if (strings == null) {
16191                        strings = new ArrayList<String>();
16192                    }
16193                    strings.add(name);
16194                    all = false;
16195                }
16196            }
16197        }
16198
16199        int build(String[] args, int opti) {
16200            for (; opti<args.length; opti++) {
16201                String name = args[opti];
16202                if ("--".equals(name)) {
16203                    return opti+1;
16204                }
16205                build(name);
16206            }
16207            return opti;
16208        }
16209
16210        boolean match(Object object, ComponentName comp) {
16211            if (all) {
16212                return true;
16213            }
16214            if (components != null) {
16215                for (int i=0; i<components.size(); i++) {
16216                    if (components.get(i).equals(comp)) {
16217                        return true;
16218                    }
16219                }
16220            }
16221            if (objects != null) {
16222                for (int i=0; i<objects.size(); i++) {
16223                    if (System.identityHashCode(object) == objects.get(i)) {
16224                        return true;
16225                    }
16226                }
16227            }
16228            if (strings != null) {
16229                String flat = comp.flattenToString();
16230                for (int i=0; i<strings.size(); i++) {
16231                    if (flat.contains(strings.get(i))) {
16232                        return true;
16233                    }
16234                }
16235            }
16236            return false;
16237        }
16238    }
16239
16240    /**
16241     * There are three things that cmd can be:
16242     *  - a flattened component name that matches an existing activity
16243     *  - the cmd arg isn't the flattened component name of an existing activity:
16244     *    dump all activity whose component contains the cmd as a substring
16245     *  - A hex number of the ActivityRecord object instance.
16246     *
16247     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16248     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16249     */
16250    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16251            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16252        ArrayList<ActivityRecord> activities;
16253
16254        synchronized (this) {
16255            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16256                    dumpFocusedStackOnly);
16257        }
16258
16259        if (activities.size() <= 0) {
16260            return false;
16261        }
16262
16263        String[] newArgs = new String[args.length - opti];
16264        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16265
16266        TaskRecord lastTask = null;
16267        boolean needSep = false;
16268        for (int i=activities.size()-1; i>=0; i--) {
16269            ActivityRecord r = activities.get(i);
16270            if (needSep) {
16271                pw.println();
16272            }
16273            needSep = true;
16274            synchronized (this) {
16275                final TaskRecord task = r.getTask();
16276                if (lastTask != task) {
16277                    lastTask = task;
16278                    pw.print("TASK "); pw.print(lastTask.affinity);
16279                            pw.print(" id="); pw.print(lastTask.taskId);
16280                            pw.print(" userId="); pw.println(lastTask.userId);
16281                    if (dumpAll) {
16282                        lastTask.dump(pw, "  ");
16283                    }
16284                }
16285            }
16286            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16287        }
16288        return true;
16289    }
16290
16291    /**
16292     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16293     * there is a thread associated with the activity.
16294     */
16295    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16296            final ActivityRecord r, String[] args, boolean dumpAll) {
16297        String innerPrefix = prefix + "  ";
16298        synchronized (this) {
16299            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16300                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16301                    pw.print(" pid=");
16302                    if (r.app != null) pw.println(r.app.pid);
16303                    else pw.println("(not running)");
16304            if (dumpAll) {
16305                r.dump(pw, innerPrefix);
16306            }
16307        }
16308        if (r.app != null && r.app.thread != null) {
16309            // flush anything that is already in the PrintWriter since the thread is going
16310            // to write to the file descriptor directly
16311            pw.flush();
16312            try {
16313                TransferPipe tp = new TransferPipe();
16314                try {
16315                    r.app.thread.dumpActivity(tp.getWriteFd(),
16316                            r.appToken, innerPrefix, args);
16317                    tp.go(fd);
16318                } finally {
16319                    tp.kill();
16320                }
16321            } catch (IOException e) {
16322                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16323            } catch (RemoteException e) {
16324                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16325            }
16326        }
16327    }
16328
16329    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16330            int opti, boolean dumpAll, String dumpPackage) {
16331        boolean needSep = false;
16332        boolean onlyHistory = false;
16333        boolean printedAnything = false;
16334
16335        if ("history".equals(dumpPackage)) {
16336            if (opti < args.length && "-s".equals(args[opti])) {
16337                dumpAll = false;
16338            }
16339            onlyHistory = true;
16340            dumpPackage = null;
16341        }
16342
16343        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16344        if (!onlyHistory && dumpAll) {
16345            if (mRegisteredReceivers.size() > 0) {
16346                boolean printed = false;
16347                Iterator it = mRegisteredReceivers.values().iterator();
16348                while (it.hasNext()) {
16349                    ReceiverList r = (ReceiverList)it.next();
16350                    if (dumpPackage != null && (r.app == null ||
16351                            !dumpPackage.equals(r.app.info.packageName))) {
16352                        continue;
16353                    }
16354                    if (!printed) {
16355                        pw.println("  Registered Receivers:");
16356                        needSep = true;
16357                        printed = true;
16358                        printedAnything = true;
16359                    }
16360                    pw.print("  * "); pw.println(r);
16361                    r.dump(pw, "    ");
16362                }
16363            }
16364
16365            if (mReceiverResolver.dump(pw, needSep ?
16366                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16367                    "    ", dumpPackage, false, false)) {
16368                needSep = true;
16369                printedAnything = true;
16370            }
16371        }
16372
16373        for (BroadcastQueue q : mBroadcastQueues) {
16374            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16375            printedAnything |= needSep;
16376        }
16377
16378        needSep = true;
16379
16380        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16381            for (int user=0; user<mStickyBroadcasts.size(); user++) {
16382                if (needSep) {
16383                    pw.println();
16384                }
16385                needSep = true;
16386                printedAnything = true;
16387                pw.print("  Sticky broadcasts for user ");
16388                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16389                StringBuilder sb = new StringBuilder(128);
16390                for (Map.Entry<String, ArrayList<Intent>> ent
16391                        : mStickyBroadcasts.valueAt(user).entrySet()) {
16392                    pw.print("  * Sticky action "); pw.print(ent.getKey());
16393                    if (dumpAll) {
16394                        pw.println(":");
16395                        ArrayList<Intent> intents = ent.getValue();
16396                        final int N = intents.size();
16397                        for (int i=0; i<N; i++) {
16398                            sb.setLength(0);
16399                            sb.append("    Intent: ");
16400                            intents.get(i).toShortString(sb, false, true, false, false);
16401                            pw.println(sb.toString());
16402                            Bundle bundle = intents.get(i).getExtras();
16403                            if (bundle != null) {
16404                                pw.print("      ");
16405                                pw.println(bundle.toString());
16406                            }
16407                        }
16408                    } else {
16409                        pw.println("");
16410                    }
16411                }
16412            }
16413        }
16414
16415        if (!onlyHistory && dumpAll) {
16416            pw.println();
16417            for (BroadcastQueue queue : mBroadcastQueues) {
16418                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16419                        + queue.mBroadcastsScheduled);
16420            }
16421            pw.println("  mHandler:");
16422            mHandler.dump(new PrintWriterPrinter(pw), "    ");
16423            needSep = true;
16424            printedAnything = true;
16425        }
16426
16427        if (!printedAnything) {
16428            pw.println("  (nothing)");
16429        }
16430    }
16431
16432    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16433            int opti, boolean dumpAll, String dumpPackage) {
16434        if (mCurBroadcastStats == null) {
16435            return;
16436        }
16437
16438        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16439        final long now = SystemClock.elapsedRealtime();
16440        if (mLastBroadcastStats != null) {
16441            pw.print("  Last stats (from ");
16442            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16443            pw.print(" to ");
16444            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16445            pw.print(", ");
16446            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16447                    - mLastBroadcastStats.mStartUptime, pw);
16448            pw.println(" uptime):");
16449            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16450                pw.println("    (nothing)");
16451            }
16452            pw.println();
16453        }
16454        pw.print("  Current stats (from ");
16455        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16456        pw.print(" to now, ");
16457        TimeUtils.formatDuration(SystemClock.uptimeMillis()
16458                - mCurBroadcastStats.mStartUptime, pw);
16459        pw.println(" uptime):");
16460        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16461            pw.println("    (nothing)");
16462        }
16463    }
16464
16465    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16466            int opti, boolean fullCheckin, String dumpPackage) {
16467        if (mCurBroadcastStats == null) {
16468            return;
16469        }
16470
16471        if (mLastBroadcastStats != null) {
16472            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16473            if (fullCheckin) {
16474                mLastBroadcastStats = null;
16475                return;
16476            }
16477        }
16478        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16479        if (fullCheckin) {
16480            mCurBroadcastStats = null;
16481        }
16482    }
16483
16484    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16485            int opti, boolean dumpAll, String dumpPackage) {
16486        boolean needSep;
16487        boolean printedAnything = false;
16488
16489        ItemMatcher matcher = new ItemMatcher();
16490        matcher.build(args, opti);
16491
16492        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16493
16494        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16495        printedAnything |= needSep;
16496
16497        if (mLaunchingProviders.size() > 0) {
16498            boolean printed = false;
16499            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16500                ContentProviderRecord r = mLaunchingProviders.get(i);
16501                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16502                    continue;
16503                }
16504                if (!printed) {
16505                    if (needSep) pw.println();
16506                    needSep = true;
16507                    pw.println("  Launching content providers:");
16508                    printed = true;
16509                    printedAnything = true;
16510                }
16511                pw.print("  Launching #"); pw.print(i); pw.print(": ");
16512                        pw.println(r);
16513            }
16514        }
16515
16516        if (!printedAnything) {
16517            pw.println("  (nothing)");
16518        }
16519    }
16520
16521    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16522            int opti, boolean dumpAll, String dumpPackage) {
16523        boolean needSep = false;
16524        boolean printedAnything = false;
16525
16526        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16527
16528        if (mGrantedUriPermissions.size() > 0) {
16529            boolean printed = false;
16530            int dumpUid = -2;
16531            if (dumpPackage != null) {
16532                try {
16533                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16534                            MATCH_ANY_USER, 0);
16535                } catch (NameNotFoundException e) {
16536                    dumpUid = -1;
16537                }
16538            }
16539            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16540                int uid = mGrantedUriPermissions.keyAt(i);
16541                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16542                    continue;
16543                }
16544                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16545                if (!printed) {
16546                    if (needSep) pw.println();
16547                    needSep = true;
16548                    pw.println("  Granted Uri Permissions:");
16549                    printed = true;
16550                    printedAnything = true;
16551                }
16552                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16553                for (UriPermission perm : perms.values()) {
16554                    pw.print("    "); pw.println(perm);
16555                    if (dumpAll) {
16556                        perm.dump(pw, "      ");
16557                    }
16558                }
16559            }
16560        }
16561
16562        if (!printedAnything) {
16563            pw.println("  (nothing)");
16564        }
16565    }
16566
16567    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16568            int opti, boolean dumpAll, String dumpPackage) {
16569        boolean printed = false;
16570
16571        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16572
16573        if (mIntentSenderRecords.size() > 0) {
16574            // Organize these by package name, so they are easier to read.
16575            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16576            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16577            final Iterator<WeakReference<PendingIntentRecord>> it
16578                    = mIntentSenderRecords.values().iterator();
16579            while (it.hasNext()) {
16580                WeakReference<PendingIntentRecord> ref = it.next();
16581                PendingIntentRecord rec = ref != null ? ref.get() : null;
16582                if (rec == null) {
16583                    weakRefs.add(ref);
16584                    continue;
16585                }
16586                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16587                    continue;
16588                }
16589                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16590                if (list == null) {
16591                    list = new ArrayList<>();
16592                    byPackage.put(rec.key.packageName, list);
16593                }
16594                list.add(rec);
16595            }
16596            for (int i = 0; i < byPackage.size(); i++) {
16597                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16598                printed = true;
16599                pw.print("  * "); pw.print(byPackage.keyAt(i));
16600                pw.print(": "); pw.print(intents.size()); pw.println(" items");
16601                for (int j = 0; j < intents.size(); j++) {
16602                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16603                    if (dumpAll) {
16604                        intents.get(j).dump(pw, "      ");
16605                    }
16606                }
16607            }
16608            if (weakRefs.size() > 0) {
16609                printed = true;
16610                pw.println("  * WEAK REFS:");
16611                for (int i = 0; i < weakRefs.size(); i++) {
16612                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16613                }
16614            }
16615        }
16616
16617        if (!printed) {
16618            pw.println("  (nothing)");
16619        }
16620    }
16621
16622    private static final int dumpProcessList(PrintWriter pw,
16623            ActivityManagerService service, List list,
16624            String prefix, String normalLabel, String persistentLabel,
16625            String dumpPackage) {
16626        int numPers = 0;
16627        final int N = list.size()-1;
16628        for (int i=N; i>=0; i--) {
16629            ProcessRecord r = (ProcessRecord)list.get(i);
16630            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16631                continue;
16632            }
16633            pw.println(String.format("%s%s #%2d: %s",
16634                    prefix, (r.persistent ? persistentLabel : normalLabel),
16635                    i, r.toString()));
16636            if (r.persistent) {
16637                numPers++;
16638            }
16639        }
16640        return numPers;
16641    }
16642
16643    private static final boolean dumpProcessOomList(PrintWriter pw,
16644            ActivityManagerService service, List<ProcessRecord> origList,
16645            String prefix, String normalLabel, String persistentLabel,
16646            boolean inclDetails, String dumpPackage) {
16647
16648        ArrayList<Pair<ProcessRecord, Integer>> list
16649                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16650        for (int i=0; i<origList.size(); i++) {
16651            ProcessRecord r = origList.get(i);
16652            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16653                continue;
16654            }
16655            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16656        }
16657
16658        if (list.size() <= 0) {
16659            return false;
16660        }
16661
16662        Comparator<Pair<ProcessRecord, Integer>> comparator
16663                = new Comparator<Pair<ProcessRecord, Integer>>() {
16664            @Override
16665            public int compare(Pair<ProcessRecord, Integer> object1,
16666                    Pair<ProcessRecord, Integer> object2) {
16667                if (object1.first.setAdj != object2.first.setAdj) {
16668                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16669                }
16670                if (object1.first.setProcState != object2.first.setProcState) {
16671                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16672                }
16673                if (object1.second.intValue() != object2.second.intValue()) {
16674                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16675                }
16676                return 0;
16677            }
16678        };
16679
16680        Collections.sort(list, comparator);
16681
16682        final long curUptime = SystemClock.uptimeMillis();
16683        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16684
16685        for (int i=list.size()-1; i>=0; i--) {
16686            ProcessRecord r = list.get(i).first;
16687            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16688            char schedGroup;
16689            switch (r.setSchedGroup) {
16690                case ProcessList.SCHED_GROUP_BACKGROUND:
16691                    schedGroup = 'B';
16692                    break;
16693                case ProcessList.SCHED_GROUP_DEFAULT:
16694                    schedGroup = 'F';
16695                    break;
16696                case ProcessList.SCHED_GROUP_TOP_APP:
16697                    schedGroup = 'T';
16698                    break;
16699                default:
16700                    schedGroup = '?';
16701                    break;
16702            }
16703            char foreground;
16704            if (r.foregroundActivities) {
16705                foreground = 'A';
16706            } else if (r.foregroundServices) {
16707                foreground = 'S';
16708            } else {
16709                foreground = ' ';
16710            }
16711            String procState = ProcessList.makeProcStateString(r.curProcState);
16712            pw.print(prefix);
16713            pw.print(r.persistent ? persistentLabel : normalLabel);
16714            pw.print(" #");
16715            int num = (origList.size()-1)-list.get(i).second;
16716            if (num < 10) pw.print(' ');
16717            pw.print(num);
16718            pw.print(": ");
16719            pw.print(oomAdj);
16720            pw.print(' ');
16721            pw.print(schedGroup);
16722            pw.print('/');
16723            pw.print(foreground);
16724            pw.print('/');
16725            pw.print(procState);
16726            pw.print(" trm:");
16727            if (r.trimMemoryLevel < 10) pw.print(' ');
16728            pw.print(r.trimMemoryLevel);
16729            pw.print(' ');
16730            pw.print(r.toShortString());
16731            pw.print(" (");
16732            pw.print(r.adjType);
16733            pw.println(')');
16734            if (r.adjSource != null || r.adjTarget != null) {
16735                pw.print(prefix);
16736                pw.print("    ");
16737                if (r.adjTarget instanceof ComponentName) {
16738                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16739                } else if (r.adjTarget != null) {
16740                    pw.print(r.adjTarget.toString());
16741                } else {
16742                    pw.print("{null}");
16743                }
16744                pw.print("<=");
16745                if (r.adjSource instanceof ProcessRecord) {
16746                    pw.print("Proc{");
16747                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16748                    pw.println("}");
16749                } else if (r.adjSource != null) {
16750                    pw.println(r.adjSource.toString());
16751                } else {
16752                    pw.println("{null}");
16753                }
16754            }
16755            if (inclDetails) {
16756                pw.print(prefix);
16757                pw.print("    ");
16758                pw.print("oom: max="); pw.print(r.maxAdj);
16759                pw.print(" curRaw="); pw.print(r.curRawAdj);
16760                pw.print(" setRaw="); pw.print(r.setRawAdj);
16761                pw.print(" cur="); pw.print(r.curAdj);
16762                pw.print(" set="); pw.println(r.setAdj);
16763                pw.print(prefix);
16764                pw.print("    ");
16765                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16766                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16767                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16768                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16769                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16770                pw.println();
16771                pw.print(prefix);
16772                pw.print("    ");
16773                pw.print("cached="); pw.print(r.cached);
16774                pw.print(" empty="); pw.print(r.empty);
16775                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16776
16777                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16778                    if (r.lastCpuTime != 0) {
16779                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16780                        pw.print(prefix);
16781                        pw.print("    ");
16782                        pw.print("run cpu over ");
16783                        TimeUtils.formatDuration(uptimeSince, pw);
16784                        pw.print(" used ");
16785                        TimeUtils.formatDuration(timeUsed, pw);
16786                        pw.print(" (");
16787                        pw.print((timeUsed*100)/uptimeSince);
16788                        pw.println("%)");
16789                    }
16790                }
16791            }
16792        }
16793        return true;
16794    }
16795
16796    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16797            String[] args) {
16798        ArrayList<ProcessRecord> procs;
16799        synchronized (this) {
16800            if (args != null && args.length > start
16801                    && args[start].charAt(0) != '-') {
16802                procs = new ArrayList<ProcessRecord>();
16803                int pid = -1;
16804                try {
16805                    pid = Integer.parseInt(args[start]);
16806                } catch (NumberFormatException e) {
16807                }
16808                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16809                    ProcessRecord proc = mLruProcesses.get(i);
16810                    if (proc.pid == pid) {
16811                        procs.add(proc);
16812                    } else if (allPkgs && proc.pkgList != null
16813                            && proc.pkgList.containsKey(args[start])) {
16814                        procs.add(proc);
16815                    } else if (proc.processName.equals(args[start])) {
16816                        procs.add(proc);
16817                    }
16818                }
16819                if (procs.size() <= 0) {
16820                    return null;
16821                }
16822            } else {
16823                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16824            }
16825        }
16826        return procs;
16827    }
16828
16829    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16830            PrintWriter pw, String[] args) {
16831        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16832        if (procs == null) {
16833            pw.println("No process found for: " + args[0]);
16834            return;
16835        }
16836
16837        long uptime = SystemClock.uptimeMillis();
16838        long realtime = SystemClock.elapsedRealtime();
16839        pw.println("Applications Graphics Acceleration Info:");
16840        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16841
16842        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16843            ProcessRecord r = procs.get(i);
16844            if (r.thread != null) {
16845                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16846                pw.flush();
16847                try {
16848                    TransferPipe tp = new TransferPipe();
16849                    try {
16850                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16851                        tp.go(fd);
16852                    } finally {
16853                        tp.kill();
16854                    }
16855                } catch (IOException e) {
16856                    pw.println("Failure while dumping the app: " + r);
16857                    pw.flush();
16858                } catch (RemoteException e) {
16859                    pw.println("Got a RemoteException while dumping the app " + r);
16860                    pw.flush();
16861                }
16862            }
16863        }
16864    }
16865
16866    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16867        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16868        if (procs == null) {
16869            pw.println("No process found for: " + args[0]);
16870            return;
16871        }
16872
16873        pw.println("Applications Database Info:");
16874
16875        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16876            ProcessRecord r = procs.get(i);
16877            if (r.thread != null) {
16878                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16879                pw.flush();
16880                try {
16881                    TransferPipe tp = new TransferPipe();
16882                    try {
16883                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16884                        tp.go(fd);
16885                    } finally {
16886                        tp.kill();
16887                    }
16888                } catch (IOException e) {
16889                    pw.println("Failure while dumping the app: " + r);
16890                    pw.flush();
16891                } catch (RemoteException e) {
16892                    pw.println("Got a RemoteException while dumping the app " + r);
16893                    pw.flush();
16894                }
16895            }
16896        }
16897    }
16898
16899    final static class MemItem {
16900        final boolean isProc;
16901        final String label;
16902        final String shortLabel;
16903        final long pss;
16904        final long swapPss;
16905        final int id;
16906        final boolean hasActivities;
16907        ArrayList<MemItem> subitems;
16908
16909        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16910                boolean _hasActivities) {
16911            isProc = true;
16912            label = _label;
16913            shortLabel = _shortLabel;
16914            pss = _pss;
16915            swapPss = _swapPss;
16916            id = _id;
16917            hasActivities = _hasActivities;
16918        }
16919
16920        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16921            isProc = false;
16922            label = _label;
16923            shortLabel = _shortLabel;
16924            pss = _pss;
16925            swapPss = _swapPss;
16926            id = _id;
16927            hasActivities = false;
16928        }
16929    }
16930
16931    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16932            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16933        if (sort && !isCompact) {
16934            Collections.sort(items, new Comparator<MemItem>() {
16935                @Override
16936                public int compare(MemItem lhs, MemItem rhs) {
16937                    if (lhs.pss < rhs.pss) {
16938                        return 1;
16939                    } else if (lhs.pss > rhs.pss) {
16940                        return -1;
16941                    }
16942                    return 0;
16943                }
16944            });
16945        }
16946
16947        for (int i=0; i<items.size(); i++) {
16948            MemItem mi = items.get(i);
16949            if (!isCompact) {
16950                if (dumpSwapPss) {
16951                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16952                            mi.label, stringifyKBSize(mi.swapPss));
16953                } else {
16954                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16955                }
16956            } else if (mi.isProc) {
16957                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16958                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16959                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16960                pw.println(mi.hasActivities ? ",a" : ",e");
16961            } else {
16962                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16963                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16964            }
16965            if (mi.subitems != null) {
16966                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16967                        true, isCompact, dumpSwapPss);
16968            }
16969        }
16970    }
16971
16972    // These are in KB.
16973    static final long[] DUMP_MEM_BUCKETS = new long[] {
16974        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16975        120*1024, 160*1024, 200*1024,
16976        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16977        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16978    };
16979
16980    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16981            boolean stackLike) {
16982        int start = label.lastIndexOf('.');
16983        if (start >= 0) start++;
16984        else start = 0;
16985        int end = label.length();
16986        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16987            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16988                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16989                out.append(bucket);
16990                out.append(stackLike ? "MB." : "MB ");
16991                out.append(label, start, end);
16992                return;
16993            }
16994        }
16995        out.append(memKB/1024);
16996        out.append(stackLike ? "MB." : "MB ");
16997        out.append(label, start, end);
16998    }
16999
17000    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17001            ProcessList.NATIVE_ADJ,
17002            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17003            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17004            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17005            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17006            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17007            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17008    };
17009    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17010            "Native",
17011            "System", "Persistent", "Persistent Service", "Foreground",
17012            "Visible", "Perceptible",
17013            "Heavy Weight", "Backup",
17014            "A Services", "Home",
17015            "Previous", "B Services", "Cached"
17016    };
17017    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17018            "native",
17019            "sys", "pers", "persvc", "fore",
17020            "vis", "percept",
17021            "heavy", "backup",
17022            "servicea", "home",
17023            "prev", "serviceb", "cached"
17024    };
17025
17026    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17027            long realtime, boolean isCheckinRequest, boolean isCompact) {
17028        if (isCompact) {
17029            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17030        }
17031        if (isCheckinRequest || isCompact) {
17032            // short checkin version
17033            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17034        } else {
17035            pw.println("Applications Memory Usage (in Kilobytes):");
17036            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17037        }
17038    }
17039
17040    private static final int KSM_SHARED = 0;
17041    private static final int KSM_SHARING = 1;
17042    private static final int KSM_UNSHARED = 2;
17043    private static final int KSM_VOLATILE = 3;
17044
17045    private final long[] getKsmInfo() {
17046        long[] longOut = new long[4];
17047        final int[] SINGLE_LONG_FORMAT = new int[] {
17048            PROC_SPACE_TERM| PROC_OUT_LONG
17049        };
17050        long[] longTmp = new long[1];
17051        readProcFile("/sys/kernel/mm/ksm/pages_shared",
17052                SINGLE_LONG_FORMAT, null, longTmp, null);
17053        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17054        longTmp[0] = 0;
17055        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17056                SINGLE_LONG_FORMAT, null, longTmp, null);
17057        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17058        longTmp[0] = 0;
17059        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17060                SINGLE_LONG_FORMAT, null, longTmp, null);
17061        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17062        longTmp[0] = 0;
17063        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17064                SINGLE_LONG_FORMAT, null, longTmp, null);
17065        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17066        return longOut;
17067    }
17068
17069    private static String stringifySize(long size, int order) {
17070        Locale locale = Locale.US;
17071        switch (order) {
17072            case 1:
17073                return String.format(locale, "%,13d", size);
17074            case 1024:
17075                return String.format(locale, "%,9dK", size / 1024);
17076            case 1024 * 1024:
17077                return String.format(locale, "%,5dM", size / 1024 / 1024);
17078            case 1024 * 1024 * 1024:
17079                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17080            default:
17081                throw new IllegalArgumentException("Invalid size order");
17082        }
17083    }
17084
17085    private static String stringifyKBSize(long size) {
17086        return stringifySize(size * 1024, 1024);
17087    }
17088
17089    // Update this version number in case you change the 'compact' format
17090    private static final int MEMINFO_COMPACT_VERSION = 1;
17091
17092    final void dumpApplicationMemoryUsage(FileDescriptor fd,
17093            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17094        boolean dumpDetails = false;
17095        boolean dumpFullDetails = false;
17096        boolean dumpDalvik = false;
17097        boolean dumpSummaryOnly = false;
17098        boolean dumpUnreachable = false;
17099        boolean oomOnly = false;
17100        boolean isCompact = false;
17101        boolean localOnly = false;
17102        boolean packages = false;
17103        boolean isCheckinRequest = false;
17104        boolean dumpSwapPss = false;
17105
17106        int opti = 0;
17107        while (opti < args.length) {
17108            String opt = args[opti];
17109            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17110                break;
17111            }
17112            opti++;
17113            if ("-a".equals(opt)) {
17114                dumpDetails = true;
17115                dumpFullDetails = true;
17116                dumpDalvik = true;
17117                dumpSwapPss = true;
17118            } else if ("-d".equals(opt)) {
17119                dumpDalvik = true;
17120            } else if ("-c".equals(opt)) {
17121                isCompact = true;
17122            } else if ("-s".equals(opt)) {
17123                dumpDetails = true;
17124                dumpSummaryOnly = true;
17125            } else if ("-S".equals(opt)) {
17126                dumpSwapPss = true;
17127            } else if ("--unreachable".equals(opt)) {
17128                dumpUnreachable = true;
17129            } else if ("--oom".equals(opt)) {
17130                oomOnly = true;
17131            } else if ("--local".equals(opt)) {
17132                localOnly = true;
17133            } else if ("--package".equals(opt)) {
17134                packages = true;
17135            } else if ("--checkin".equals(opt)) {
17136                isCheckinRequest = true;
17137
17138            } else if ("-h".equals(opt)) {
17139                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17140                pw.println("  -a: include all available information for each process.");
17141                pw.println("  -d: include dalvik details.");
17142                pw.println("  -c: dump in a compact machine-parseable representation.");
17143                pw.println("  -s: dump only summary of application memory usage.");
17144                pw.println("  -S: dump also SwapPss.");
17145                pw.println("  --oom: only show processes organized by oom adj.");
17146                pw.println("  --local: only collect details locally, don't call process.");
17147                pw.println("  --package: interpret process arg as package, dumping all");
17148                pw.println("             processes that have loaded that package.");
17149                pw.println("  --checkin: dump data for a checkin");
17150                pw.println("If [process] is specified it can be the name or ");
17151                pw.println("pid of a specific process to dump.");
17152                return;
17153            } else {
17154                pw.println("Unknown argument: " + opt + "; use -h for help");
17155            }
17156        }
17157
17158        long uptime = SystemClock.uptimeMillis();
17159        long realtime = SystemClock.elapsedRealtime();
17160        final long[] tmpLong = new long[1];
17161
17162        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17163        if (procs == null) {
17164            // No Java processes.  Maybe they want to print a native process.
17165            if (args != null && args.length > opti
17166                    && args[opti].charAt(0) != '-') {
17167                ArrayList<ProcessCpuTracker.Stats> nativeProcs
17168                        = new ArrayList<ProcessCpuTracker.Stats>();
17169                updateCpuStatsNow();
17170                int findPid = -1;
17171                try {
17172                    findPid = Integer.parseInt(args[opti]);
17173                } catch (NumberFormatException e) {
17174                }
17175                synchronized (mProcessCpuTracker) {
17176                    final int N = mProcessCpuTracker.countStats();
17177                    for (int i=0; i<N; i++) {
17178                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17179                        if (st.pid == findPid || (st.baseName != null
17180                                && st.baseName.equals(args[opti]))) {
17181                            nativeProcs.add(st);
17182                        }
17183                    }
17184                }
17185                if (nativeProcs.size() > 0) {
17186                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17187                            isCompact);
17188                    Debug.MemoryInfo mi = null;
17189                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17190                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17191                        final int pid = r.pid;
17192                        if (!isCheckinRequest && dumpDetails) {
17193                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17194                        }
17195                        if (mi == null) {
17196                            mi = new Debug.MemoryInfo();
17197                        }
17198                        if (dumpDetails || (!brief && !oomOnly)) {
17199                            Debug.getMemoryInfo(pid, mi);
17200                        } else {
17201                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17202                            mi.dalvikPrivateDirty = (int)tmpLong[0];
17203                        }
17204                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17205                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17206                        if (isCheckinRequest) {
17207                            pw.println();
17208                        }
17209                    }
17210                    return;
17211                }
17212            }
17213            pw.println("No process found for: " + args[opti]);
17214            return;
17215        }
17216
17217        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17218            dumpDetails = true;
17219        }
17220
17221        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17222
17223        String[] innerArgs = new String[args.length-opti];
17224        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17225
17226        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17227        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17228        long nativePss = 0;
17229        long nativeSwapPss = 0;
17230        long dalvikPss = 0;
17231        long dalvikSwapPss = 0;
17232        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17233                EmptyArray.LONG;
17234        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17235                EmptyArray.LONG;
17236        long otherPss = 0;
17237        long otherSwapPss = 0;
17238        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17239        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17240
17241        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17242        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17243        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17244                new ArrayList[DUMP_MEM_OOM_LABEL.length];
17245
17246        long totalPss = 0;
17247        long totalSwapPss = 0;
17248        long cachedPss = 0;
17249        long cachedSwapPss = 0;
17250        boolean hasSwapPss = false;
17251
17252        Debug.MemoryInfo mi = null;
17253        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17254            final ProcessRecord r = procs.get(i);
17255            final IApplicationThread thread;
17256            final int pid;
17257            final int oomAdj;
17258            final boolean hasActivities;
17259            synchronized (this) {
17260                thread = r.thread;
17261                pid = r.pid;
17262                oomAdj = r.getSetAdjWithServices();
17263                hasActivities = r.activities.size() > 0;
17264            }
17265            if (thread != null) {
17266                if (!isCheckinRequest && dumpDetails) {
17267                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17268                }
17269                if (mi == null) {
17270                    mi = new Debug.MemoryInfo();
17271                }
17272                if (dumpDetails || (!brief && !oomOnly)) {
17273                    Debug.getMemoryInfo(pid, mi);
17274                    hasSwapPss = mi.hasSwappedOutPss;
17275                } else {
17276                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17277                    mi.dalvikPrivateDirty = (int)tmpLong[0];
17278                }
17279                if (dumpDetails) {
17280                    if (localOnly) {
17281                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17282                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17283                        if (isCheckinRequest) {
17284                            pw.println();
17285                        }
17286                    } else {
17287                        pw.flush();
17288                        try {
17289                            TransferPipe tp = new TransferPipe();
17290                            try {
17291                                thread.dumpMemInfo(tp.getWriteFd(),
17292                                        mi, isCheckinRequest, dumpFullDetails,
17293                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17294                                tp.go(fd);
17295                            } finally {
17296                                tp.kill();
17297                            }
17298                        } catch (IOException e) {
17299                            if (!isCheckinRequest) {
17300                                pw.println("Got IoException! " + e);
17301                                pw.flush();
17302                            }
17303                        } catch (RemoteException e) {
17304                            if (!isCheckinRequest) {
17305                                pw.println("Got RemoteException! " + e);
17306                                pw.flush();
17307                            }
17308                        }
17309                    }
17310                }
17311
17312                final long myTotalPss = mi.getTotalPss();
17313                final long myTotalUss = mi.getTotalUss();
17314                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17315
17316                synchronized (this) {
17317                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17318                        // Record this for posterity if the process has been stable.
17319                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17320                    }
17321                }
17322
17323                if (!isCheckinRequest && mi != null) {
17324                    totalPss += myTotalPss;
17325                    totalSwapPss += myTotalSwapPss;
17326                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17327                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17328                            myTotalSwapPss, pid, hasActivities);
17329                    procMems.add(pssItem);
17330                    procMemsMap.put(pid, pssItem);
17331
17332                    nativePss += mi.nativePss;
17333                    nativeSwapPss += mi.nativeSwappedOutPss;
17334                    dalvikPss += mi.dalvikPss;
17335                    dalvikSwapPss += mi.dalvikSwappedOutPss;
17336                    for (int j=0; j<dalvikSubitemPss.length; j++) {
17337                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17338                        dalvikSubitemSwapPss[j] +=
17339                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17340                    }
17341                    otherPss += mi.otherPss;
17342                    otherSwapPss += mi.otherSwappedOutPss;
17343                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17344                        long mem = mi.getOtherPss(j);
17345                        miscPss[j] += mem;
17346                        otherPss -= mem;
17347                        mem = mi.getOtherSwappedOutPss(j);
17348                        miscSwapPss[j] += mem;
17349                        otherSwapPss -= mem;
17350                    }
17351
17352                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17353                        cachedPss += myTotalPss;
17354                        cachedSwapPss += myTotalSwapPss;
17355                    }
17356
17357                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17358                        if (oomIndex == (oomPss.length - 1)
17359                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17360                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17361                            oomPss[oomIndex] += myTotalPss;
17362                            oomSwapPss[oomIndex] += myTotalSwapPss;
17363                            if (oomProcs[oomIndex] == null) {
17364                                oomProcs[oomIndex] = new ArrayList<MemItem>();
17365                            }
17366                            oomProcs[oomIndex].add(pssItem);
17367                            break;
17368                        }
17369                    }
17370                }
17371            }
17372        }
17373
17374        long nativeProcTotalPss = 0;
17375
17376        if (!isCheckinRequest && procs.size() > 1 && !packages) {
17377            // If we are showing aggregations, also look for native processes to
17378            // include so that our aggregations are more accurate.
17379            updateCpuStatsNow();
17380            mi = null;
17381            synchronized (mProcessCpuTracker) {
17382                final int N = mProcessCpuTracker.countStats();
17383                for (int i=0; i<N; i++) {
17384                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17385                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17386                        if (mi == null) {
17387                            mi = new Debug.MemoryInfo();
17388                        }
17389                        if (!brief && !oomOnly) {
17390                            Debug.getMemoryInfo(st.pid, mi);
17391                        } else {
17392                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17393                            mi.nativePrivateDirty = (int)tmpLong[0];
17394                        }
17395
17396                        final long myTotalPss = mi.getTotalPss();
17397                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17398                        totalPss += myTotalPss;
17399                        nativeProcTotalPss += myTotalPss;
17400
17401                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17402                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17403                        procMems.add(pssItem);
17404
17405                        nativePss += mi.nativePss;
17406                        nativeSwapPss += mi.nativeSwappedOutPss;
17407                        dalvikPss += mi.dalvikPss;
17408                        dalvikSwapPss += mi.dalvikSwappedOutPss;
17409                        for (int j=0; j<dalvikSubitemPss.length; j++) {
17410                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17411                            dalvikSubitemSwapPss[j] +=
17412                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17413                        }
17414                        otherPss += mi.otherPss;
17415                        otherSwapPss += mi.otherSwappedOutPss;
17416                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17417                            long mem = mi.getOtherPss(j);
17418                            miscPss[j] += mem;
17419                            otherPss -= mem;
17420                            mem = mi.getOtherSwappedOutPss(j);
17421                            miscSwapPss[j] += mem;
17422                            otherSwapPss -= mem;
17423                        }
17424                        oomPss[0] += myTotalPss;
17425                        oomSwapPss[0] += myTotalSwapPss;
17426                        if (oomProcs[0] == null) {
17427                            oomProcs[0] = new ArrayList<MemItem>();
17428                        }
17429                        oomProcs[0].add(pssItem);
17430                    }
17431                }
17432            }
17433
17434            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17435
17436            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17437            final int dalvikId = -2;
17438            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17439            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17440            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17441                String label = Debug.MemoryInfo.getOtherLabel(j);
17442                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17443            }
17444            if (dalvikSubitemPss.length > 0) {
17445                // Add dalvik subitems.
17446                for (MemItem memItem : catMems) {
17447                    int memItemStart = 0, memItemEnd = 0;
17448                    if (memItem.id == dalvikId) {
17449                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17450                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17451                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17452                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17453                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17454                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17455                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17456                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17457                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17458                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17459                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17460                    } else {
17461                        continue;  // No subitems, continue.
17462                    }
17463                    memItem.subitems = new ArrayList<MemItem>();
17464                    for (int j=memItemStart; j<=memItemEnd; j++) {
17465                        final String name = Debug.MemoryInfo.getOtherLabel(
17466                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
17467                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17468                                dalvikSubitemSwapPss[j], j));
17469                    }
17470                }
17471            }
17472
17473            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17474            for (int j=0; j<oomPss.length; j++) {
17475                if (oomPss[j] != 0) {
17476                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17477                            : DUMP_MEM_OOM_LABEL[j];
17478                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17479                            DUMP_MEM_OOM_ADJ[j]);
17480                    item.subitems = oomProcs[j];
17481                    oomMems.add(item);
17482                }
17483            }
17484
17485            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17486            if (!brief && !oomOnly && !isCompact) {
17487                pw.println();
17488                pw.println("Total PSS by process:");
17489                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17490                pw.println();
17491            }
17492            if (!isCompact) {
17493                pw.println("Total PSS by OOM adjustment:");
17494            }
17495            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17496            if (!brief && !oomOnly) {
17497                PrintWriter out = categoryPw != null ? categoryPw : pw;
17498                if (!isCompact) {
17499                    out.println();
17500                    out.println("Total PSS by category:");
17501                }
17502                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17503            }
17504            if (!isCompact) {
17505                pw.println();
17506            }
17507            MemInfoReader memInfo = new MemInfoReader();
17508            memInfo.readMemInfo();
17509            if (nativeProcTotalPss > 0) {
17510                synchronized (this) {
17511                    final long cachedKb = memInfo.getCachedSizeKb();
17512                    final long freeKb = memInfo.getFreeSizeKb();
17513                    final long zramKb = memInfo.getZramTotalSizeKb();
17514                    final long kernelKb = memInfo.getKernelUsedSizeKb();
17515                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17516                            kernelKb*1024, nativeProcTotalPss*1024);
17517                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17518                            nativeProcTotalPss);
17519                }
17520            }
17521            if (!brief) {
17522                if (!isCompact) {
17523                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17524                    pw.print(" (status ");
17525                    switch (mLastMemoryLevel) {
17526                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17527                            pw.println("normal)");
17528                            break;
17529                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17530                            pw.println("moderate)");
17531                            break;
17532                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
17533                            pw.println("low)");
17534                            break;
17535                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17536                            pw.println("critical)");
17537                            break;
17538                        default:
17539                            pw.print(mLastMemoryLevel);
17540                            pw.println(")");
17541                            break;
17542                    }
17543                    pw.print(" Free RAM: ");
17544                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17545                            + memInfo.getFreeSizeKb()));
17546                    pw.print(" (");
17547                    pw.print(stringifyKBSize(cachedPss));
17548                    pw.print(" cached pss + ");
17549                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17550                    pw.print(" cached kernel + ");
17551                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17552                    pw.println(" free)");
17553                } else {
17554                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17555                    pw.print(cachedPss + memInfo.getCachedSizeKb()
17556                            + memInfo.getFreeSizeKb()); pw.print(",");
17557                    pw.println(totalPss - cachedPss);
17558                }
17559            }
17560            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17561                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17562                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17563            if (!isCompact) {
17564                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17565                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17566                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17567                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17568                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17569            } else {
17570                pw.print("lostram,"); pw.println(lostRAM);
17571            }
17572            if (!brief) {
17573                if (memInfo.getZramTotalSizeKb() != 0) {
17574                    if (!isCompact) {
17575                        pw.print("     ZRAM: ");
17576                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17577                                pw.print(" physical used for ");
17578                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17579                                        - memInfo.getSwapFreeSizeKb()));
17580                                pw.print(" in swap (");
17581                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17582                                pw.println(" total swap)");
17583                    } else {
17584                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17585                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17586                                pw.println(memInfo.getSwapFreeSizeKb());
17587                    }
17588                }
17589                final long[] ksm = getKsmInfo();
17590                if (!isCompact) {
17591                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17592                            || ksm[KSM_VOLATILE] != 0) {
17593                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17594                                pw.print(" saved from shared ");
17595                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17596                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17597                                pw.print(" unshared; ");
17598                                pw.print(stringifyKBSize(
17599                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
17600                    }
17601                    pw.print("   Tuning: ");
17602                    pw.print(ActivityManager.staticGetMemoryClass());
17603                    pw.print(" (large ");
17604                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17605                    pw.print("), oom ");
17606                    pw.print(stringifySize(
17607                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17608                    pw.print(", restore limit ");
17609                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17610                    if (ActivityManager.isLowRamDeviceStatic()) {
17611                        pw.print(" (low-ram)");
17612                    }
17613                    if (ActivityManager.isHighEndGfx()) {
17614                        pw.print(" (high-end-gfx)");
17615                    }
17616                    pw.println();
17617                } else {
17618                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17619                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17620                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17621                    pw.print("tuning,");
17622                    pw.print(ActivityManager.staticGetMemoryClass());
17623                    pw.print(',');
17624                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17625                    pw.print(',');
17626                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17627                    if (ActivityManager.isLowRamDeviceStatic()) {
17628                        pw.print(",low-ram");
17629                    }
17630                    if (ActivityManager.isHighEndGfx()) {
17631                        pw.print(",high-end-gfx");
17632                    }
17633                    pw.println();
17634                }
17635            }
17636        }
17637    }
17638
17639    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17640            long memtrack, String name) {
17641        sb.append("  ");
17642        sb.append(ProcessList.makeOomAdjString(oomAdj));
17643        sb.append(' ');
17644        sb.append(ProcessList.makeProcStateString(procState));
17645        sb.append(' ');
17646        ProcessList.appendRamKb(sb, pss);
17647        sb.append(": ");
17648        sb.append(name);
17649        if (memtrack > 0) {
17650            sb.append(" (");
17651            sb.append(stringifyKBSize(memtrack));
17652            sb.append(" memtrack)");
17653        }
17654    }
17655
17656    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17657        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17658        sb.append(" (pid ");
17659        sb.append(mi.pid);
17660        sb.append(") ");
17661        sb.append(mi.adjType);
17662        sb.append('\n');
17663        if (mi.adjReason != null) {
17664            sb.append("                      ");
17665            sb.append(mi.adjReason);
17666            sb.append('\n');
17667        }
17668    }
17669
17670    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17671        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17672        for (int i=0, N=memInfos.size(); i<N; i++) {
17673            ProcessMemInfo mi = memInfos.get(i);
17674            infoMap.put(mi.pid, mi);
17675        }
17676        updateCpuStatsNow();
17677        long[] memtrackTmp = new long[1];
17678        final List<ProcessCpuTracker.Stats> stats;
17679        // Get a list of Stats that have vsize > 0
17680        synchronized (mProcessCpuTracker) {
17681            stats = mProcessCpuTracker.getStats((st) -> {
17682                return st.vsize > 0;
17683            });
17684        }
17685        final int statsCount = stats.size();
17686        for (int i = 0; i < statsCount; i++) {
17687            ProcessCpuTracker.Stats st = stats.get(i);
17688            long pss = Debug.getPss(st.pid, null, memtrackTmp);
17689            if (pss > 0) {
17690                if (infoMap.indexOfKey(st.pid) < 0) {
17691                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17692                            ProcessList.NATIVE_ADJ, -1, "native", null);
17693                    mi.pss = pss;
17694                    mi.memtrack = memtrackTmp[0];
17695                    memInfos.add(mi);
17696                }
17697            }
17698        }
17699
17700        long totalPss = 0;
17701        long totalMemtrack = 0;
17702        for (int i=0, N=memInfos.size(); i<N; i++) {
17703            ProcessMemInfo mi = memInfos.get(i);
17704            if (mi.pss == 0) {
17705                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17706                mi.memtrack = memtrackTmp[0];
17707            }
17708            totalPss += mi.pss;
17709            totalMemtrack += mi.memtrack;
17710        }
17711        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17712            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17713                if (lhs.oomAdj != rhs.oomAdj) {
17714                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17715                }
17716                if (lhs.pss != rhs.pss) {
17717                    return lhs.pss < rhs.pss ? 1 : -1;
17718                }
17719                return 0;
17720            }
17721        });
17722
17723        StringBuilder tag = new StringBuilder(128);
17724        StringBuilder stack = new StringBuilder(128);
17725        tag.append("Low on memory -- ");
17726        appendMemBucket(tag, totalPss, "total", false);
17727        appendMemBucket(stack, totalPss, "total", true);
17728
17729        StringBuilder fullNativeBuilder = new StringBuilder(1024);
17730        StringBuilder shortNativeBuilder = new StringBuilder(1024);
17731        StringBuilder fullJavaBuilder = new StringBuilder(1024);
17732
17733        boolean firstLine = true;
17734        int lastOomAdj = Integer.MIN_VALUE;
17735        long extraNativeRam = 0;
17736        long extraNativeMemtrack = 0;
17737        long cachedPss = 0;
17738        for (int i=0, N=memInfos.size(); i<N; i++) {
17739            ProcessMemInfo mi = memInfos.get(i);
17740
17741            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17742                cachedPss += mi.pss;
17743            }
17744
17745            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17746                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17747                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17748                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17749                if (lastOomAdj != mi.oomAdj) {
17750                    lastOomAdj = mi.oomAdj;
17751                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17752                        tag.append(" / ");
17753                    }
17754                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17755                        if (firstLine) {
17756                            stack.append(":");
17757                            firstLine = false;
17758                        }
17759                        stack.append("\n\t at ");
17760                    } else {
17761                        stack.append("$");
17762                    }
17763                } else {
17764                    tag.append(" ");
17765                    stack.append("$");
17766                }
17767                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17768                    appendMemBucket(tag, mi.pss, mi.name, false);
17769                }
17770                appendMemBucket(stack, mi.pss, mi.name, true);
17771                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17772                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17773                    stack.append("(");
17774                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17775                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17776                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17777                            stack.append(":");
17778                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17779                        }
17780                    }
17781                    stack.append(")");
17782                }
17783            }
17784
17785            appendMemInfo(fullNativeBuilder, mi);
17786            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17787                // The short form only has native processes that are >= 512K.
17788                if (mi.pss >= 512) {
17789                    appendMemInfo(shortNativeBuilder, mi);
17790                } else {
17791                    extraNativeRam += mi.pss;
17792                    extraNativeMemtrack += mi.memtrack;
17793                }
17794            } else {
17795                // Short form has all other details, but if we have collected RAM
17796                // from smaller native processes let's dump a summary of that.
17797                if (extraNativeRam > 0) {
17798                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17799                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17800                    shortNativeBuilder.append('\n');
17801                    extraNativeRam = 0;
17802                }
17803                appendMemInfo(fullJavaBuilder, mi);
17804            }
17805        }
17806
17807        fullJavaBuilder.append("           ");
17808        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17809        fullJavaBuilder.append(": TOTAL");
17810        if (totalMemtrack > 0) {
17811            fullJavaBuilder.append(" (");
17812            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17813            fullJavaBuilder.append(" memtrack)");
17814        } else {
17815        }
17816        fullJavaBuilder.append("\n");
17817
17818        MemInfoReader memInfo = new MemInfoReader();
17819        memInfo.readMemInfo();
17820        final long[] infos = memInfo.getRawInfo();
17821
17822        StringBuilder memInfoBuilder = new StringBuilder(1024);
17823        Debug.getMemInfo(infos);
17824        memInfoBuilder.append("  MemInfo: ");
17825        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17826        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17827        memInfoBuilder.append(stringifyKBSize(
17828                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17829        memInfoBuilder.append(stringifyKBSize(
17830                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17831        memInfoBuilder.append(stringifyKBSize(
17832                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17833        memInfoBuilder.append("           ");
17834        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17835        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17836        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17837        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17838        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17839            memInfoBuilder.append("  ZRAM: ");
17840            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17841            memInfoBuilder.append(" RAM, ");
17842            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17843            memInfoBuilder.append(" swap total, ");
17844            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17845            memInfoBuilder.append(" swap free\n");
17846        }
17847        final long[] ksm = getKsmInfo();
17848        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17849                || ksm[KSM_VOLATILE] != 0) {
17850            memInfoBuilder.append("  KSM: ");
17851            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17852            memInfoBuilder.append(" saved from shared ");
17853            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17854            memInfoBuilder.append("\n       ");
17855            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17856            memInfoBuilder.append(" unshared; ");
17857            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17858            memInfoBuilder.append(" volatile\n");
17859        }
17860        memInfoBuilder.append("  Free RAM: ");
17861        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17862                + memInfo.getFreeSizeKb()));
17863        memInfoBuilder.append("\n");
17864        memInfoBuilder.append("  Used RAM: ");
17865        memInfoBuilder.append(stringifyKBSize(
17866                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17867        memInfoBuilder.append("\n");
17868        memInfoBuilder.append("  Lost RAM: ");
17869        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17870                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17871                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17872        memInfoBuilder.append("\n");
17873        Slog.i(TAG, "Low on memory:");
17874        Slog.i(TAG, shortNativeBuilder.toString());
17875        Slog.i(TAG, fullJavaBuilder.toString());
17876        Slog.i(TAG, memInfoBuilder.toString());
17877
17878        StringBuilder dropBuilder = new StringBuilder(1024);
17879        /*
17880        StringWriter oomSw = new StringWriter();
17881        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17882        StringWriter catSw = new StringWriter();
17883        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17884        String[] emptyArgs = new String[] { };
17885        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17886        oomPw.flush();
17887        String oomString = oomSw.toString();
17888        */
17889        dropBuilder.append("Low on memory:");
17890        dropBuilder.append(stack);
17891        dropBuilder.append('\n');
17892        dropBuilder.append(fullNativeBuilder);
17893        dropBuilder.append(fullJavaBuilder);
17894        dropBuilder.append('\n');
17895        dropBuilder.append(memInfoBuilder);
17896        dropBuilder.append('\n');
17897        /*
17898        dropBuilder.append(oomString);
17899        dropBuilder.append('\n');
17900        */
17901        StringWriter catSw = new StringWriter();
17902        synchronized (ActivityManagerService.this) {
17903            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17904            String[] emptyArgs = new String[] { };
17905            catPw.println();
17906            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17907            catPw.println();
17908            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17909                    false, null).dumpLocked();
17910            catPw.println();
17911            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17912            catPw.flush();
17913        }
17914        dropBuilder.append(catSw.toString());
17915        addErrorToDropBox("lowmem", null, "system_server", null,
17916                null, tag.toString(), dropBuilder.toString(), null, null);
17917        //Slog.i(TAG, "Sent to dropbox:");
17918        //Slog.i(TAG, dropBuilder.toString());
17919        synchronized (ActivityManagerService.this) {
17920            long now = SystemClock.uptimeMillis();
17921            if (mLastMemUsageReportTime < now) {
17922                mLastMemUsageReportTime = now;
17923            }
17924        }
17925    }
17926
17927    /**
17928     * Searches array of arguments for the specified string
17929     * @param args array of argument strings
17930     * @param value value to search for
17931     * @return true if the value is contained in the array
17932     */
17933    private static boolean scanArgs(String[] args, String value) {
17934        if (args != null) {
17935            for (String arg : args) {
17936                if (value.equals(arg)) {
17937                    return true;
17938                }
17939            }
17940        }
17941        return false;
17942    }
17943
17944    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17945            ContentProviderRecord cpr, boolean always) {
17946        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17947
17948        if (!inLaunching || always) {
17949            synchronized (cpr) {
17950                cpr.launchingApp = null;
17951                cpr.notifyAll();
17952            }
17953            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17954            String names[] = cpr.info.authority.split(";");
17955            for (int j = 0; j < names.length; j++) {
17956                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17957            }
17958        }
17959
17960        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17961            ContentProviderConnection conn = cpr.connections.get(i);
17962            if (conn.waiting) {
17963                // If this connection is waiting for the provider, then we don't
17964                // need to mess with its process unless we are always removing
17965                // or for some reason the provider is not currently launching.
17966                if (inLaunching && !always) {
17967                    continue;
17968                }
17969            }
17970            ProcessRecord capp = conn.client;
17971            conn.dead = true;
17972            if (conn.stableCount > 0) {
17973                if (!capp.persistent && capp.thread != null
17974                        && capp.pid != 0
17975                        && capp.pid != MY_PID) {
17976                    capp.kill("depends on provider "
17977                            + cpr.name.flattenToShortString()
17978                            + " in dying proc " + (proc != null ? proc.processName : "??")
17979                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17980                }
17981            } else if (capp.thread != null && conn.provider.provider != null) {
17982                try {
17983                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17984                } catch (RemoteException e) {
17985                }
17986                // In the protocol here, we don't expect the client to correctly
17987                // clean up this connection, we'll just remove it.
17988                cpr.connections.remove(i);
17989                if (conn.client.conProviders.remove(conn)) {
17990                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17991                }
17992            }
17993        }
17994
17995        if (inLaunching && always) {
17996            mLaunchingProviders.remove(cpr);
17997        }
17998        return inLaunching;
17999    }
18000
18001    /**
18002     * Main code for cleaning up a process when it has gone away.  This is
18003     * called both as a result of the process dying, or directly when stopping
18004     * a process when running in single process mode.
18005     *
18006     * @return Returns true if the given process has been restarted, so the
18007     * app that was passed in must remain on the process lists.
18008     */
18009    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18010            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18011        if (index >= 0) {
18012            removeLruProcessLocked(app);
18013            ProcessList.remove(app.pid);
18014        }
18015
18016        mProcessesToGc.remove(app);
18017        mPendingPssProcesses.remove(app);
18018
18019        // Dismiss any open dialogs.
18020        if (app.crashDialog != null && !app.forceCrashReport) {
18021            app.crashDialog.dismiss();
18022            app.crashDialog = null;
18023        }
18024        if (app.anrDialog != null) {
18025            app.anrDialog.dismiss();
18026            app.anrDialog = null;
18027        }
18028        if (app.waitDialog != null) {
18029            app.waitDialog.dismiss();
18030            app.waitDialog = null;
18031        }
18032
18033        app.crashing = false;
18034        app.notResponding = false;
18035
18036        app.resetPackageList(mProcessStats);
18037        app.unlinkDeathRecipient();
18038        app.makeInactive(mProcessStats);
18039        app.waitingToKill = null;
18040        app.forcingToImportant = null;
18041        updateProcessForegroundLocked(app, false, false);
18042        app.foregroundActivities = false;
18043        app.hasShownUi = false;
18044        app.treatLikeActivity = false;
18045        app.hasAboveClient = false;
18046        app.hasClientActivities = false;
18047
18048        mServices.killServicesLocked(app, allowRestart);
18049
18050        boolean restart = false;
18051
18052        // Remove published content providers.
18053        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18054            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18055            final boolean always = app.bad || !allowRestart;
18056            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18057            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18058                // We left the provider in the launching list, need to
18059                // restart it.
18060                restart = true;
18061            }
18062
18063            cpr.provider = null;
18064            cpr.proc = null;
18065        }
18066        app.pubProviders.clear();
18067
18068        // Take care of any launching providers waiting for this process.
18069        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18070            restart = true;
18071        }
18072
18073        // Unregister from connected content providers.
18074        if (!app.conProviders.isEmpty()) {
18075            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18076                ContentProviderConnection conn = app.conProviders.get(i);
18077                conn.provider.connections.remove(conn);
18078                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18079                        conn.provider.name);
18080            }
18081            app.conProviders.clear();
18082        }
18083
18084        // At this point there may be remaining entries in mLaunchingProviders
18085        // where we were the only one waiting, so they are no longer of use.
18086        // Look for these and clean up if found.
18087        // XXX Commented out for now.  Trying to figure out a way to reproduce
18088        // the actual situation to identify what is actually going on.
18089        if (false) {
18090            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18091                ContentProviderRecord cpr = mLaunchingProviders.get(i);
18092                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18093                    synchronized (cpr) {
18094                        cpr.launchingApp = null;
18095                        cpr.notifyAll();
18096                    }
18097                }
18098            }
18099        }
18100
18101        skipCurrentReceiverLocked(app);
18102
18103        // Unregister any receivers.
18104        for (int i = app.receivers.size() - 1; i >= 0; i--) {
18105            removeReceiverLocked(app.receivers.valueAt(i));
18106        }
18107        app.receivers.clear();
18108
18109        // If the app is undergoing backup, tell the backup manager about it
18110        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18111            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18112                    + mBackupTarget.appInfo + " died during backup");
18113            mHandler.post(new Runnable() {
18114                @Override
18115                public void run(){
18116                    try {
18117                        IBackupManager bm = IBackupManager.Stub.asInterface(
18118                                ServiceManager.getService(Context.BACKUP_SERVICE));
18119                        bm.agentDisconnected(app.info.packageName);
18120                    } catch (RemoteException e) {
18121                        // can't happen; backup manager is local
18122                    }
18123                }
18124            });
18125        }
18126
18127        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18128            ProcessChangeItem item = mPendingProcessChanges.get(i);
18129            if (item.pid == app.pid) {
18130                mPendingProcessChanges.remove(i);
18131                mAvailProcessChanges.add(item);
18132            }
18133        }
18134        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18135                null).sendToTarget();
18136
18137        // If the caller is restarting this app, then leave it in its
18138        // current lists and let the caller take care of it.
18139        if (restarting) {
18140            return false;
18141        }
18142
18143        if (!app.persistent || app.isolated) {
18144            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18145                    "Removing non-persistent process during cleanup: " + app);
18146            if (!replacingPid) {
18147                removeProcessNameLocked(app.processName, app.uid, app);
18148            }
18149            if (mHeavyWeightProcess == app) {
18150                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18151                        mHeavyWeightProcess.userId, 0));
18152                mHeavyWeightProcess = null;
18153            }
18154        } else if (!app.removed) {
18155            // This app is persistent, so we need to keep its record around.
18156            // If it is not already on the pending app list, add it there
18157            // and start a new process for it.
18158            if (mPersistentStartingProcesses.indexOf(app) < 0) {
18159                mPersistentStartingProcesses.add(app);
18160                restart = true;
18161            }
18162        }
18163        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18164                TAG_CLEANUP, "Clean-up removing on hold: " + app);
18165        mProcessesOnHold.remove(app);
18166
18167        if (app == mHomeProcess) {
18168            mHomeProcess = null;
18169        }
18170        if (app == mPreviousProcess) {
18171            mPreviousProcess = null;
18172        }
18173
18174        if (restart && !app.isolated) {
18175            // We have components that still need to be running in the
18176            // process, so re-launch it.
18177            if (index < 0) {
18178                ProcessList.remove(app.pid);
18179            }
18180            addProcessNameLocked(app);
18181            startProcessLocked(app, "restart", app.processName);
18182            return true;
18183        } else if (app.pid > 0 && app.pid != MY_PID) {
18184            // Goodbye!
18185            boolean removed;
18186            synchronized (mPidsSelfLocked) {
18187                mPidsSelfLocked.remove(app.pid);
18188                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18189            }
18190            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18191            if (app.isolated) {
18192                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18193            }
18194            app.setPid(0);
18195        }
18196        return false;
18197    }
18198
18199    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18200        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18201            ContentProviderRecord cpr = mLaunchingProviders.get(i);
18202            if (cpr.launchingApp == app) {
18203                return true;
18204            }
18205        }
18206        return false;
18207    }
18208
18209    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18210        // Look through the content providers we are waiting to have launched,
18211        // and if any run in this process then either schedule a restart of
18212        // the process or kill the client waiting for it if this process has
18213        // gone bad.
18214        boolean restart = false;
18215        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18216            ContentProviderRecord cpr = mLaunchingProviders.get(i);
18217            if (cpr.launchingApp == app) {
18218                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18219                    restart = true;
18220                } else {
18221                    removeDyingProviderLocked(app, cpr, true);
18222                }
18223            }
18224        }
18225        return restart;
18226    }
18227
18228    // =========================================================
18229    // SERVICES
18230    // =========================================================
18231
18232    @Override
18233    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18234            int flags) {
18235        enforceNotIsolatedCaller("getServices");
18236
18237        final int callingUid = Binder.getCallingUid();
18238        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18239            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18240        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18241            callingUid);
18242        synchronized (this) {
18243            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18244                allowed, canInteractAcrossUsers);
18245        }
18246    }
18247
18248    @Override
18249    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18250        enforceNotIsolatedCaller("getRunningServiceControlPanel");
18251        synchronized (this) {
18252            return mServices.getRunningServiceControlPanelLocked(name);
18253        }
18254    }
18255
18256    @Override
18257    public ComponentName startService(IApplicationThread caller, Intent service,
18258            String resolvedType, boolean requireForeground, String callingPackage, int userId)
18259            throws TransactionTooLargeException {
18260        enforceNotIsolatedCaller("startService");
18261        // Refuse possible leaked file descriptors
18262        if (service != null && service.hasFileDescriptors() == true) {
18263            throw new IllegalArgumentException("File descriptors passed in Intent");
18264        }
18265
18266        if (callingPackage == null) {
18267            throw new IllegalArgumentException("callingPackage cannot be null");
18268        }
18269
18270        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18271                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18272        synchronized(this) {
18273            final int callingPid = Binder.getCallingPid();
18274            final int callingUid = Binder.getCallingUid();
18275            final long origId = Binder.clearCallingIdentity();
18276            ComponentName res;
18277            try {
18278                res = mServices.startServiceLocked(caller, service,
18279                        resolvedType, callingPid, callingUid,
18280                        requireForeground, callingPackage, userId);
18281            } finally {
18282                Binder.restoreCallingIdentity(origId);
18283            }
18284            return res;
18285        }
18286    }
18287
18288    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18289            boolean fgRequired, String callingPackage, int userId)
18290            throws TransactionTooLargeException {
18291        synchronized(this) {
18292            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18293                    "startServiceInPackage: " + service + " type=" + resolvedType);
18294            final long origId = Binder.clearCallingIdentity();
18295            ComponentName res;
18296            try {
18297                res = mServices.startServiceLocked(null, service,
18298                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
18299            } finally {
18300                Binder.restoreCallingIdentity(origId);
18301            }
18302            return res;
18303        }
18304    }
18305
18306    @Override
18307    public int stopService(IApplicationThread caller, Intent service,
18308            String resolvedType, int userId) {
18309        enforceNotIsolatedCaller("stopService");
18310        // Refuse possible leaked file descriptors
18311        if (service != null && service.hasFileDescriptors() == true) {
18312            throw new IllegalArgumentException("File descriptors passed in Intent");
18313        }
18314
18315        synchronized(this) {
18316            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18317        }
18318    }
18319
18320    @Override
18321    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18322        enforceNotIsolatedCaller("peekService");
18323        // Refuse possible leaked file descriptors
18324        if (service != null && service.hasFileDescriptors() == true) {
18325            throw new IllegalArgumentException("File descriptors passed in Intent");
18326        }
18327
18328        if (callingPackage == null) {
18329            throw new IllegalArgumentException("callingPackage cannot be null");
18330        }
18331
18332        synchronized(this) {
18333            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18334        }
18335    }
18336
18337    @Override
18338    public boolean stopServiceToken(ComponentName className, IBinder token,
18339            int startId) {
18340        synchronized(this) {
18341            return mServices.stopServiceTokenLocked(className, token, startId);
18342        }
18343    }
18344
18345    @Override
18346    public void setServiceForeground(ComponentName className, IBinder token,
18347            int id, Notification notification, int flags) {
18348        synchronized(this) {
18349            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18350        }
18351    }
18352
18353    @Override
18354    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18355            boolean requireFull, String name, String callerPackage) {
18356        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18357                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18358    }
18359
18360    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18361            String className, int flags) {
18362        boolean result = false;
18363        // For apps that don't have pre-defined UIDs, check for permission
18364        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18365            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18366                if (ActivityManager.checkUidPermission(
18367                        INTERACT_ACROSS_USERS,
18368                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18369                    ComponentName comp = new ComponentName(aInfo.packageName, className);
18370                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
18371                            + " requests FLAG_SINGLE_USER, but app does not hold "
18372                            + INTERACT_ACROSS_USERS;
18373                    Slog.w(TAG, msg);
18374                    throw new SecurityException(msg);
18375                }
18376                // Permission passed
18377                result = true;
18378            }
18379        } else if ("system".equals(componentProcessName)) {
18380            result = true;
18381        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18382            // Phone app and persistent apps are allowed to export singleuser providers.
18383            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18384                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18385        }
18386        if (DEBUG_MU) Slog.v(TAG_MU,
18387                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18388                + Integer.toHexString(flags) + ") = " + result);
18389        return result;
18390    }
18391
18392    /**
18393     * Checks to see if the caller is in the same app as the singleton
18394     * component, or the component is in a special app. It allows special apps
18395     * to export singleton components but prevents exporting singleton
18396     * components for regular apps.
18397     */
18398    boolean isValidSingletonCall(int callingUid, int componentUid) {
18399        int componentAppId = UserHandle.getAppId(componentUid);
18400        return UserHandle.isSameApp(callingUid, componentUid)
18401                || componentAppId == SYSTEM_UID
18402                || componentAppId == PHONE_UID
18403                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18404                        == PackageManager.PERMISSION_GRANTED;
18405    }
18406
18407    public int bindService(IApplicationThread caller, IBinder token, Intent service,
18408            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18409            int userId) throws TransactionTooLargeException {
18410        enforceNotIsolatedCaller("bindService");
18411
18412        // Refuse possible leaked file descriptors
18413        if (service != null && service.hasFileDescriptors() == true) {
18414            throw new IllegalArgumentException("File descriptors passed in Intent");
18415        }
18416
18417        if (callingPackage == null) {
18418            throw new IllegalArgumentException("callingPackage cannot be null");
18419        }
18420
18421        synchronized(this) {
18422            return mServices.bindServiceLocked(caller, token, service,
18423                    resolvedType, connection, flags, callingPackage, userId);
18424        }
18425    }
18426
18427    public boolean unbindService(IServiceConnection connection) {
18428        synchronized (this) {
18429            return mServices.unbindServiceLocked(connection);
18430        }
18431    }
18432
18433    public void publishService(IBinder token, Intent intent, IBinder service) {
18434        // Refuse possible leaked file descriptors
18435        if (intent != null && intent.hasFileDescriptors() == true) {
18436            throw new IllegalArgumentException("File descriptors passed in Intent");
18437        }
18438
18439        synchronized(this) {
18440            if (!(token instanceof ServiceRecord)) {
18441                throw new IllegalArgumentException("Invalid service token");
18442            }
18443            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18444        }
18445    }
18446
18447    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18448        // Refuse possible leaked file descriptors
18449        if (intent != null && intent.hasFileDescriptors() == true) {
18450            throw new IllegalArgumentException("File descriptors passed in Intent");
18451        }
18452
18453        synchronized(this) {
18454            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18455        }
18456    }
18457
18458    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18459        synchronized(this) {
18460            if (!(token instanceof ServiceRecord)) {
18461                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18462                throw new IllegalArgumentException("Invalid service token");
18463            }
18464            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18465        }
18466    }
18467
18468    // =========================================================
18469    // BACKUP AND RESTORE
18470    // =========================================================
18471
18472    // Cause the target app to be launched if necessary and its backup agent
18473    // instantiated.  The backup agent will invoke backupAgentCreated() on the
18474    // activity manager to announce its creation.
18475    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18476        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18477        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18478
18479        IPackageManager pm = AppGlobals.getPackageManager();
18480        ApplicationInfo app = null;
18481        try {
18482            app = pm.getApplicationInfo(packageName, 0, userId);
18483        } catch (RemoteException e) {
18484            // can't happen; package manager is process-local
18485        }
18486        if (app == null) {
18487            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18488            return false;
18489        }
18490
18491        int oldBackupUid;
18492        int newBackupUid;
18493
18494        synchronized(this) {
18495            // !!! TODO: currently no check here that we're already bound
18496            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18497            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18498            synchronized (stats) {
18499                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18500            }
18501
18502            // Backup agent is now in use, its package can't be stopped.
18503            try {
18504                AppGlobals.getPackageManager().setPackageStoppedState(
18505                        app.packageName, false, UserHandle.getUserId(app.uid));
18506            } catch (RemoteException e) {
18507            } catch (IllegalArgumentException e) {
18508                Slog.w(TAG, "Failed trying to unstop package "
18509                        + app.packageName + ": " + e);
18510            }
18511
18512            BackupRecord r = new BackupRecord(ss, app, backupMode);
18513            ComponentName hostingName =
18514                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18515                            ? new ComponentName(app.packageName, app.backupAgentName)
18516                            : new ComponentName("android", "FullBackupAgent");
18517            // startProcessLocked() returns existing proc's record if it's already running
18518            ProcessRecord proc = startProcessLocked(app.processName, app,
18519                    false, 0, "backup", hostingName, false, false, false);
18520            if (proc == null) {
18521                Slog.e(TAG, "Unable to start backup agent process " + r);
18522                return false;
18523            }
18524
18525            // If the app is a regular app (uid >= 10000) and not the system server or phone
18526            // process, etc, then mark it as being in full backup so that certain calls to the
18527            // process can be blocked. This is not reset to false anywhere because we kill the
18528            // process after the full backup is done and the ProcessRecord will vaporize anyway.
18529            if (UserHandle.isApp(app.uid) &&
18530                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18531                proc.inFullBackup = true;
18532            }
18533            r.app = proc;
18534            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18535            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18536            mBackupTarget = r;
18537            mBackupAppName = app.packageName;
18538
18539            // Try not to kill the process during backup
18540            updateOomAdjLocked(proc, true);
18541
18542            // If the process is already attached, schedule the creation of the backup agent now.
18543            // If it is not yet live, this will be done when it attaches to the framework.
18544            if (proc.thread != null) {
18545                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18546                try {
18547                    proc.thread.scheduleCreateBackupAgent(app,
18548                            compatibilityInfoForPackageLocked(app), backupMode);
18549                } catch (RemoteException e) {
18550                    // Will time out on the backup manager side
18551                }
18552            } else {
18553                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18554            }
18555            // Invariants: at this point, the target app process exists and the application
18556            // is either already running or in the process of coming up.  mBackupTarget and
18557            // mBackupAppName describe the app, so that when it binds back to the AM we
18558            // know that it's scheduled for a backup-agent operation.
18559        }
18560
18561        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18562        if (oldBackupUid != -1) {
18563            js.removeBackingUpUid(oldBackupUid);
18564        }
18565        if (newBackupUid != -1) {
18566            js.addBackingUpUid(newBackupUid);
18567        }
18568
18569        return true;
18570    }
18571
18572    @Override
18573    public void clearPendingBackup() {
18574        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18575        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18576
18577        synchronized (this) {
18578            mBackupTarget = null;
18579            mBackupAppName = null;
18580        }
18581
18582        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18583        js.clearAllBackingUpUids();
18584    }
18585
18586    // A backup agent has just come up
18587    public void backupAgentCreated(String agentPackageName, IBinder agent) {
18588        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18589                + " = " + agent);
18590
18591        synchronized(this) {
18592            if (!agentPackageName.equals(mBackupAppName)) {
18593                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18594                return;
18595            }
18596        }
18597
18598        long oldIdent = Binder.clearCallingIdentity();
18599        try {
18600            IBackupManager bm = IBackupManager.Stub.asInterface(
18601                    ServiceManager.getService(Context.BACKUP_SERVICE));
18602            bm.agentConnected(agentPackageName, agent);
18603        } catch (RemoteException e) {
18604            // can't happen; the backup manager service is local
18605        } catch (Exception e) {
18606            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18607            e.printStackTrace();
18608        } finally {
18609            Binder.restoreCallingIdentity(oldIdent);
18610        }
18611    }
18612
18613    // done with this agent
18614    public void unbindBackupAgent(ApplicationInfo appInfo) {
18615        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18616        if (appInfo == null) {
18617            Slog.w(TAG, "unbind backup agent for null app");
18618            return;
18619        }
18620
18621        int oldBackupUid;
18622
18623        synchronized(this) {
18624            try {
18625                if (mBackupAppName == null) {
18626                    Slog.w(TAG, "Unbinding backup agent with no active backup");
18627                    return;
18628                }
18629
18630                if (!mBackupAppName.equals(appInfo.packageName)) {
18631                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18632                    return;
18633                }
18634
18635                // Not backing this app up any more; reset its OOM adjustment
18636                final ProcessRecord proc = mBackupTarget.app;
18637                updateOomAdjLocked(proc, true);
18638                proc.inFullBackup = false;
18639
18640                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18641
18642                // If the app crashed during backup, 'thread' will be null here
18643                if (proc.thread != null) {
18644                    try {
18645                        proc.thread.scheduleDestroyBackupAgent(appInfo,
18646                                compatibilityInfoForPackageLocked(appInfo));
18647                    } catch (Exception e) {
18648                        Slog.e(TAG, "Exception when unbinding backup agent:");
18649                        e.printStackTrace();
18650                    }
18651                }
18652            } finally {
18653                mBackupTarget = null;
18654                mBackupAppName = null;
18655            }
18656        }
18657
18658        if (oldBackupUid != -1) {
18659            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18660            js.removeBackingUpUid(oldBackupUid);
18661        }
18662    }
18663
18664    // =========================================================
18665    // BROADCASTS
18666    // =========================================================
18667
18668    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18669        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18670            return false;
18671        }
18672        // Easy case -- we have the app's ProcessRecord.
18673        if (record != null) {
18674            return record.info.isInstantApp();
18675        }
18676        // Otherwise check with PackageManager.
18677        if (callerPackage == null) {
18678            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18679            throw new IllegalArgumentException("Calling application did not provide package name");
18680        }
18681        mAppOpsService.checkPackage(uid, callerPackage);
18682        try {
18683            IPackageManager pm = AppGlobals.getPackageManager();
18684            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18685        } catch (RemoteException e) {
18686            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18687            return true;
18688        }
18689    }
18690
18691    boolean isPendingBroadcastProcessLocked(int pid) {
18692        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18693                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18694    }
18695
18696    void skipPendingBroadcastLocked(int pid) {
18697            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18698            for (BroadcastQueue queue : mBroadcastQueues) {
18699                queue.skipPendingBroadcastLocked(pid);
18700            }
18701    }
18702
18703    // The app just attached; send any pending broadcasts that it should receive
18704    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18705        boolean didSomething = false;
18706        for (BroadcastQueue queue : mBroadcastQueues) {
18707            didSomething |= queue.sendPendingBroadcastsLocked(app);
18708        }
18709        return didSomething;
18710    }
18711
18712    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18713            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18714            int flags) {
18715        enforceNotIsolatedCaller("registerReceiver");
18716        ArrayList<Intent> stickyIntents = null;
18717        ProcessRecord callerApp = null;
18718        final boolean visibleToInstantApps
18719                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18720        int callingUid;
18721        int callingPid;
18722        boolean instantApp;
18723        synchronized(this) {
18724            if (caller != null) {
18725                callerApp = getRecordForAppLocked(caller);
18726                if (callerApp == null) {
18727                    throw new SecurityException(
18728                            "Unable to find app for caller " + caller
18729                            + " (pid=" + Binder.getCallingPid()
18730                            + ") when registering receiver " + receiver);
18731                }
18732                if (callerApp.info.uid != SYSTEM_UID &&
18733                        !callerApp.pkgList.containsKey(callerPackage) &&
18734                        !"android".equals(callerPackage)) {
18735                    throw new SecurityException("Given caller package " + callerPackage
18736                            + " is not running in process " + callerApp);
18737                }
18738                callingUid = callerApp.info.uid;
18739                callingPid = callerApp.pid;
18740            } else {
18741                callerPackage = null;
18742                callingUid = Binder.getCallingUid();
18743                callingPid = Binder.getCallingPid();
18744            }
18745
18746            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18747            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18748                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18749
18750            Iterator<String> actions = filter.actionsIterator();
18751            if (actions == null) {
18752                ArrayList<String> noAction = new ArrayList<String>(1);
18753                noAction.add(null);
18754                actions = noAction.iterator();
18755            }
18756
18757            // Collect stickies of users
18758            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18759            while (actions.hasNext()) {
18760                String action = actions.next();
18761                for (int id : userIds) {
18762                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18763                    if (stickies != null) {
18764                        ArrayList<Intent> intents = stickies.get(action);
18765                        if (intents != null) {
18766                            if (stickyIntents == null) {
18767                                stickyIntents = new ArrayList<Intent>();
18768                            }
18769                            stickyIntents.addAll(intents);
18770                        }
18771                    }
18772                }
18773            }
18774        }
18775
18776        ArrayList<Intent> allSticky = null;
18777        if (stickyIntents != null) {
18778            final ContentResolver resolver = mContext.getContentResolver();
18779            // Look for any matching sticky broadcasts...
18780            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18781                Intent intent = stickyIntents.get(i);
18782                // Don't provided intents that aren't available to instant apps.
18783                if (instantApp &&
18784                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18785                    continue;
18786                }
18787                // If intent has scheme "content", it will need to acccess
18788                // provider that needs to lock mProviderMap in ActivityThread
18789                // and also it may need to wait application response, so we
18790                // cannot lock ActivityManagerService here.
18791                if (filter.match(resolver, intent, true, TAG) >= 0) {
18792                    if (allSticky == null) {
18793                        allSticky = new ArrayList<Intent>();
18794                    }
18795                    allSticky.add(intent);
18796                }
18797            }
18798        }
18799
18800        // The first sticky in the list is returned directly back to the client.
18801        Intent sticky = allSticky != null ? allSticky.get(0) : null;
18802        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18803        if (receiver == null) {
18804            return sticky;
18805        }
18806
18807        synchronized (this) {
18808            if (callerApp != null && (callerApp.thread == null
18809                    || callerApp.thread.asBinder() != caller.asBinder())) {
18810                // Original caller already died
18811                return null;
18812            }
18813            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18814            if (rl == null) {
18815                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18816                        userId, receiver);
18817                if (rl.app != null) {
18818                    rl.app.receivers.add(rl);
18819                } else {
18820                    try {
18821                        receiver.asBinder().linkToDeath(rl, 0);
18822                    } catch (RemoteException e) {
18823                        return sticky;
18824                    }
18825                    rl.linkedToDeath = true;
18826                }
18827                mRegisteredReceivers.put(receiver.asBinder(), rl);
18828            } else if (rl.uid != callingUid) {
18829                throw new IllegalArgumentException(
18830                        "Receiver requested to register for uid " + callingUid
18831                        + " was previously registered for uid " + rl.uid
18832                        + " callerPackage is " + callerPackage);
18833            } else if (rl.pid != callingPid) {
18834                throw new IllegalArgumentException(
18835                        "Receiver requested to register for pid " + callingPid
18836                        + " was previously registered for pid " + rl.pid
18837                        + " callerPackage is " + callerPackage);
18838            } else if (rl.userId != userId) {
18839                throw new IllegalArgumentException(
18840                        "Receiver requested to register for user " + userId
18841                        + " was previously registered for user " + rl.userId
18842                        + " callerPackage is " + callerPackage);
18843            }
18844            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18845                    permission, callingUid, userId, instantApp, visibleToInstantApps);
18846            rl.add(bf);
18847            if (!bf.debugCheck()) {
18848                Slog.w(TAG, "==> For Dynamic broadcast");
18849            }
18850            mReceiverResolver.addFilter(bf);
18851
18852            // Enqueue broadcasts for all existing stickies that match
18853            // this filter.
18854            if (allSticky != null) {
18855                ArrayList receivers = new ArrayList();
18856                receivers.add(bf);
18857
18858                final int stickyCount = allSticky.size();
18859                for (int i = 0; i < stickyCount; i++) {
18860                    Intent intent = allSticky.get(i);
18861                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18862                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18863                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18864                            null, 0, null, null, false, true, true, -1);
18865                    queue.enqueueParallelBroadcastLocked(r);
18866                    queue.scheduleBroadcastsLocked();
18867                }
18868            }
18869
18870            return sticky;
18871        }
18872    }
18873
18874    public void unregisterReceiver(IIntentReceiver receiver) {
18875        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18876
18877        final long origId = Binder.clearCallingIdentity();
18878        try {
18879            boolean doTrim = false;
18880
18881            synchronized(this) {
18882                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18883                if (rl != null) {
18884                    final BroadcastRecord r = rl.curBroadcast;
18885                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18886                        final boolean doNext = r.queue.finishReceiverLocked(
18887                                r, r.resultCode, r.resultData, r.resultExtras,
18888                                r.resultAbort, false);
18889                        if (doNext) {
18890                            doTrim = true;
18891                            r.queue.processNextBroadcast(false);
18892                        }
18893                    }
18894
18895                    if (rl.app != null) {
18896                        rl.app.receivers.remove(rl);
18897                    }
18898                    removeReceiverLocked(rl);
18899                    if (rl.linkedToDeath) {
18900                        rl.linkedToDeath = false;
18901                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18902                    }
18903                }
18904            }
18905
18906            // If we actually concluded any broadcasts, we might now be able
18907            // to trim the recipients' apps from our working set
18908            if (doTrim) {
18909                trimApplications();
18910                return;
18911            }
18912
18913        } finally {
18914            Binder.restoreCallingIdentity(origId);
18915        }
18916    }
18917
18918    void removeReceiverLocked(ReceiverList rl) {
18919        mRegisteredReceivers.remove(rl.receiver.asBinder());
18920        for (int i = rl.size() - 1; i >= 0; i--) {
18921            mReceiverResolver.removeFilter(rl.get(i));
18922        }
18923    }
18924
18925    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18926        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18927            ProcessRecord r = mLruProcesses.get(i);
18928            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18929                try {
18930                    r.thread.dispatchPackageBroadcast(cmd, packages);
18931                } catch (RemoteException ex) {
18932                }
18933            }
18934        }
18935    }
18936
18937    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18938            int callingUid, int[] users) {
18939        // TODO: come back and remove this assumption to triage all broadcasts
18940        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18941
18942        List<ResolveInfo> receivers = null;
18943        try {
18944            HashSet<ComponentName> singleUserReceivers = null;
18945            boolean scannedFirstReceivers = false;
18946            for (int user : users) {
18947                // Skip users that have Shell restrictions, with exception of always permitted
18948                // Shell broadcasts
18949                if (callingUid == SHELL_UID
18950                        && mUserController.hasUserRestriction(
18951                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18952                        && !isPermittedShellBroadcast(intent)) {
18953                    continue;
18954                }
18955                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18956                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18957                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18958                    // If this is not the system user, we need to check for
18959                    // any receivers that should be filtered out.
18960                    for (int i=0; i<newReceivers.size(); i++) {
18961                        ResolveInfo ri = newReceivers.get(i);
18962                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18963                            newReceivers.remove(i);
18964                            i--;
18965                        }
18966                    }
18967                }
18968                if (newReceivers != null && newReceivers.size() == 0) {
18969                    newReceivers = null;
18970                }
18971                if (receivers == null) {
18972                    receivers = newReceivers;
18973                } else if (newReceivers != null) {
18974                    // We need to concatenate the additional receivers
18975                    // found with what we have do far.  This would be easy,
18976                    // but we also need to de-dup any receivers that are
18977                    // singleUser.
18978                    if (!scannedFirstReceivers) {
18979                        // Collect any single user receivers we had already retrieved.
18980                        scannedFirstReceivers = true;
18981                        for (int i=0; i<receivers.size(); i++) {
18982                            ResolveInfo ri = receivers.get(i);
18983                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18984                                ComponentName cn = new ComponentName(
18985                                        ri.activityInfo.packageName, ri.activityInfo.name);
18986                                if (singleUserReceivers == null) {
18987                                    singleUserReceivers = new HashSet<ComponentName>();
18988                                }
18989                                singleUserReceivers.add(cn);
18990                            }
18991                        }
18992                    }
18993                    // Add the new results to the existing results, tracking
18994                    // and de-dupping single user receivers.
18995                    for (int i=0; i<newReceivers.size(); i++) {
18996                        ResolveInfo ri = newReceivers.get(i);
18997                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18998                            ComponentName cn = new ComponentName(
18999                                    ri.activityInfo.packageName, ri.activityInfo.name);
19000                            if (singleUserReceivers == null) {
19001                                singleUserReceivers = new HashSet<ComponentName>();
19002                            }
19003                            if (!singleUserReceivers.contains(cn)) {
19004                                singleUserReceivers.add(cn);
19005                                receivers.add(ri);
19006                            }
19007                        } else {
19008                            receivers.add(ri);
19009                        }
19010                    }
19011                }
19012            }
19013        } catch (RemoteException ex) {
19014            // pm is in same process, this will never happen.
19015        }
19016        return receivers;
19017    }
19018
19019    private boolean isPermittedShellBroadcast(Intent intent) {
19020        // remote bugreport should always be allowed to be taken
19021        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19022    }
19023
19024    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19025            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19026        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19027            // Don't yell about broadcasts sent via shell
19028            return;
19029        }
19030
19031        final String action = intent.getAction();
19032        if (isProtectedBroadcast
19033                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19034                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19035                || Intent.ACTION_MEDIA_BUTTON.equals(action)
19036                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19037                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19038                || Intent.ACTION_MASTER_CLEAR.equals(action)
19039                || Intent.ACTION_FACTORY_RESET.equals(action)
19040                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19041                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19042                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19043                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19044                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19045                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19046                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19047            // Broadcast is either protected, or it's a public action that
19048            // we've relaxed, so it's fine for system internals to send.
19049            return;
19050        }
19051
19052        // This broadcast may be a problem...  but there are often system components that
19053        // want to send an internal broadcast to themselves, which is annoying to have to
19054        // explicitly list each action as a protected broadcast, so we will check for that
19055        // one safe case and allow it: an explicit broadcast, only being received by something
19056        // that has protected itself.
19057        if (receivers != null && receivers.size() > 0
19058                && (intent.getPackage() != null || intent.getComponent() != null)) {
19059            boolean allProtected = true;
19060            for (int i = receivers.size()-1; i >= 0; i--) {
19061                Object target = receivers.get(i);
19062                if (target instanceof ResolveInfo) {
19063                    ResolveInfo ri = (ResolveInfo)target;
19064                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19065                        allProtected = false;
19066                        break;
19067                    }
19068                } else {
19069                    BroadcastFilter bf = (BroadcastFilter)target;
19070                    if (bf.requiredPermission == null) {
19071                        allProtected = false;
19072                        break;
19073                    }
19074                }
19075            }
19076            if (allProtected) {
19077                // All safe!
19078                return;
19079            }
19080        }
19081
19082        // The vast majority of broadcasts sent from system internals
19083        // should be protected to avoid security holes, so yell loudly
19084        // to ensure we examine these cases.
19085        if (callerApp != null) {
19086            Log.wtf(TAG, "Sending non-protected broadcast " + action
19087                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19088                    new Throwable());
19089        } else {
19090            Log.wtf(TAG, "Sending non-protected broadcast " + action
19091                            + " from system uid " + UserHandle.formatUid(callingUid)
19092                            + " pkg " + callerPackage,
19093                    new Throwable());
19094        }
19095    }
19096
19097    final int broadcastIntentLocked(ProcessRecord callerApp,
19098            String callerPackage, Intent intent, String resolvedType,
19099            IIntentReceiver resultTo, int resultCode, String resultData,
19100            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19101            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19102        intent = new Intent(intent);
19103
19104        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19105        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19106        if (callerInstantApp) {
19107            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19108        }
19109
19110        // By default broadcasts do not go to stopped apps.
19111        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19112
19113        // If we have not finished booting, don't allow this to launch new processes.
19114        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19115            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19116        }
19117
19118        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19119                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19120                + " ordered=" + ordered + " userid=" + userId);
19121        if ((resultTo != null) && !ordered) {
19122            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19123        }
19124
19125        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19126                ALLOW_NON_FULL, "broadcast", callerPackage);
19127
19128        // Make sure that the user who is receiving this broadcast is running.
19129        // If not, we will just skip it. Make an exception for shutdown broadcasts
19130        // and upgrade steps.
19131
19132        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19133            if ((callingUid != SYSTEM_UID
19134                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19135                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19136                Slog.w(TAG, "Skipping broadcast of " + intent
19137                        + ": user " + userId + " is stopped");
19138                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19139            }
19140        }
19141
19142        BroadcastOptions brOptions = null;
19143        if (bOptions != null) {
19144            brOptions = new BroadcastOptions(bOptions);
19145            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19146                // See if the caller is allowed to do this.  Note we are checking against
19147                // the actual real caller (not whoever provided the operation as say a
19148                // PendingIntent), because that who is actually supplied the arguments.
19149                if (checkComponentPermission(
19150                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19151                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19152                        != PackageManager.PERMISSION_GRANTED) {
19153                    String msg = "Permission Denial: " + intent.getAction()
19154                            + " broadcast from " + callerPackage + " (pid=" + callingPid
19155                            + ", uid=" + callingUid + ")"
19156                            + " requires "
19157                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19158                    Slog.w(TAG, msg);
19159                    throw new SecurityException(msg);
19160                }
19161            }
19162        }
19163
19164        // Verify that protected broadcasts are only being sent by system code,
19165        // and that system code is only sending protected broadcasts.
19166        final String action = intent.getAction();
19167        final boolean isProtectedBroadcast;
19168        try {
19169            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19170        } catch (RemoteException e) {
19171            Slog.w(TAG, "Remote exception", e);
19172            return ActivityManager.BROADCAST_SUCCESS;
19173        }
19174
19175        final boolean isCallerSystem;
19176        switch (UserHandle.getAppId(callingUid)) {
19177            case ROOT_UID:
19178            case SYSTEM_UID:
19179            case PHONE_UID:
19180            case BLUETOOTH_UID:
19181            case NFC_UID:
19182                isCallerSystem = true;
19183                break;
19184            default:
19185                isCallerSystem = (callerApp != null) && callerApp.persistent;
19186                break;
19187        }
19188
19189        // First line security check before anything else: stop non-system apps from
19190        // sending protected broadcasts.
19191        if (!isCallerSystem) {
19192            if (isProtectedBroadcast) {
19193                String msg = "Permission Denial: not allowed to send broadcast "
19194                        + action + " from pid="
19195                        + callingPid + ", uid=" + callingUid;
19196                Slog.w(TAG, msg);
19197                throw new SecurityException(msg);
19198
19199            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19200                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19201                // Special case for compatibility: we don't want apps to send this,
19202                // but historically it has not been protected and apps may be using it
19203                // to poke their own app widget.  So, instead of making it protected,
19204                // just limit it to the caller.
19205                if (callerPackage == null) {
19206                    String msg = "Permission Denial: not allowed to send broadcast "
19207                            + action + " from unknown caller.";
19208                    Slog.w(TAG, msg);
19209                    throw new SecurityException(msg);
19210                } else if (intent.getComponent() != null) {
19211                    // They are good enough to send to an explicit component...  verify
19212                    // it is being sent to the calling app.
19213                    if (!intent.getComponent().getPackageName().equals(
19214                            callerPackage)) {
19215                        String msg = "Permission Denial: not allowed to send broadcast "
19216                                + action + " to "
19217                                + intent.getComponent().getPackageName() + " from "
19218                                + callerPackage;
19219                        Slog.w(TAG, msg);
19220                        throw new SecurityException(msg);
19221                    }
19222                } else {
19223                    // Limit broadcast to their own package.
19224                    intent.setPackage(callerPackage);
19225                }
19226            }
19227        }
19228
19229        if (action != null) {
19230            if (getBackgroundLaunchBroadcasts().contains(action)) {
19231                if (DEBUG_BACKGROUND_CHECK) {
19232                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19233                }
19234                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19235            }
19236
19237            switch (action) {
19238                case Intent.ACTION_UID_REMOVED:
19239                case Intent.ACTION_PACKAGE_REMOVED:
19240                case Intent.ACTION_PACKAGE_CHANGED:
19241                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19242                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19243                case Intent.ACTION_PACKAGES_SUSPENDED:
19244                case Intent.ACTION_PACKAGES_UNSUSPENDED:
19245                    // Handle special intents: if this broadcast is from the package
19246                    // manager about a package being removed, we need to remove all of
19247                    // its activities from the history stack.
19248                    if (checkComponentPermission(
19249                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19250                            callingPid, callingUid, -1, true)
19251                            != PackageManager.PERMISSION_GRANTED) {
19252                        String msg = "Permission Denial: " + intent.getAction()
19253                                + " broadcast from " + callerPackage + " (pid=" + callingPid
19254                                + ", uid=" + callingUid + ")"
19255                                + " requires "
19256                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19257                        Slog.w(TAG, msg);
19258                        throw new SecurityException(msg);
19259                    }
19260                    switch (action) {
19261                        case Intent.ACTION_UID_REMOVED:
19262                            final int uid = getUidFromIntent(intent);
19263                            if (uid >= 0) {
19264                                mBatteryStatsService.removeUid(uid);
19265                                mAppOpsService.uidRemoved(uid);
19266                            }
19267                            break;
19268                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19269                            // If resources are unavailable just force stop all those packages
19270                            // and flush the attribute cache as well.
19271                            String list[] =
19272                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19273                            if (list != null && list.length > 0) {
19274                                for (int i = 0; i < list.length; i++) {
19275                                    forceStopPackageLocked(list[i], -1, false, true, true,
19276                                            false, false, userId, "storage unmount");
19277                                }
19278                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19279                                sendPackageBroadcastLocked(
19280                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19281                                        list, userId);
19282                            }
19283                            break;
19284                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19285                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19286                            break;
19287                        case Intent.ACTION_PACKAGE_REMOVED:
19288                        case Intent.ACTION_PACKAGE_CHANGED:
19289                            Uri data = intent.getData();
19290                            String ssp;
19291                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19292                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19293                                final boolean replacing =
19294                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19295                                final boolean killProcess =
19296                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19297                                final boolean fullUninstall = removed && !replacing;
19298                                if (removed) {
19299                                    if (killProcess) {
19300                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
19301                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19302                                                false, true, true, false, fullUninstall, userId,
19303                                                removed ? "pkg removed" : "pkg changed");
19304                                    }
19305                                    final int cmd = killProcess
19306                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
19307                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19308                                    sendPackageBroadcastLocked(cmd,
19309                                            new String[] {ssp}, userId);
19310                                    if (fullUninstall) {
19311                                        mAppOpsService.packageRemoved(
19312                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19313
19314                                        // Remove all permissions granted from/to this package
19315                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
19316
19317                                        removeTasksByPackageNameLocked(ssp, userId);
19318
19319                                        mServices.forceStopPackageLocked(ssp, userId);
19320
19321                                        // Hide the "unsupported display" dialog if necessary.
19322                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19323                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19324                                            mUnsupportedDisplaySizeDialog.dismiss();
19325                                            mUnsupportedDisplaySizeDialog = null;
19326                                        }
19327                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
19328                                        mBatteryStatsService.notePackageUninstalled(ssp);
19329                                    }
19330                                } else {
19331                                    if (killProcess) {
19332                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
19333                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19334                                                userId, ProcessList.INVALID_ADJ,
19335                                                false, true, true, false, "change " + ssp);
19336                                    }
19337                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19338                                            intent.getStringArrayExtra(
19339                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19340                                }
19341                            }
19342                            break;
19343                        case Intent.ACTION_PACKAGES_SUSPENDED:
19344                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
19345                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19346                                    intent.getAction());
19347                            final String[] packageNames = intent.getStringArrayExtra(
19348                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
19349                            final int userHandle = intent.getIntExtra(
19350                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19351
19352                            synchronized(ActivityManagerService.this) {
19353                                mRecentTasks.onPackagesSuspendedChanged(
19354                                        packageNames, suspended, userHandle);
19355                            }
19356                            break;
19357                    }
19358                    break;
19359                case Intent.ACTION_PACKAGE_REPLACED:
19360                {
19361                    final Uri data = intent.getData();
19362                    final String ssp;
19363                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19364                        ApplicationInfo aInfo = null;
19365                        try {
19366                            aInfo = AppGlobals.getPackageManager()
19367                                    .getApplicationInfo(ssp, 0 /*flags*/, userId);
19368                        } catch (RemoteException ignore) {}
19369                        if (aInfo == null) {
19370                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19371                                    + " ssp=" + ssp + " data=" + data);
19372                            return ActivityManager.BROADCAST_SUCCESS;
19373                        }
19374                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19375                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19376                                new String[] {ssp}, userId);
19377                    }
19378                    break;
19379                }
19380                case Intent.ACTION_PACKAGE_ADDED:
19381                {
19382                    // Special case for adding a package: by default turn on compatibility mode.
19383                    Uri data = intent.getData();
19384                    String ssp;
19385                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19386                        final boolean replacing =
19387                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19388                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19389
19390                        try {
19391                            ApplicationInfo ai = AppGlobals.getPackageManager().
19392                                    getApplicationInfo(ssp, 0, 0);
19393                            mBatteryStatsService.notePackageInstalled(ssp,
19394                                    ai != null ? ai.versionCode : 0);
19395                        } catch (RemoteException e) {
19396                        }
19397                    }
19398                    break;
19399                }
19400                case Intent.ACTION_PACKAGE_DATA_CLEARED:
19401                {
19402                    Uri data = intent.getData();
19403                    String ssp;
19404                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19405                        // Hide the "unsupported display" dialog if necessary.
19406                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19407                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19408                            mUnsupportedDisplaySizeDialog.dismiss();
19409                            mUnsupportedDisplaySizeDialog = null;
19410                        }
19411                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
19412                    }
19413                    break;
19414                }
19415                case Intent.ACTION_TIMEZONE_CHANGED:
19416                    // If this is the time zone changed action, queue up a message that will reset
19417                    // the timezone of all currently running processes. This message will get
19418                    // queued up before the broadcast happens.
19419                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19420                    break;
19421                case Intent.ACTION_TIME_CHANGED:
19422                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19423                    // the tri-state value it may contain and "unknown".
19424                    // For convenience we re-use the Intent extra values.
19425                    final int NO_EXTRA_VALUE_FOUND = -1;
19426                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19427                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19428                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
19429                    // Only send a message if the time preference is available.
19430                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19431                        Message updateTimePreferenceMsg =
19432                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19433                                        timeFormatPreferenceMsgValue, 0);
19434                        mHandler.sendMessage(updateTimePreferenceMsg);
19435                    }
19436                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19437                    synchronized (stats) {
19438                        stats.noteCurrentTimeChangedLocked();
19439                    }
19440                    break;
19441                case Intent.ACTION_CLEAR_DNS_CACHE:
19442                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19443                    break;
19444                case Proxy.PROXY_CHANGE_ACTION:
19445                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19446                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19447                    break;
19448                case android.hardware.Camera.ACTION_NEW_PICTURE:
19449                case android.hardware.Camera.ACTION_NEW_VIDEO:
19450                    // In N we just turned these off; in O we are turing them back on partly,
19451                    // only for registered receivers.  This will still address the main problem
19452                    // (a spam of apps waking up when a picture is taken putting significant
19453                    // memory pressure on the system at a bad point), while still allowing apps
19454                    // that are already actively running to know about this happening.
19455                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19456                    break;
19457                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19458                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19459                    break;
19460                case "com.android.launcher.action.INSTALL_SHORTCUT":
19461                    // As of O, we no longer support this broadcasts, even for pre-O apps.
19462                    // Apps should now be using ShortcutManager.pinRequestShortcut().
19463                    Log.w(TAG, "Broadcast " + action
19464                            + " no longer supported. It will not be delivered.");
19465                    return ActivityManager.BROADCAST_SUCCESS;
19466            }
19467
19468            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19469                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19470                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19471                final int uid = getUidFromIntent(intent);
19472                if (uid != -1) {
19473                    final UidRecord uidRec = mActiveUids.get(uid);
19474                    if (uidRec != null) {
19475                        uidRec.updateHasInternetPermission();
19476                    }
19477                }
19478            }
19479        }
19480
19481        // Add to the sticky list if requested.
19482        if (sticky) {
19483            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19484                    callingPid, callingUid)
19485                    != PackageManager.PERMISSION_GRANTED) {
19486                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19487                        + callingPid + ", uid=" + callingUid
19488                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19489                Slog.w(TAG, msg);
19490                throw new SecurityException(msg);
19491            }
19492            if (requiredPermissions != null && requiredPermissions.length > 0) {
19493                Slog.w(TAG, "Can't broadcast sticky intent " + intent
19494                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
19495                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19496            }
19497            if (intent.getComponent() != null) {
19498                throw new SecurityException(
19499                        "Sticky broadcasts can't target a specific component");
19500            }
19501            // We use userId directly here, since the "all" target is maintained
19502            // as a separate set of sticky broadcasts.
19503            if (userId != UserHandle.USER_ALL) {
19504                // But first, if this is not a broadcast to all users, then
19505                // make sure it doesn't conflict with an existing broadcast to
19506                // all users.
19507                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19508                        UserHandle.USER_ALL);
19509                if (stickies != null) {
19510                    ArrayList<Intent> list = stickies.get(intent.getAction());
19511                    if (list != null) {
19512                        int N = list.size();
19513                        int i;
19514                        for (i=0; i<N; i++) {
19515                            if (intent.filterEquals(list.get(i))) {
19516                                throw new IllegalArgumentException(
19517                                        "Sticky broadcast " + intent + " for user "
19518                                        + userId + " conflicts with existing global broadcast");
19519                            }
19520                        }
19521                    }
19522                }
19523            }
19524            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19525            if (stickies == null) {
19526                stickies = new ArrayMap<>();
19527                mStickyBroadcasts.put(userId, stickies);
19528            }
19529            ArrayList<Intent> list = stickies.get(intent.getAction());
19530            if (list == null) {
19531                list = new ArrayList<>();
19532                stickies.put(intent.getAction(), list);
19533            }
19534            final int stickiesCount = list.size();
19535            int i;
19536            for (i = 0; i < stickiesCount; i++) {
19537                if (intent.filterEquals(list.get(i))) {
19538                    // This sticky already exists, replace it.
19539                    list.set(i, new Intent(intent));
19540                    break;
19541                }
19542            }
19543            if (i >= stickiesCount) {
19544                list.add(new Intent(intent));
19545            }
19546        }
19547
19548        int[] users;
19549        if (userId == UserHandle.USER_ALL) {
19550            // Caller wants broadcast to go to all started users.
19551            users = mUserController.getStartedUserArrayLocked();
19552        } else {
19553            // Caller wants broadcast to go to one specific user.
19554            users = new int[] {userId};
19555        }
19556
19557        // Figure out who all will receive this broadcast.
19558        List receivers = null;
19559        List<BroadcastFilter> registeredReceivers = null;
19560        // Need to resolve the intent to interested receivers...
19561        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19562                 == 0) {
19563            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19564        }
19565        if (intent.getComponent() == null) {
19566            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19567                // Query one target user at a time, excluding shell-restricted users
19568                for (int i = 0; i < users.length; i++) {
19569                    if (mUserController.hasUserRestriction(
19570                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19571                        continue;
19572                    }
19573                    List<BroadcastFilter> registeredReceiversForUser =
19574                            mReceiverResolver.queryIntent(intent,
19575                                    resolvedType, false /*defaultOnly*/, users[i]);
19576                    if (registeredReceivers == null) {
19577                        registeredReceivers = registeredReceiversForUser;
19578                    } else if (registeredReceiversForUser != null) {
19579                        registeredReceivers.addAll(registeredReceiversForUser);
19580                    }
19581                }
19582            } else {
19583                registeredReceivers = mReceiverResolver.queryIntent(intent,
19584                        resolvedType, false /*defaultOnly*/, userId);
19585            }
19586        }
19587
19588        final boolean replacePending =
19589                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19590
19591        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19592                + " replacePending=" + replacePending);
19593
19594        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19595        if (!ordered && NR > 0) {
19596            // If we are not serializing this broadcast, then send the
19597            // registered receivers separately so they don't wait for the
19598            // components to be launched.
19599            if (isCallerSystem) {
19600                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19601                        isProtectedBroadcast, registeredReceivers);
19602            }
19603            final BroadcastQueue queue = broadcastQueueForIntent(intent);
19604            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19605                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19606                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19607                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19608            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19609            final boolean replaced = replacePending
19610                    && (queue.replaceParallelBroadcastLocked(r) != null);
19611            // Note: We assume resultTo is null for non-ordered broadcasts.
19612            if (!replaced) {
19613                queue.enqueueParallelBroadcastLocked(r);
19614                queue.scheduleBroadcastsLocked();
19615            }
19616            registeredReceivers = null;
19617            NR = 0;
19618        }
19619
19620        // Merge into one list.
19621        int ir = 0;
19622        if (receivers != null) {
19623            // A special case for PACKAGE_ADDED: do not allow the package
19624            // being added to see this broadcast.  This prevents them from
19625            // using this as a back door to get run as soon as they are
19626            // installed.  Maybe in the future we want to have a special install
19627            // broadcast or such for apps, but we'd like to deliberately make
19628            // this decision.
19629            String skipPackages[] = null;
19630            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19631                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19632                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19633                Uri data = intent.getData();
19634                if (data != null) {
19635                    String pkgName = data.getSchemeSpecificPart();
19636                    if (pkgName != null) {
19637                        skipPackages = new String[] { pkgName };
19638                    }
19639                }
19640            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19641                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19642            }
19643            if (skipPackages != null && (skipPackages.length > 0)) {
19644                for (String skipPackage : skipPackages) {
19645                    if (skipPackage != null) {
19646                        int NT = receivers.size();
19647                        for (int it=0; it<NT; it++) {
19648                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
19649                            if (curt.activityInfo.packageName.equals(skipPackage)) {
19650                                receivers.remove(it);
19651                                it--;
19652                                NT--;
19653                            }
19654                        }
19655                    }
19656                }
19657            }
19658
19659            int NT = receivers != null ? receivers.size() : 0;
19660            int it = 0;
19661            ResolveInfo curt = null;
19662            BroadcastFilter curr = null;
19663            while (it < NT && ir < NR) {
19664                if (curt == null) {
19665                    curt = (ResolveInfo)receivers.get(it);
19666                }
19667                if (curr == null) {
19668                    curr = registeredReceivers.get(ir);
19669                }
19670                if (curr.getPriority() >= curt.priority) {
19671                    // Insert this broadcast record into the final list.
19672                    receivers.add(it, curr);
19673                    ir++;
19674                    curr = null;
19675                    it++;
19676                    NT++;
19677                } else {
19678                    // Skip to the next ResolveInfo in the final list.
19679                    it++;
19680                    curt = null;
19681                }
19682            }
19683        }
19684        while (ir < NR) {
19685            if (receivers == null) {
19686                receivers = new ArrayList();
19687            }
19688            receivers.add(registeredReceivers.get(ir));
19689            ir++;
19690        }
19691
19692        if (isCallerSystem) {
19693            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19694                    isProtectedBroadcast, receivers);
19695        }
19696
19697        if ((receivers != null && receivers.size() > 0)
19698                || resultTo != null) {
19699            BroadcastQueue queue = broadcastQueueForIntent(intent);
19700            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19701                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19702                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19703                    resultData, resultExtras, ordered, sticky, false, userId);
19704
19705            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19706                    + ": prev had " + queue.mOrderedBroadcasts.size());
19707            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19708                    "Enqueueing broadcast " + r.intent.getAction());
19709
19710            final BroadcastRecord oldRecord =
19711                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19712            if (oldRecord != null) {
19713                // Replaced, fire the result-to receiver.
19714                if (oldRecord.resultTo != null) {
19715                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19716                    try {
19717                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19718                                oldRecord.intent,
19719                                Activity.RESULT_CANCELED, null, null,
19720                                false, false, oldRecord.userId);
19721                    } catch (RemoteException e) {
19722                        Slog.w(TAG, "Failure ["
19723                                + queue.mQueueName + "] sending broadcast result of "
19724                                + intent, e);
19725
19726                    }
19727                }
19728            } else {
19729                queue.enqueueOrderedBroadcastLocked(r);
19730                queue.scheduleBroadcastsLocked();
19731            }
19732        } else {
19733            // There was nobody interested in the broadcast, but we still want to record
19734            // that it happened.
19735            if (intent.getComponent() == null && intent.getPackage() == null
19736                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19737                // This was an implicit broadcast... let's record it for posterity.
19738                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19739            }
19740        }
19741
19742        return ActivityManager.BROADCAST_SUCCESS;
19743    }
19744
19745    /**
19746     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19747     */
19748    private int getUidFromIntent(Intent intent) {
19749        if (intent == null) {
19750            return -1;
19751        }
19752        final Bundle intentExtras = intent.getExtras();
19753        return intent.hasExtra(Intent.EXTRA_UID)
19754                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19755    }
19756
19757    final void rotateBroadcastStatsIfNeededLocked() {
19758        final long now = SystemClock.elapsedRealtime();
19759        if (mCurBroadcastStats == null ||
19760                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19761            mLastBroadcastStats = mCurBroadcastStats;
19762            if (mLastBroadcastStats != null) {
19763                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19764                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19765            }
19766            mCurBroadcastStats = new BroadcastStats();
19767        }
19768    }
19769
19770    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19771            int skipCount, long dispatchTime) {
19772        rotateBroadcastStatsIfNeededLocked();
19773        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19774    }
19775
19776    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19777        rotateBroadcastStatsIfNeededLocked();
19778        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19779    }
19780
19781    final Intent verifyBroadcastLocked(Intent intent) {
19782        // Refuse possible leaked file descriptors
19783        if (intent != null && intent.hasFileDescriptors() == true) {
19784            throw new IllegalArgumentException("File descriptors passed in Intent");
19785        }
19786
19787        int flags = intent.getFlags();
19788
19789        if (!mProcessesReady) {
19790            // if the caller really truly claims to know what they're doing, go
19791            // ahead and allow the broadcast without launching any receivers
19792            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19793                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19794            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19795                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19796                        + " before boot completion");
19797                throw new IllegalStateException("Cannot broadcast before boot completed");
19798            }
19799        }
19800
19801        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19802            throw new IllegalArgumentException(
19803                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19804        }
19805
19806        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19807            switch (Binder.getCallingUid()) {
19808                case ROOT_UID:
19809                case SHELL_UID:
19810                    break;
19811                default:
19812                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19813                            + Binder.getCallingUid());
19814                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19815                    break;
19816            }
19817        }
19818
19819        return intent;
19820    }
19821
19822    public final int broadcastIntent(IApplicationThread caller,
19823            Intent intent, String resolvedType, IIntentReceiver resultTo,
19824            int resultCode, String resultData, Bundle resultExtras,
19825            String[] requiredPermissions, int appOp, Bundle bOptions,
19826            boolean serialized, boolean sticky, int userId) {
19827        enforceNotIsolatedCaller("broadcastIntent");
19828        synchronized(this) {
19829            intent = verifyBroadcastLocked(intent);
19830
19831            final ProcessRecord callerApp = getRecordForAppLocked(caller);
19832            final int callingPid = Binder.getCallingPid();
19833            final int callingUid = Binder.getCallingUid();
19834            final long origId = Binder.clearCallingIdentity();
19835            int res = broadcastIntentLocked(callerApp,
19836                    callerApp != null ? callerApp.info.packageName : null,
19837                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19838                    requiredPermissions, appOp, bOptions, serialized, sticky,
19839                    callingPid, callingUid, userId);
19840            Binder.restoreCallingIdentity(origId);
19841            return res;
19842        }
19843    }
19844
19845
19846    int broadcastIntentInPackage(String packageName, int uid,
19847            Intent intent, String resolvedType, IIntentReceiver resultTo,
19848            int resultCode, String resultData, Bundle resultExtras,
19849            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19850            int userId) {
19851        synchronized(this) {
19852            intent = verifyBroadcastLocked(intent);
19853
19854            final long origId = Binder.clearCallingIdentity();
19855            String[] requiredPermissions = requiredPermission == null ? null
19856                    : new String[] {requiredPermission};
19857            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19858                    resultTo, resultCode, resultData, resultExtras,
19859                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19860                    sticky, -1, uid, userId);
19861            Binder.restoreCallingIdentity(origId);
19862            return res;
19863        }
19864    }
19865
19866    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19867        // Refuse possible leaked file descriptors
19868        if (intent != null && intent.hasFileDescriptors() == true) {
19869            throw new IllegalArgumentException("File descriptors passed in Intent");
19870        }
19871
19872        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19873                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19874
19875        synchronized(this) {
19876            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19877                    != PackageManager.PERMISSION_GRANTED) {
19878                String msg = "Permission Denial: unbroadcastIntent() from pid="
19879                        + Binder.getCallingPid()
19880                        + ", uid=" + Binder.getCallingUid()
19881                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19882                Slog.w(TAG, msg);
19883                throw new SecurityException(msg);
19884            }
19885            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19886            if (stickies != null) {
19887                ArrayList<Intent> list = stickies.get(intent.getAction());
19888                if (list != null) {
19889                    int N = list.size();
19890                    int i;
19891                    for (i=0; i<N; i++) {
19892                        if (intent.filterEquals(list.get(i))) {
19893                            list.remove(i);
19894                            break;
19895                        }
19896                    }
19897                    if (list.size() <= 0) {
19898                        stickies.remove(intent.getAction());
19899                    }
19900                }
19901                if (stickies.size() <= 0) {
19902                    mStickyBroadcasts.remove(userId);
19903                }
19904            }
19905        }
19906    }
19907
19908    void backgroundServicesFinishedLocked(int userId) {
19909        for (BroadcastQueue queue : mBroadcastQueues) {
19910            queue.backgroundServicesFinishedLocked(userId);
19911        }
19912    }
19913
19914    public void finishReceiver(IBinder who, int resultCode, String resultData,
19915            Bundle resultExtras, boolean resultAbort, int flags) {
19916        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19917
19918        // Refuse possible leaked file descriptors
19919        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19920            throw new IllegalArgumentException("File descriptors passed in Bundle");
19921        }
19922
19923        final long origId = Binder.clearCallingIdentity();
19924        try {
19925            boolean doNext = false;
19926            BroadcastRecord r;
19927
19928            synchronized(this) {
19929                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19930                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19931                r = queue.getMatchingOrderedReceiver(who);
19932                if (r != null) {
19933                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19934                        resultData, resultExtras, resultAbort, true);
19935                }
19936            }
19937
19938            if (doNext) {
19939                r.queue.processNextBroadcast(false);
19940            }
19941            trimApplications();
19942        } finally {
19943            Binder.restoreCallingIdentity(origId);
19944        }
19945    }
19946
19947    // =========================================================
19948    // INSTRUMENTATION
19949    // =========================================================
19950
19951    public boolean startInstrumentation(ComponentName className,
19952            String profileFile, int flags, Bundle arguments,
19953            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19954            int userId, String abiOverride) {
19955        enforceNotIsolatedCaller("startInstrumentation");
19956        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19957                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19958        // Refuse possible leaked file descriptors
19959        if (arguments != null && arguments.hasFileDescriptors()) {
19960            throw new IllegalArgumentException("File descriptors passed in Bundle");
19961        }
19962
19963        synchronized(this) {
19964            InstrumentationInfo ii = null;
19965            ApplicationInfo ai = null;
19966            try {
19967                ii = mContext.getPackageManager().getInstrumentationInfo(
19968                    className, STOCK_PM_FLAGS);
19969                ai = AppGlobals.getPackageManager().getApplicationInfo(
19970                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19971            } catch (PackageManager.NameNotFoundException e) {
19972            } catch (RemoteException e) {
19973            }
19974            if (ii == null) {
19975                reportStartInstrumentationFailureLocked(watcher, className,
19976                        "Unable to find instrumentation info for: " + className);
19977                return false;
19978            }
19979            if (ai == null) {
19980                reportStartInstrumentationFailureLocked(watcher, className,
19981                        "Unable to find instrumentation target package: " + ii.targetPackage);
19982                return false;
19983            }
19984            if (!ai.hasCode()) {
19985                reportStartInstrumentationFailureLocked(watcher, className,
19986                        "Instrumentation target has no code: " + ii.targetPackage);
19987                return false;
19988            }
19989
19990            int match = mContext.getPackageManager().checkSignatures(
19991                    ii.targetPackage, ii.packageName);
19992            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19993                String msg = "Permission Denial: starting instrumentation "
19994                        + className + " from pid="
19995                        + Binder.getCallingPid()
19996                        + ", uid=" + Binder.getCallingPid()
19997                        + " not allowed because package " + ii.packageName
19998                        + " does not have a signature matching the target "
19999                        + ii.targetPackage;
20000                reportStartInstrumentationFailureLocked(watcher, className, msg);
20001                throw new SecurityException(msg);
20002            }
20003
20004            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20005            activeInstr.mClass = className;
20006            String defProcess = ai.processName;;
20007            if (ii.targetProcesses == null) {
20008                activeInstr.mTargetProcesses = new String[]{ai.processName};
20009            } else if (ii.targetProcesses.equals("*")) {
20010                activeInstr.mTargetProcesses = new String[0];
20011            } else {
20012                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20013                defProcess = activeInstr.mTargetProcesses[0];
20014            }
20015            activeInstr.mTargetInfo = ai;
20016            activeInstr.mProfileFile = profileFile;
20017            activeInstr.mArguments = arguments;
20018            activeInstr.mWatcher = watcher;
20019            activeInstr.mUiAutomationConnection = uiAutomationConnection;
20020            activeInstr.mResultClass = className;
20021
20022            final long origId = Binder.clearCallingIdentity();
20023            // Instrumentation can kill and relaunch even persistent processes
20024            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20025                    "start instr");
20026            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20027            app.instr = activeInstr;
20028            activeInstr.mFinished = false;
20029            activeInstr.mRunningProcesses.add(app);
20030            if (!mActiveInstrumentation.contains(activeInstr)) {
20031                mActiveInstrumentation.add(activeInstr);
20032            }
20033            Binder.restoreCallingIdentity(origId);
20034        }
20035
20036        return true;
20037    }
20038
20039    /**
20040     * Report errors that occur while attempting to start Instrumentation.  Always writes the
20041     * error to the logs, but if somebody is watching, send the report there too.  This enables
20042     * the "am" command to report errors with more information.
20043     *
20044     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
20045     * @param cn The component name of the instrumentation.
20046     * @param report The error report.
20047     */
20048    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20049            ComponentName cn, String report) {
20050        Slog.w(TAG, report);
20051        if (watcher != null) {
20052            Bundle results = new Bundle();
20053            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20054            results.putString("Error", report);
20055            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20056        }
20057    }
20058
20059    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20060        if (app.instr == null) {
20061            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20062            return;
20063        }
20064
20065        if (!app.instr.mFinished && results != null) {
20066            if (app.instr.mCurResults == null) {
20067                app.instr.mCurResults = new Bundle(results);
20068            } else {
20069                app.instr.mCurResults.putAll(results);
20070            }
20071        }
20072    }
20073
20074    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20075        int userId = UserHandle.getCallingUserId();
20076        // Refuse possible leaked file descriptors
20077        if (results != null && results.hasFileDescriptors()) {
20078            throw new IllegalArgumentException("File descriptors passed in Intent");
20079        }
20080
20081        synchronized(this) {
20082            ProcessRecord app = getRecordForAppLocked(target);
20083            if (app == null) {
20084                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20085                return;
20086            }
20087            final long origId = Binder.clearCallingIdentity();
20088            addInstrumentationResultsLocked(app, results);
20089            Binder.restoreCallingIdentity(origId);
20090        }
20091    }
20092
20093    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20094        if (app.instr == null) {
20095            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20096            return;
20097        }
20098
20099        if (!app.instr.mFinished) {
20100            if (app.instr.mWatcher != null) {
20101                Bundle finalResults = app.instr.mCurResults;
20102                if (finalResults != null) {
20103                    if (app.instr.mCurResults != null && results != null) {
20104                        finalResults.putAll(results);
20105                    }
20106                } else {
20107                    finalResults = results;
20108                }
20109                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20110                        app.instr.mClass, resultCode, finalResults);
20111            }
20112
20113            // Can't call out of the system process with a lock held, so post a message.
20114            if (app.instr.mUiAutomationConnection != null) {
20115                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20116                        app.instr.mUiAutomationConnection).sendToTarget();
20117            }
20118            app.instr.mFinished = true;
20119        }
20120
20121        app.instr.removeProcess(app);
20122        app.instr = null;
20123
20124        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20125                "finished inst");
20126    }
20127
20128    public void finishInstrumentation(IApplicationThread target,
20129            int resultCode, Bundle results) {
20130        int userId = UserHandle.getCallingUserId();
20131        // Refuse possible leaked file descriptors
20132        if (results != null && results.hasFileDescriptors()) {
20133            throw new IllegalArgumentException("File descriptors passed in Intent");
20134        }
20135
20136        synchronized(this) {
20137            ProcessRecord app = getRecordForAppLocked(target);
20138            if (app == null) {
20139                Slog.w(TAG, "finishInstrumentation: no app for " + target);
20140                return;
20141            }
20142            final long origId = Binder.clearCallingIdentity();
20143            finishInstrumentationLocked(app, resultCode, results);
20144            Binder.restoreCallingIdentity(origId);
20145        }
20146    }
20147
20148    // =========================================================
20149    // CONFIGURATION
20150    // =========================================================
20151
20152    public ConfigurationInfo getDeviceConfigurationInfo() {
20153        ConfigurationInfo config = new ConfigurationInfo();
20154        synchronized (this) {
20155            final Configuration globalConfig = getGlobalConfiguration();
20156            config.reqTouchScreen = globalConfig.touchscreen;
20157            config.reqKeyboardType = globalConfig.keyboard;
20158            config.reqNavigation = globalConfig.navigation;
20159            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20160                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20161                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20162            }
20163            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20164                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20165                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20166            }
20167            config.reqGlEsVersion = GL_ES_VERSION;
20168        }
20169        return config;
20170    }
20171
20172    ActivityStack getFocusedStack() {
20173        return mStackSupervisor.getFocusedStack();
20174    }
20175
20176    @Override
20177    public int getFocusedStackId() throws RemoteException {
20178        ActivityStack focusedStack = getFocusedStack();
20179        if (focusedStack != null) {
20180            return focusedStack.getStackId();
20181        }
20182        return -1;
20183    }
20184
20185    public Configuration getConfiguration() {
20186        Configuration ci;
20187        synchronized(this) {
20188            ci = new Configuration(getGlobalConfiguration());
20189            ci.userSetLocale = false;
20190        }
20191        return ci;
20192    }
20193
20194    @Override
20195    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20196        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20197        synchronized (this) {
20198            mSuppressResizeConfigChanges = suppress;
20199        }
20200    }
20201
20202    /**
20203     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20204     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20205     *       activity and clearing the task at the same time.
20206     */
20207    @Override
20208    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20209        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20210        if (StackId.isHomeOrRecentsStack(fromStackId)) {
20211            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20212        }
20213        synchronized (this) {
20214            final long origId = Binder.clearCallingIdentity();
20215            try {
20216                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20217            } finally {
20218                Binder.restoreCallingIdentity(origId);
20219            }
20220        }
20221    }
20222
20223    @Override
20224    public void updatePersistentConfiguration(Configuration values) {
20225        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20226        enforceWriteSettingsPermission("updatePersistentConfiguration()");
20227        if (values == null) {
20228            throw new NullPointerException("Configuration must not be null");
20229        }
20230
20231        int userId = UserHandle.getCallingUserId();
20232
20233        synchronized(this) {
20234            updatePersistentConfigurationLocked(values, userId);
20235        }
20236    }
20237
20238    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20239        final long origId = Binder.clearCallingIdentity();
20240        try {
20241            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20242        } finally {
20243            Binder.restoreCallingIdentity(origId);
20244        }
20245    }
20246
20247    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20248        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20249                FONT_SCALE, 1.0f, userId);
20250
20251        synchronized (this) {
20252            if (getGlobalConfiguration().fontScale == scaleFactor) {
20253                return;
20254            }
20255
20256            final Configuration configuration
20257                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20258            configuration.fontScale = scaleFactor;
20259            updatePersistentConfigurationLocked(configuration, userId);
20260        }
20261    }
20262
20263    private void enforceWriteSettingsPermission(String func) {
20264        int uid = Binder.getCallingUid();
20265        if (uid == ROOT_UID) {
20266            return;
20267        }
20268
20269        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20270                Settings.getPackageNameForUid(mContext, uid), false)) {
20271            return;
20272        }
20273
20274        String msg = "Permission Denial: " + func + " from pid="
20275                + Binder.getCallingPid()
20276                + ", uid=" + uid
20277                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20278        Slog.w(TAG, msg);
20279        throw new SecurityException(msg);
20280    }
20281
20282    @Override
20283    public boolean updateConfiguration(Configuration values) {
20284        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20285
20286        synchronized(this) {
20287            if (values == null && mWindowManager != null) {
20288                // sentinel: fetch the current configuration from the window manager
20289                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20290            }
20291
20292            if (mWindowManager != null) {
20293                // Update OOM levels based on display size.
20294                mProcessList.applyDisplaySize(mWindowManager);
20295            }
20296
20297            final long origId = Binder.clearCallingIdentity();
20298            try {
20299                if (values != null) {
20300                    Settings.System.clearConfiguration(values);
20301                }
20302                updateConfigurationLocked(values, null, false, false /* persistent */,
20303                        UserHandle.USER_NULL, false /* deferResume */,
20304                        mTmpUpdateConfigurationResult);
20305                return mTmpUpdateConfigurationResult.changes != 0;
20306            } finally {
20307                Binder.restoreCallingIdentity(origId);
20308            }
20309        }
20310    }
20311
20312    void updateUserConfigurationLocked() {
20313        final Configuration configuration = new Configuration(getGlobalConfiguration());
20314        final int currentUserId = mUserController.getCurrentUserIdLocked();
20315        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20316                currentUserId, Settings.System.canWrite(mContext));
20317        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20318                false /* persistent */, currentUserId, false /* deferResume */);
20319    }
20320
20321    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20322            boolean initLocale) {
20323        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20324    }
20325
20326    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20327            boolean initLocale, boolean deferResume) {
20328        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20329        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20330                UserHandle.USER_NULL, deferResume);
20331    }
20332
20333    // To cache the list of supported system locales
20334    private String[] mSupportedSystemLocales = null;
20335
20336    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20337            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20338        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20339                deferResume, null /* result */);
20340    }
20341
20342    /**
20343     * Do either or both things: (1) change the current configuration, and (2)
20344     * make sure the given activity is running with the (now) current
20345     * configuration.  Returns true if the activity has been left running, or
20346     * false if <var>starting</var> is being destroyed to match the new
20347     * configuration.
20348     *
20349     * @param userId is only used when persistent parameter is set to true to persist configuration
20350     *               for that particular user
20351     */
20352    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20353            boolean initLocale, boolean persistent, int userId, boolean deferResume,
20354            UpdateConfigurationResult result) {
20355        int changes = 0;
20356        boolean kept = true;
20357
20358        if (mWindowManager != null) {
20359            mWindowManager.deferSurfaceLayout();
20360        }
20361        try {
20362            if (values != null) {
20363                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20364                        deferResume);
20365            }
20366
20367            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20368        } finally {
20369            if (mWindowManager != null) {
20370                mWindowManager.continueSurfaceLayout();
20371            }
20372        }
20373
20374        if (result != null) {
20375            result.changes = changes;
20376            result.activityRelaunched = !kept;
20377        }
20378        return kept;
20379    }
20380
20381    /** Update default (global) configuration and notify listeners about changes. */
20382    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20383            boolean persistent, int userId, boolean deferResume) {
20384        mTempConfig.setTo(getGlobalConfiguration());
20385        final int changes = mTempConfig.updateFrom(values);
20386        if (changes == 0) {
20387            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20388            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20389            // performDisplayOverrideConfigUpdate in order to send the new display configuration
20390            // (even if there are no actual changes) to unfreeze the window.
20391            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20392            return 0;
20393        }
20394
20395        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20396                "Updating global configuration to: " + values);
20397
20398        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20399
20400        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20401            final LocaleList locales = values.getLocales();
20402            int bestLocaleIndex = 0;
20403            if (locales.size() > 1) {
20404                if (mSupportedSystemLocales == null) {
20405                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20406                }
20407                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20408            }
20409            SystemProperties.set("persist.sys.locale",
20410                    locales.get(bestLocaleIndex).toLanguageTag());
20411            LocaleList.setDefault(locales, bestLocaleIndex);
20412            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20413                    locales.get(bestLocaleIndex)));
20414        }
20415
20416        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20417        mTempConfig.seq = mConfigurationSeq;
20418
20419        // Update stored global config and notify everyone about the change.
20420        mStackSupervisor.onConfigurationChanged(mTempConfig);
20421
20422        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20423        // TODO(multi-display): Update UsageEvents#Event to include displayId.
20424        mUsageStatsService.reportConfigurationChange(mTempConfig,
20425                mUserController.getCurrentUserIdLocked());
20426
20427        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20428        mShowDialogs = shouldShowDialogs(mTempConfig);
20429
20430        AttributeCache ac = AttributeCache.instance();
20431        if (ac != null) {
20432            ac.updateConfiguration(mTempConfig);
20433        }
20434
20435        // Make sure all resources in our process are updated right now, so that anyone who is going
20436        // to retrieve resource values after we return will be sure to get the new ones. This is
20437        // especially important during boot, where the first config change needs to guarantee all
20438        // resources have that config before following boot code is executed.
20439        mSystemThread.applyConfigurationToResources(mTempConfig);
20440
20441        // We need another copy of global config because we're scheduling some calls instead of
20442        // running them in place. We need to be sure that object we send will be handled unchanged.
20443        final Configuration configCopy = new Configuration(mTempConfig);
20444        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20445            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20446            msg.obj = configCopy;
20447            msg.arg1 = userId;
20448            mHandler.sendMessage(msg);
20449        }
20450
20451        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20452            ProcessRecord app = mLruProcesses.get(i);
20453            try {
20454                if (app.thread != null) {
20455                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20456                            + app.processName + " new config " + configCopy);
20457                    app.thread.scheduleConfigurationChanged(configCopy);
20458                }
20459            } catch (Exception e) {
20460            }
20461        }
20462
20463        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20464        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20465                | Intent.FLAG_RECEIVER_FOREGROUND
20466                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20467        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20468                AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20469                UserHandle.USER_ALL);
20470        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20471            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20472            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20473                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20474                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20475            if (initLocale || !mProcessesReady) {
20476                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20477            }
20478            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20479                    AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20480                    UserHandle.USER_ALL);
20481        }
20482
20483        // Override configuration of the default display duplicates global config, so we need to
20484        // update it also. This will also notify WindowManager about changes.
20485        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20486                DEFAULT_DISPLAY);
20487
20488        return changes;
20489    }
20490
20491    @Override
20492    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20493        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20494
20495        synchronized (this) {
20496            // Check if display is initialized in AM.
20497            if (!mStackSupervisor.isDisplayAdded(displayId)) {
20498                // Call might come when display is not yet added or has already been removed.
20499                if (DEBUG_CONFIGURATION) {
20500                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20501                            + displayId);
20502                }
20503                return false;
20504            }
20505
20506            if (values == null && mWindowManager != null) {
20507                // sentinel: fetch the current configuration from the window manager
20508                values = mWindowManager.computeNewConfiguration(displayId);
20509            }
20510
20511            if (mWindowManager != null) {
20512                // Update OOM levels based on display size.
20513                mProcessList.applyDisplaySize(mWindowManager);
20514            }
20515
20516            final long origId = Binder.clearCallingIdentity();
20517            try {
20518                if (values != null) {
20519                    Settings.System.clearConfiguration(values);
20520                }
20521                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20522                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20523                return mTmpUpdateConfigurationResult.changes != 0;
20524            } finally {
20525                Binder.restoreCallingIdentity(origId);
20526            }
20527        }
20528    }
20529
20530    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20531            boolean deferResume, int displayId) {
20532        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20533                displayId, null /* result */);
20534    }
20535
20536    /**
20537     * Updates override configuration specific for the selected display. If no config is provided,
20538     * new one will be computed in WM based on current display info.
20539     */
20540    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20541            ActivityRecord starting, boolean deferResume, int displayId,
20542            UpdateConfigurationResult result) {
20543        int changes = 0;
20544        boolean kept = true;
20545
20546        if (mWindowManager != null) {
20547            mWindowManager.deferSurfaceLayout();
20548        }
20549        try {
20550            if (values != null) {
20551                if (displayId == DEFAULT_DISPLAY) {
20552                    // Override configuration of the default display duplicates global config, so
20553                    // we're calling global config update instead for default display. It will also
20554                    // apply the correct override config.
20555                    changes = updateGlobalConfiguration(values, false /* initLocale */,
20556                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20557                } else {
20558                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20559                }
20560            }
20561
20562            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20563        } finally {
20564            if (mWindowManager != null) {
20565                mWindowManager.continueSurfaceLayout();
20566            }
20567        }
20568
20569        if (result != null) {
20570            result.changes = changes;
20571            result.activityRelaunched = !kept;
20572        }
20573        return kept;
20574    }
20575
20576    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20577            int displayId) {
20578        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20579        final int changes = mTempConfig.updateFrom(values);
20580        if (changes != 0) {
20581            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20582                    + mTempConfig + " for displayId=" + displayId);
20583            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20584
20585            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20586            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20587                // Reset the unsupported display size dialog.
20588                mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20589
20590                killAllBackgroundProcessesExcept(N,
20591                        ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20592            }
20593        }
20594
20595        // Update the configuration with WM first and check if any of the stacks need to be resized
20596        // due to the configuration change. If so, resize the stacks now and do any relaunches if
20597        // necessary. This way we don't need to relaunch again afterwards in
20598        // ensureActivityConfigurationLocked().
20599        if (mWindowManager != null) {
20600            final int[] resizedStacks =
20601                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20602            if (resizedStacks != null) {
20603                for (int stackId : resizedStacks) {
20604                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20605                }
20606            }
20607        }
20608
20609        return changes;
20610    }
20611
20612    /** Applies latest configuration and/or visibility updates if needed. */
20613    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20614        boolean kept = true;
20615        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20616        // mainStack is null during startup.
20617        if (mainStack != null) {
20618            if (changes != 0 && starting == null) {
20619                // If the configuration changed, and the caller is not already
20620                // in the process of starting an activity, then find the top
20621                // activity to check if its configuration needs to change.
20622                starting = mainStack.topRunningActivityLocked();
20623            }
20624
20625            if (starting != null) {
20626                kept = starting.ensureActivityConfigurationLocked(changes,
20627                        false /* preserveWindow */);
20628                // And we need to make sure at this point that all other activities
20629                // are made visible with the correct configuration.
20630                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20631                        !PRESERVE_WINDOWS);
20632            }
20633        }
20634
20635        return kept;
20636    }
20637
20638    /** Helper method that requests bounds from WM and applies them to stack. */
20639    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20640        final Rect newStackBounds = new Rect();
20641        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20642        mStackSupervisor.resizeStackLocked(
20643                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20644                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20645                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20646    }
20647
20648    /**
20649     * Decide based on the configuration whether we should show the ANR,
20650     * crash, etc dialogs.  The idea is that if there is no affordance to
20651     * press the on-screen buttons, or the user experience would be more
20652     * greatly impacted than the crash itself, we shouldn't show the dialog.
20653     *
20654     * A thought: SystemUI might also want to get told about this, the Power
20655     * dialog / global actions also might want different behaviors.
20656     */
20657    private static boolean shouldShowDialogs(Configuration config) {
20658        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20659                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20660                                   && config.navigation == Configuration.NAVIGATION_NONAV);
20661        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20662        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20663                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20664                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20665                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20666        return inputMethodExists && uiModeSupportsDialogs;
20667    }
20668
20669    @Override
20670    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20671        synchronized (this) {
20672            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20673            if (srec != null) {
20674                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20675            }
20676        }
20677        return false;
20678    }
20679
20680    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20681            Intent resultData) {
20682
20683        synchronized (this) {
20684            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20685            if (r != null) {
20686                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20687            }
20688            return false;
20689        }
20690    }
20691
20692    public int getLaunchedFromUid(IBinder activityToken) {
20693        ActivityRecord srec;
20694        synchronized (this) {
20695            srec = ActivityRecord.forTokenLocked(activityToken);
20696        }
20697        if (srec == null) {
20698            return -1;
20699        }
20700        return srec.launchedFromUid;
20701    }
20702
20703    public String getLaunchedFromPackage(IBinder activityToken) {
20704        ActivityRecord srec;
20705        synchronized (this) {
20706            srec = ActivityRecord.forTokenLocked(activityToken);
20707        }
20708        if (srec == null) {
20709            return null;
20710        }
20711        return srec.launchedFromPackage;
20712    }
20713
20714    // =========================================================
20715    // LIFETIME MANAGEMENT
20716    // =========================================================
20717
20718    // Returns whether the app is receiving broadcast.
20719    // If receiving, fetch all broadcast queues which the app is
20720    // the current [or imminent] receiver on.
20721    private boolean isReceivingBroadcastLocked(ProcessRecord app,
20722            ArraySet<BroadcastQueue> receivingQueues) {
20723        if (!app.curReceivers.isEmpty()) {
20724            for (BroadcastRecord r : app.curReceivers) {
20725                receivingQueues.add(r.queue);
20726            }
20727            return true;
20728        }
20729
20730        // It's not the current receiver, but it might be starting up to become one
20731        for (BroadcastQueue queue : mBroadcastQueues) {
20732            final BroadcastRecord r = queue.mPendingBroadcast;
20733            if (r != null && r.curApp == app) {
20734                // found it; report which queue it's in
20735                receivingQueues.add(queue);
20736            }
20737        }
20738
20739        return !receivingQueues.isEmpty();
20740    }
20741
20742    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20743            int targetUid, ComponentName targetComponent, String targetProcess) {
20744        if (!mTrackingAssociations) {
20745            return null;
20746        }
20747        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20748                = mAssociations.get(targetUid);
20749        if (components == null) {
20750            components = new ArrayMap<>();
20751            mAssociations.put(targetUid, components);
20752        }
20753        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20754        if (sourceUids == null) {
20755            sourceUids = new SparseArray<>();
20756            components.put(targetComponent, sourceUids);
20757        }
20758        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20759        if (sourceProcesses == null) {
20760            sourceProcesses = new ArrayMap<>();
20761            sourceUids.put(sourceUid, sourceProcesses);
20762        }
20763        Association ass = sourceProcesses.get(sourceProcess);
20764        if (ass == null) {
20765            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20766                    targetProcess);
20767            sourceProcesses.put(sourceProcess, ass);
20768        }
20769        ass.mCount++;
20770        ass.mNesting++;
20771        if (ass.mNesting == 1) {
20772            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20773            ass.mLastState = sourceState;
20774        }
20775        return ass;
20776    }
20777
20778    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20779            ComponentName targetComponent) {
20780        if (!mTrackingAssociations) {
20781            return;
20782        }
20783        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20784                = mAssociations.get(targetUid);
20785        if (components == null) {
20786            return;
20787        }
20788        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20789        if (sourceUids == null) {
20790            return;
20791        }
20792        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20793        if (sourceProcesses == null) {
20794            return;
20795        }
20796        Association ass = sourceProcesses.get(sourceProcess);
20797        if (ass == null || ass.mNesting <= 0) {
20798            return;
20799        }
20800        ass.mNesting--;
20801        if (ass.mNesting == 0) {
20802            long uptime = SystemClock.uptimeMillis();
20803            ass.mTime += uptime - ass.mStartTime;
20804            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20805                    += uptime - ass.mLastStateUptime;
20806            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20807        }
20808    }
20809
20810    private void noteUidProcessState(final int uid, final int state) {
20811        mBatteryStatsService.noteUidProcessState(uid, state);
20812        if (mTrackingAssociations) {
20813            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20814                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20815                        = mAssociations.valueAt(i1);
20816                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20817                    SparseArray<ArrayMap<String, Association>> sourceUids
20818                            = targetComponents.valueAt(i2);
20819                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20820                    if (sourceProcesses != null) {
20821                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20822                            Association ass = sourceProcesses.valueAt(i4);
20823                            if (ass.mNesting >= 1) {
20824                                // currently associated
20825                                long uptime = SystemClock.uptimeMillis();
20826                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20827                                        += uptime - ass.mLastStateUptime;
20828                                ass.mLastState = state;
20829                                ass.mLastStateUptime = uptime;
20830                            }
20831                        }
20832                    }
20833                }
20834            }
20835        }
20836    }
20837
20838    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20839            boolean doingAll, long now) {
20840        if (mAdjSeq == app.adjSeq) {
20841            // This adjustment has already been computed.
20842            return app.curRawAdj;
20843        }
20844
20845        if (app.thread == null) {
20846            app.adjSeq = mAdjSeq;
20847            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20848            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20849            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20850        }
20851
20852        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20853        app.adjSource = null;
20854        app.adjTarget = null;
20855        app.empty = false;
20856        app.cached = false;
20857
20858        final int activitiesSize = app.activities.size();
20859
20860        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20861            // The max adjustment doesn't allow this app to be anything
20862            // below foreground, so it is not worth doing work for it.
20863            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20864            app.adjType = "fixed";
20865            app.adjSeq = mAdjSeq;
20866            app.curRawAdj = app.maxAdj;
20867            app.foregroundActivities = false;
20868            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20869            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20870            // System processes can do UI, and when they do we want to have
20871            // them trim their memory after the user leaves the UI.  To
20872            // facilitate this, here we need to determine whether or not it
20873            // is currently showing UI.
20874            app.systemNoUi = true;
20875            if (app == TOP_APP) {
20876                app.systemNoUi = false;
20877                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20878                app.adjType = "pers-top-activity";
20879            } else if (app.hasTopUi) {
20880                app.systemNoUi = false;
20881                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20882                app.adjType = "pers-top-ui";
20883            } else if (activitiesSize > 0) {
20884                for (int j = 0; j < activitiesSize; j++) {
20885                    final ActivityRecord r = app.activities.get(j);
20886                    if (r.visible) {
20887                        app.systemNoUi = false;
20888                    }
20889                }
20890            }
20891            if (!app.systemNoUi) {
20892                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20893            }
20894            return (app.curAdj=app.maxAdj);
20895        }
20896
20897        app.systemNoUi = false;
20898
20899        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20900
20901        // Determine the importance of the process, starting with most
20902        // important to least, and assign an appropriate OOM adjustment.
20903        int adj;
20904        int schedGroup;
20905        int procState;
20906        boolean foregroundActivities = false;
20907        mTmpBroadcastQueue.clear();
20908        if (app == TOP_APP) {
20909            // The last app on the list is the foreground app.
20910            adj = ProcessList.FOREGROUND_APP_ADJ;
20911            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20912            app.adjType = "top-activity";
20913            foregroundActivities = true;
20914            procState = PROCESS_STATE_CUR_TOP;
20915            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20916        } else if (app.instr != null) {
20917            // Don't want to kill running instrumentation.
20918            adj = ProcessList.FOREGROUND_APP_ADJ;
20919            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20920            app.adjType = "instrumentation";
20921            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20922            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20923        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20924            // An app that is currently receiving a broadcast also
20925            // counts as being in the foreground for OOM killer purposes.
20926            // It's placed in a sched group based on the nature of the
20927            // broadcast as reflected by which queue it's active in.
20928            adj = ProcessList.FOREGROUND_APP_ADJ;
20929            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20930                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20931            app.adjType = "broadcast";
20932            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20933            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20934        } else if (app.executingServices.size() > 0) {
20935            // An app that is currently executing a service callback also
20936            // counts as being in the foreground.
20937            adj = ProcessList.FOREGROUND_APP_ADJ;
20938            schedGroup = app.execServicesFg ?
20939                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20940            app.adjType = "exec-service";
20941            procState = ActivityManager.PROCESS_STATE_SERVICE;
20942            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20943            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20944        } else {
20945            // As far as we know the process is empty.  We may change our mind later.
20946            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20947            // At this point we don't actually know the adjustment.  Use the cached adj
20948            // value that the caller wants us to.
20949            adj = cachedAdj;
20950            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20951            app.cached = true;
20952            app.empty = true;
20953            app.adjType = "cch-empty";
20954            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20955        }
20956
20957        // Examine all activities if not already foreground.
20958        if (!foregroundActivities && activitiesSize > 0) {
20959            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20960            for (int j = 0; j < activitiesSize; j++) {
20961                final ActivityRecord r = app.activities.get(j);
20962                if (r.app != app) {
20963                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20964                            + " instead of expected " + app);
20965                    if (r.app == null || (r.app.uid == app.uid)) {
20966                        // Only fix things up when they look sane
20967                        r.app = app;
20968                    } else {
20969                        continue;
20970                    }
20971                }
20972                if (r.visible) {
20973                    // App has a visible activity; only upgrade adjustment.
20974                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20975                        adj = ProcessList.VISIBLE_APP_ADJ;
20976                        app.adjType = "vis-activity";
20977                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20978                    }
20979                    if (procState > PROCESS_STATE_CUR_TOP) {
20980                        procState = PROCESS_STATE_CUR_TOP;
20981                        app.adjType = "vis-activity";
20982                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20983                    }
20984                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20985                    app.cached = false;
20986                    app.empty = false;
20987                    foregroundActivities = true;
20988                    final TaskRecord task = r.getTask();
20989                    if (task != null && minLayer > 0) {
20990                        final int layer = task.mLayerRank;
20991                        if (layer >= 0 && minLayer > layer) {
20992                            minLayer = layer;
20993                        }
20994                    }
20995                    break;
20996                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20997                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20998                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20999                        app.adjType = "pause-activity";
21000                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21001                    }
21002                    if (procState > PROCESS_STATE_CUR_TOP) {
21003                        procState = PROCESS_STATE_CUR_TOP;
21004                        app.adjType = "pause-activity";
21005                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21006                    }
21007                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21008                    app.cached = false;
21009                    app.empty = false;
21010                    foregroundActivities = true;
21011                } else if (r.state == ActivityState.STOPPING) {
21012                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21013                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21014                        app.adjType = "stop-activity";
21015                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21016                    }
21017                    // For the process state, we will at this point consider the
21018                    // process to be cached.  It will be cached either as an activity
21019                    // or empty depending on whether the activity is finishing.  We do
21020                    // this so that we can treat the process as cached for purposes of
21021                    // memory trimming (determing current memory level, trim command to
21022                    // send to process) since there can be an arbitrary number of stopping
21023                    // processes and they should soon all go into the cached state.
21024                    if (!r.finishing) {
21025                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21026                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21027                            app.adjType = "stop-activity";
21028                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21029                        }
21030                    }
21031                    app.cached = false;
21032                    app.empty = false;
21033                    foregroundActivities = true;
21034                } else {
21035                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21036                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21037                        app.adjType = "cch-act";
21038                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21039                    }
21040                }
21041            }
21042            if (adj == ProcessList.VISIBLE_APP_ADJ) {
21043                adj += minLayer;
21044            }
21045        }
21046
21047        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21048                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21049            if (app.foregroundServices) {
21050                // The user is aware of this app, so make it visible.
21051                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21052                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21053                app.cached = false;
21054                app.adjType = "fg-service";
21055                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21056                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21057            } else if (app.hasOverlayUi) {
21058                // The process is display an overlay UI.
21059                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21060                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21061                app.cached = false;
21062                app.adjType = "has-overlay-ui";
21063                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21064                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21065            }
21066        }
21067
21068        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21069                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21070            if (app.forcingToImportant != null) {
21071                // This is currently used for toasts...  they are not interactive, and
21072                // we don't want them to cause the app to become fully foreground (and
21073                // thus out of background check), so we yes the best background level we can.
21074                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21075                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21076                app.cached = false;
21077                app.adjType = "force-imp";
21078                app.adjSource = app.forcingToImportant;
21079                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21080                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21081            }
21082        }
21083
21084        if (app == mHeavyWeightProcess) {
21085            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21086                // We don't want to kill the current heavy-weight process.
21087                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21088                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21089                app.cached = false;
21090                app.adjType = "heavy";
21091                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21092            }
21093            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21094                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21095                app.adjType = "heavy";
21096                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21097            }
21098        }
21099
21100        if (app == mHomeProcess) {
21101            if (adj > ProcessList.HOME_APP_ADJ) {
21102                // This process is hosting what we currently consider to be the
21103                // home app, so we don't want to let it go into the background.
21104                adj = ProcessList.HOME_APP_ADJ;
21105                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21106                app.cached = false;
21107                app.adjType = "home";
21108                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21109            }
21110            if (procState > ActivityManager.PROCESS_STATE_HOME) {
21111                procState = ActivityManager.PROCESS_STATE_HOME;
21112                app.adjType = "home";
21113                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21114            }
21115        }
21116
21117        if (app == mPreviousProcess && app.activities.size() > 0) {
21118            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21119                // This was the previous process that showed UI to the user.
21120                // We want to try to keep it around more aggressively, to give
21121                // a good experience around switching between two apps.
21122                adj = ProcessList.PREVIOUS_APP_ADJ;
21123                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21124                app.cached = false;
21125                app.adjType = "previous";
21126                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21127            }
21128            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21129                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21130                app.adjType = "previous";
21131                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21132            }
21133        }
21134
21135        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21136                + " reason=" + app.adjType);
21137
21138        // By default, we use the computed adjustment.  It may be changed if
21139        // there are applications dependent on our services or providers, but
21140        // this gives us a baseline and makes sure we don't get into an
21141        // infinite recursion.
21142        app.adjSeq = mAdjSeq;
21143        app.curRawAdj = adj;
21144        app.hasStartedServices = false;
21145
21146        if (mBackupTarget != null && app == mBackupTarget.app) {
21147            // If possible we want to avoid killing apps while they're being backed up
21148            if (adj > ProcessList.BACKUP_APP_ADJ) {
21149                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21150                adj = ProcessList.BACKUP_APP_ADJ;
21151                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21152                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21153                }
21154                app.adjType = "backup";
21155                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21156                app.cached = false;
21157            }
21158            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21159                procState = ActivityManager.PROCESS_STATE_BACKUP;
21160                app.adjType = "backup";
21161                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21162            }
21163        }
21164
21165        boolean mayBeTop = false;
21166        String mayBeTopType = null;
21167        Object mayBeTopSource = null;
21168        Object mayBeTopTarget = null;
21169
21170        for (int is = app.services.size()-1;
21171                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21172                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21173                        || procState > ActivityManager.PROCESS_STATE_TOP);
21174                is--) {
21175            ServiceRecord s = app.services.valueAt(is);
21176            if (s.startRequested) {
21177                app.hasStartedServices = true;
21178                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21179                    procState = ActivityManager.PROCESS_STATE_SERVICE;
21180                    app.adjType = "started-services";
21181                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21182                }
21183                if (app.hasShownUi && app != mHomeProcess) {
21184                    // If this process has shown some UI, let it immediately
21185                    // go to the LRU list because it may be pretty heavy with
21186                    // UI stuff.  We'll tag it with a label just to help
21187                    // debug and understand what is going on.
21188                    if (adj > ProcessList.SERVICE_ADJ) {
21189                        app.adjType = "cch-started-ui-services";
21190                    }
21191                } else {
21192                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21193                        // This service has seen some activity within
21194                        // recent memory, so we will keep its process ahead
21195                        // of the background processes.
21196                        if (adj > ProcessList.SERVICE_ADJ) {
21197                            adj = ProcessList.SERVICE_ADJ;
21198                            app.adjType = "started-services";
21199                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21200                            app.cached = false;
21201                        }
21202                    }
21203                    // If we have let the service slide into the background
21204                    // state, still have some text describing what it is doing
21205                    // even though the service no longer has an impact.
21206                    if (adj > ProcessList.SERVICE_ADJ) {
21207                        app.adjType = "cch-started-services";
21208                    }
21209                }
21210            }
21211
21212            for (int conni = s.connections.size()-1;
21213                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21214                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21215                            || procState > ActivityManager.PROCESS_STATE_TOP);
21216                    conni--) {
21217                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21218                for (int i = 0;
21219                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21220                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21221                                || procState > ActivityManager.PROCESS_STATE_TOP);
21222                        i++) {
21223                    // XXX should compute this based on the max of
21224                    // all connected clients.
21225                    ConnectionRecord cr = clist.get(i);
21226                    if (cr.binding.client == app) {
21227                        // Binding to ourself is not interesting.
21228                        continue;
21229                    }
21230
21231                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21232                        ProcessRecord client = cr.binding.client;
21233                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
21234                                TOP_APP, doingAll, now);
21235                        int clientProcState = client.curProcState;
21236                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21237                            // If the other app is cached for any reason, for purposes here
21238                            // we are going to consider it empty.  The specific cached state
21239                            // doesn't propagate except under certain conditions.
21240                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21241                        }
21242                        String adjType = null;
21243                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21244                            // Not doing bind OOM management, so treat
21245                            // this guy more like a started service.
21246                            if (app.hasShownUi && app != mHomeProcess) {
21247                                // If this process has shown some UI, let it immediately
21248                                // go to the LRU list because it may be pretty heavy with
21249                                // UI stuff.  We'll tag it with a label just to help
21250                                // debug and understand what is going on.
21251                                if (adj > clientAdj) {
21252                                    adjType = "cch-bound-ui-services";
21253                                }
21254                                app.cached = false;
21255                                clientAdj = adj;
21256                                clientProcState = procState;
21257                            } else {
21258                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21259                                    // This service has not seen activity within
21260                                    // recent memory, so allow it to drop to the
21261                                    // LRU list if there is no other reason to keep
21262                                    // it around.  We'll also tag it with a label just
21263                                    // to help debug and undertand what is going on.
21264                                    if (adj > clientAdj) {
21265                                        adjType = "cch-bound-services";
21266                                    }
21267                                    clientAdj = adj;
21268                                }
21269                            }
21270                        }
21271                        if (adj > clientAdj) {
21272                            // If this process has recently shown UI, and
21273                            // the process that is binding to it is less
21274                            // important than being visible, then we don't
21275                            // care about the binding as much as we care
21276                            // about letting this process get into the LRU
21277                            // list to be killed and restarted if needed for
21278                            // memory.
21279                            if (app.hasShownUi && app != mHomeProcess
21280                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21281                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21282                                    adjType = "cch-bound-ui-services";
21283                                }
21284                            } else {
21285                                int newAdj;
21286                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21287                                        |Context.BIND_IMPORTANT)) != 0) {
21288                                    newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21289                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21290                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21291                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21292                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21293                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21294                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21295                                    newAdj = clientAdj;
21296                                } else {
21297                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
21298                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21299                                    } else {
21300                                        newAdj = adj;
21301                                    }
21302                                }
21303                                if (!client.cached) {
21304                                    app.cached = false;
21305                                }
21306                                if (adj >  newAdj) {
21307                                    adj = newAdj;
21308                                    adjType = "service";
21309                                }
21310                            }
21311                        }
21312                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21313                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21314                            // This will treat important bound services identically to
21315                            // the top app, which may behave differently than generic
21316                            // foreground work.
21317                            if (client.curSchedGroup > schedGroup) {
21318                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21319                                    schedGroup = client.curSchedGroup;
21320                                } else {
21321                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21322                                }
21323                            }
21324                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21325                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21326                                    // Special handling of clients who are in the top state.
21327                                    // We *may* want to consider this process to be in the
21328                                    // top state as well, but only if there is not another
21329                                    // reason for it to be running.  Being on the top is a
21330                                    // special state, meaning you are specifically running
21331                                    // for the current top app.  If the process is already
21332                                    // running in the background for some other reason, it
21333                                    // is more important to continue considering it to be
21334                                    // in the background state.
21335                                    mayBeTop = true;
21336                                    mayBeTopType = "service";
21337                                    mayBeTopSource = cr.binding.client;
21338                                    mayBeTopTarget = s.name;
21339                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21340                                } else {
21341                                    // Special handling for above-top states (persistent
21342                                    // processes).  These should not bring the current process
21343                                    // into the top state, since they are not on top.  Instead
21344                                    // give them the best state after that.
21345                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21346                                        clientProcState =
21347                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21348                                    } else if (mWakefulness
21349                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21350                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21351                                                    != 0) {
21352                                        clientProcState =
21353                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21354                                    } else {
21355                                        clientProcState =
21356                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21357                                    }
21358                                }
21359                            }
21360                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21361                            if (clientProcState <
21362                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21363                                clientProcState =
21364                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21365                            }
21366                        } else {
21367                            if (clientProcState <
21368                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21369                                clientProcState =
21370                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21371                            }
21372                        }
21373                        if (procState > clientProcState) {
21374                            procState = clientProcState;
21375                            if (adjType == null) {
21376                                adjType = "service";
21377                            }
21378                        }
21379                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21380                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21381                            app.pendingUiClean = true;
21382                        }
21383                        if (adjType != null) {
21384                            app.adjType = adjType;
21385                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21386                                    .REASON_SERVICE_IN_USE;
21387                            app.adjSource = cr.binding.client;
21388                            app.adjSourceProcState = clientProcState;
21389                            app.adjTarget = s.name;
21390                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21391                                    + ": " + app + ", due to " + cr.binding.client
21392                                    + " adj=" + adj + " procState=" + procState);
21393                        }
21394                    }
21395                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21396                        app.treatLikeActivity = true;
21397                    }
21398                    final ActivityRecord a = cr.activity;
21399                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21400                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21401                            (a.visible || a.state == ActivityState.RESUMED ||
21402                             a.state == ActivityState.PAUSING)) {
21403                            adj = ProcessList.FOREGROUND_APP_ADJ;
21404                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21405                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21406                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21407                                } else {
21408                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21409                                }
21410                            }
21411                            app.cached = false;
21412                            app.adjType = "service";
21413                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21414                                    .REASON_SERVICE_IN_USE;
21415                            app.adjSource = a;
21416                            app.adjSourceProcState = procState;
21417                            app.adjTarget = s.name;
21418                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21419                                    + app);
21420                        }
21421                    }
21422                }
21423            }
21424        }
21425
21426        for (int provi = app.pubProviders.size()-1;
21427                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21428                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21429                        || procState > ActivityManager.PROCESS_STATE_TOP);
21430                provi--) {
21431            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21432            for (int i = cpr.connections.size()-1;
21433                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21434                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21435                            || procState > ActivityManager.PROCESS_STATE_TOP);
21436                    i--) {
21437                ContentProviderConnection conn = cpr.connections.get(i);
21438                ProcessRecord client = conn.client;
21439                if (client == app) {
21440                    // Being our own client is not interesting.
21441                    continue;
21442                }
21443                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21444                int clientProcState = client.curProcState;
21445                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21446                    // If the other app is cached for any reason, for purposes here
21447                    // we are going to consider it empty.
21448                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21449                }
21450                String adjType = null;
21451                if (adj > clientAdj) {
21452                    if (app.hasShownUi && app != mHomeProcess
21453                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21454                        adjType = "cch-ui-provider";
21455                    } else {
21456                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21457                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21458                        adjType = "provider";
21459                    }
21460                    app.cached &= client.cached;
21461                }
21462                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21463                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21464                        // Special handling of clients who are in the top state.
21465                        // We *may* want to consider this process to be in the
21466                        // top state as well, but only if there is not another
21467                        // reason for it to be running.  Being on the top is a
21468                        // special state, meaning you are specifically running
21469                        // for the current top app.  If the process is already
21470                        // running in the background for some other reason, it
21471                        // is more important to continue considering it to be
21472                        // in the background state.
21473                        mayBeTop = true;
21474                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21475                        mayBeTopType = adjType = "provider-top";
21476                        mayBeTopSource = client;
21477                        mayBeTopTarget = cpr.name;
21478                    } else {
21479                        // Special handling for above-top states (persistent
21480                        // processes).  These should not bring the current process
21481                        // into the top state, since they are not on top.  Instead
21482                        // give them the best state after that.
21483                        clientProcState =
21484                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21485                        if (adjType == null) {
21486                            adjType = "provider";
21487                        }
21488                    }
21489                }
21490                if (procState > clientProcState) {
21491                    procState = clientProcState;
21492                }
21493                if (client.curSchedGroup > schedGroup) {
21494                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21495                }
21496                if (adjType != null) {
21497                    app.adjType = adjType;
21498                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21499                            .REASON_PROVIDER_IN_USE;
21500                    app.adjSource = client;
21501                    app.adjSourceProcState = clientProcState;
21502                    app.adjTarget = cpr.name;
21503                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21504                            + ": " + app + ", due to " + client
21505                            + " adj=" + adj + " procState=" + procState);
21506                }
21507            }
21508            // If the provider has external (non-framework) process
21509            // dependencies, ensure that its adjustment is at least
21510            // FOREGROUND_APP_ADJ.
21511            if (cpr.hasExternalProcessHandles()) {
21512                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21513                    adj = ProcessList.FOREGROUND_APP_ADJ;
21514                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21515                    app.cached = false;
21516                    app.adjType = "ext-provider";
21517                    app.adjTarget = cpr.name;
21518                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21519                }
21520                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21521                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21522                }
21523            }
21524        }
21525
21526        if (app.lastProviderTime > 0 &&
21527                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21528            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21529                adj = ProcessList.PREVIOUS_APP_ADJ;
21530                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21531                app.cached = false;
21532                app.adjType = "recent-provider";
21533                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21534            }
21535            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21536                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21537                app.adjType = "recent-provider";
21538                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21539            }
21540        }
21541
21542        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21543            // A client of one of our services or providers is in the top state.  We
21544            // *may* want to be in the top state, but not if we are already running in
21545            // the background for some other reason.  For the decision here, we are going
21546            // to pick out a few specific states that we want to remain in when a client
21547            // is top (states that tend to be longer-term) and otherwise allow it to go
21548            // to the top state.
21549            switch (procState) {
21550                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21551                    // Something else is keeping it at this level, just leave it.
21552                    break;
21553                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21554                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21555                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21556                case ActivityManager.PROCESS_STATE_SERVICE:
21557                    // These all are longer-term states, so pull them up to the top
21558                    // of the background states, but not all the way to the top state.
21559                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21560                    app.adjType = mayBeTopType;
21561                    app.adjSource = mayBeTopSource;
21562                    app.adjTarget = mayBeTopTarget;
21563                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21564                            + ": " + app + ", due to " + mayBeTopSource
21565                            + " adj=" + adj + " procState=" + procState);
21566                    break;
21567                default:
21568                    // Otherwise, top is a better choice, so take it.
21569                    procState = ActivityManager.PROCESS_STATE_TOP;
21570                    app.adjType = mayBeTopType;
21571                    app.adjSource = mayBeTopSource;
21572                    app.adjTarget = mayBeTopTarget;
21573                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21574                            + ": " + app + ", due to " + mayBeTopSource
21575                            + " adj=" + adj + " procState=" + procState);
21576                    break;
21577            }
21578        }
21579
21580        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21581            if (app.hasClientActivities) {
21582                // This is a cached process, but with client activities.  Mark it so.
21583                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21584                app.adjType = "cch-client-act";
21585            } else if (app.treatLikeActivity) {
21586                // This is a cached process, but somebody wants us to treat it like it has
21587                // an activity, okay!
21588                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21589                app.adjType = "cch-as-act";
21590            }
21591        }
21592
21593        if (adj == ProcessList.SERVICE_ADJ) {
21594            if (doingAll) {
21595                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21596                mNewNumServiceProcs++;
21597                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21598                if (!app.serviceb) {
21599                    // This service isn't far enough down on the LRU list to
21600                    // normally be a B service, but if we are low on RAM and it
21601                    // is large we want to force it down since we would prefer to
21602                    // keep launcher over it.
21603                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21604                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21605                        app.serviceHighRam = true;
21606                        app.serviceb = true;
21607                        //Slog.i(TAG, "ADJ " + app + " high ram!");
21608                    } else {
21609                        mNewNumAServiceProcs++;
21610                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
21611                    }
21612                } else {
21613                    app.serviceHighRam = false;
21614                }
21615            }
21616            if (app.serviceb) {
21617                adj = ProcessList.SERVICE_B_ADJ;
21618            }
21619        }
21620
21621        app.curRawAdj = adj;
21622
21623        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21624        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21625        if (adj > app.maxAdj) {
21626            adj = app.maxAdj;
21627            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21628                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21629            }
21630        }
21631
21632        // Do final modification to adj.  Everything we do between here and applying
21633        // the final setAdj must be done in this function, because we will also use
21634        // it when computing the final cached adj later.  Note that we don't need to
21635        // worry about this for max adj above, since max adj will always be used to
21636        // keep it out of the cached vaues.
21637        app.curAdj = app.modifyRawOomAdj(adj);
21638        app.curSchedGroup = schedGroup;
21639        app.curProcState = procState;
21640        app.foregroundActivities = foregroundActivities;
21641
21642        return app.curRawAdj;
21643    }
21644
21645    /**
21646     * Record new PSS sample for a process.
21647     */
21648    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21649            long now) {
21650        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21651                swapPss * 1024);
21652        proc.lastPssTime = now;
21653        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21654        if (DEBUG_PSS) Slog.d(TAG_PSS,
21655                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21656                + " state=" + ProcessList.makeProcStateString(procState));
21657        if (proc.initialIdlePss == 0) {
21658            proc.initialIdlePss = pss;
21659        }
21660        proc.lastPss = pss;
21661        proc.lastSwapPss = swapPss;
21662        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21663            proc.lastCachedPss = pss;
21664            proc.lastCachedSwapPss = swapPss;
21665        }
21666
21667        final SparseArray<Pair<Long, String>> watchUids
21668                = mMemWatchProcesses.getMap().get(proc.processName);
21669        Long check = null;
21670        if (watchUids != null) {
21671            Pair<Long, String> val = watchUids.get(proc.uid);
21672            if (val == null) {
21673                val = watchUids.get(0);
21674            }
21675            if (val != null) {
21676                check = val.first;
21677            }
21678        }
21679        if (check != null) {
21680            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21681                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21682                if (!isDebuggable) {
21683                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21684                        isDebuggable = true;
21685                    }
21686                }
21687                if (isDebuggable) {
21688                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21689                    final ProcessRecord myProc = proc;
21690                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
21691                    mMemWatchDumpProcName = proc.processName;
21692                    mMemWatchDumpFile = heapdumpFile.toString();
21693                    mMemWatchDumpPid = proc.pid;
21694                    mMemWatchDumpUid = proc.uid;
21695                    BackgroundThread.getHandler().post(new Runnable() {
21696                        @Override
21697                        public void run() {
21698                            revokeUriPermission(ActivityThread.currentActivityThread()
21699                                            .getApplicationThread(),
21700                                    null, DumpHeapActivity.JAVA_URI,
21701                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
21702                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21703                                    UserHandle.myUserId());
21704                            ParcelFileDescriptor fd = null;
21705                            try {
21706                                heapdumpFile.delete();
21707                                fd = ParcelFileDescriptor.open(heapdumpFile,
21708                                        ParcelFileDescriptor.MODE_CREATE |
21709                                                ParcelFileDescriptor.MODE_TRUNCATE |
21710                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
21711                                                ParcelFileDescriptor.MODE_APPEND);
21712                                IApplicationThread thread = myProc.thread;
21713                                if (thread != null) {
21714                                    try {
21715                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
21716                                                "Requesting dump heap from "
21717                                                + myProc + " to " + heapdumpFile);
21718                                        thread.dumpHeap(/* managed= */ true,
21719                                                /* mallocInfo= */ false, /* runGc= */ false,
21720                                                heapdumpFile.toString(), fd);
21721                                    } catch (RemoteException e) {
21722                                    }
21723                                }
21724                            } catch (FileNotFoundException e) {
21725                                e.printStackTrace();
21726                            } finally {
21727                                if (fd != null) {
21728                                    try {
21729                                        fd.close();
21730                                    } catch (IOException e) {
21731                                    }
21732                                }
21733                            }
21734                        }
21735                    });
21736                } else {
21737                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21738                            + ", but debugging not enabled");
21739                }
21740            }
21741        }
21742    }
21743
21744    /**
21745     * Schedule PSS collection of a process.
21746     */
21747    void requestPssLocked(ProcessRecord proc, int procState) {
21748        if (mPendingPssProcesses.contains(proc)) {
21749            return;
21750        }
21751        if (mPendingPssProcesses.size() == 0) {
21752            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21753        }
21754        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21755        proc.pssProcState = procState;
21756        mPendingPssProcesses.add(proc);
21757    }
21758
21759    /**
21760     * Schedule PSS collection of all processes.
21761     */
21762    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21763        if (!always) {
21764            if (now < (mLastFullPssTime +
21765                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21766                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
21767                return;
21768            }
21769        }
21770        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21771        mLastFullPssTime = now;
21772        mFullPssPending = true;
21773        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21774        mPendingPssProcesses.clear();
21775        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21776            ProcessRecord app = mLruProcesses.get(i);
21777            if (app.thread == null
21778                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21779                continue;
21780            }
21781            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21782                app.pssProcState = app.setProcState;
21783                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21784                        mTestPssMode, isSleepingLocked(), now);
21785                mPendingPssProcesses.add(app);
21786            }
21787        }
21788        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21789    }
21790
21791    public void setTestPssMode(boolean enabled) {
21792        synchronized (this) {
21793            mTestPssMode = enabled;
21794            if (enabled) {
21795                // Whenever we enable the mode, we want to take a snapshot all of current
21796                // process mem use.
21797                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21798            }
21799        }
21800    }
21801
21802    /**
21803     * Ask a given process to GC right now.
21804     */
21805    final void performAppGcLocked(ProcessRecord app) {
21806        try {
21807            app.lastRequestedGc = SystemClock.uptimeMillis();
21808            if (app.thread != null) {
21809                if (app.reportLowMemory) {
21810                    app.reportLowMemory = false;
21811                    app.thread.scheduleLowMemory();
21812                } else {
21813                    app.thread.processInBackground();
21814                }
21815            }
21816        } catch (Exception e) {
21817            // whatever.
21818        }
21819    }
21820
21821    /**
21822     * Returns true if things are idle enough to perform GCs.
21823     */
21824    private final boolean canGcNowLocked() {
21825        boolean processingBroadcasts = false;
21826        for (BroadcastQueue q : mBroadcastQueues) {
21827            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21828                processingBroadcasts = true;
21829            }
21830        }
21831        return !processingBroadcasts
21832                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21833    }
21834
21835    /**
21836     * Perform GCs on all processes that are waiting for it, but only
21837     * if things are idle.
21838     */
21839    final void performAppGcsLocked() {
21840        final int N = mProcessesToGc.size();
21841        if (N <= 0) {
21842            return;
21843        }
21844        if (canGcNowLocked()) {
21845            while (mProcessesToGc.size() > 0) {
21846                ProcessRecord proc = mProcessesToGc.remove(0);
21847                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21848                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21849                            <= SystemClock.uptimeMillis()) {
21850                        // To avoid spamming the system, we will GC processes one
21851                        // at a time, waiting a few seconds between each.
21852                        performAppGcLocked(proc);
21853                        scheduleAppGcsLocked();
21854                        return;
21855                    } else {
21856                        // It hasn't been long enough since we last GCed this
21857                        // process...  put it in the list to wait for its time.
21858                        addProcessToGcListLocked(proc);
21859                        break;
21860                    }
21861                }
21862            }
21863
21864            scheduleAppGcsLocked();
21865        }
21866    }
21867
21868    /**
21869     * If all looks good, perform GCs on all processes waiting for them.
21870     */
21871    final void performAppGcsIfAppropriateLocked() {
21872        if (canGcNowLocked()) {
21873            performAppGcsLocked();
21874            return;
21875        }
21876        // Still not idle, wait some more.
21877        scheduleAppGcsLocked();
21878    }
21879
21880    /**
21881     * Schedule the execution of all pending app GCs.
21882     */
21883    final void scheduleAppGcsLocked() {
21884        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21885
21886        if (mProcessesToGc.size() > 0) {
21887            // Schedule a GC for the time to the next process.
21888            ProcessRecord proc = mProcessesToGc.get(0);
21889            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21890
21891            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21892            long now = SystemClock.uptimeMillis();
21893            if (when < (now+mConstants.GC_TIMEOUT)) {
21894                when = now + mConstants.GC_TIMEOUT;
21895            }
21896            mHandler.sendMessageAtTime(msg, when);
21897        }
21898    }
21899
21900    /**
21901     * Add a process to the array of processes waiting to be GCed.  Keeps the
21902     * list in sorted order by the last GC time.  The process can't already be
21903     * on the list.
21904     */
21905    final void addProcessToGcListLocked(ProcessRecord proc) {
21906        boolean added = false;
21907        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21908            if (mProcessesToGc.get(i).lastRequestedGc <
21909                    proc.lastRequestedGc) {
21910                added = true;
21911                mProcessesToGc.add(i+1, proc);
21912                break;
21913            }
21914        }
21915        if (!added) {
21916            mProcessesToGc.add(0, proc);
21917        }
21918    }
21919
21920    /**
21921     * Set up to ask a process to GC itself.  This will either do it
21922     * immediately, or put it on the list of processes to gc the next
21923     * time things are idle.
21924     */
21925    final void scheduleAppGcLocked(ProcessRecord app) {
21926        long now = SystemClock.uptimeMillis();
21927        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21928            return;
21929        }
21930        if (!mProcessesToGc.contains(app)) {
21931            addProcessToGcListLocked(app);
21932            scheduleAppGcsLocked();
21933        }
21934    }
21935
21936    final void checkExcessivePowerUsageLocked() {
21937        updateCpuStatsNow();
21938
21939        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21940        boolean doCpuKills = true;
21941        if (mLastPowerCheckUptime == 0) {
21942            doCpuKills = false;
21943        }
21944        final long curUptime = SystemClock.uptimeMillis();
21945        final long uptimeSince = curUptime - mLastPowerCheckUptime;
21946        mLastPowerCheckUptime = curUptime;
21947        int i = mLruProcesses.size();
21948        while (i > 0) {
21949            i--;
21950            ProcessRecord app = mLruProcesses.get(i);
21951            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21952                if (app.lastCpuTime <= 0) {
21953                    continue;
21954                }
21955                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21956                if (DEBUG_POWER) {
21957                    StringBuilder sb = new StringBuilder(128);
21958                    sb.append("CPU for ");
21959                    app.toShortString(sb);
21960                    sb.append(": over ");
21961                    TimeUtils.formatDuration(uptimeSince, sb);
21962                    sb.append(" used ");
21963                    TimeUtils.formatDuration(cputimeUsed, sb);
21964                    sb.append(" (");
21965                    sb.append((cputimeUsed*100)/uptimeSince);
21966                    sb.append("%)");
21967                    Slog.i(TAG_POWER, sb.toString());
21968                }
21969                // If the process has used too much CPU over the last duration, the
21970                // user probably doesn't want this, so kill!
21971                if (doCpuKills && uptimeSince > 0) {
21972                    // What is the limit for this process?
21973                    int cpuLimit;
21974                    long checkDur = curUptime - app.whenUnimportant;
21975                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21976                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21977                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21978                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21979                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21980                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21981                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21982                    } else {
21983                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
21984                    }
21985                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
21986                        synchronized (stats) {
21987                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21988                                    uptimeSince, cputimeUsed);
21989                        }
21990                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
21991                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
21992                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21993                    }
21994                }
21995                app.lastCpuTime = app.curCpuTime;
21996            }
21997        }
21998    }
21999
22000    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22001            long nowElapsed) {
22002        boolean success = true;
22003
22004        if (app.curRawAdj != app.setRawAdj) {
22005            app.setRawAdj = app.curRawAdj;
22006        }
22007
22008        int changes = 0;
22009
22010        if (app.curAdj != app.setAdj) {
22011            ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22012            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22013                String msg = "Set " + app.pid + " " + app.processName + " adj "
22014                        + app.curAdj + ": " + app.adjType;
22015                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22016            }
22017            app.setAdj = app.curAdj;
22018            app.verifiedAdj = ProcessList.INVALID_ADJ;
22019        }
22020
22021        if (app.setSchedGroup != app.curSchedGroup) {
22022            int oldSchedGroup = app.setSchedGroup;
22023            app.setSchedGroup = app.curSchedGroup;
22024            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22025                String msg = "Setting sched group of " + app.processName
22026                        + " to " + app.curSchedGroup;
22027                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22028            }
22029            if (app.waitingToKill != null && app.curReceivers.isEmpty()
22030                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22031                app.kill(app.waitingToKill, true);
22032                success = false;
22033            } else {
22034                int processGroup;
22035                switch (app.curSchedGroup) {
22036                    case ProcessList.SCHED_GROUP_BACKGROUND:
22037                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22038                        break;
22039                    case ProcessList.SCHED_GROUP_TOP_APP:
22040                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22041                        processGroup = THREAD_GROUP_TOP_APP;
22042                        break;
22043                    default:
22044                        processGroup = THREAD_GROUP_DEFAULT;
22045                        break;
22046                }
22047                long oldId = Binder.clearCallingIdentity();
22048                try {
22049                    setProcessGroup(app.pid, processGroup);
22050                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22051                        // do nothing if we already switched to RT
22052                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22053                            mVrController.onTopProcChangedLocked(app);
22054                            if (mUseFifoUiScheduling) {
22055                                // Switch UI pipeline for app to SCHED_FIFO
22056                                app.savedPriority = Process.getThreadPriority(app.pid);
22057                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22058                                if (app.renderThreadTid != 0) {
22059                                    scheduleAsFifoPriority(app.renderThreadTid,
22060                                        /* suppressLogs */true);
22061                                    if (DEBUG_OOM_ADJ) {
22062                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
22063                                            app.renderThreadTid + ") to FIFO");
22064                                    }
22065                                } else {
22066                                    if (DEBUG_OOM_ADJ) {
22067                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
22068                                    }
22069                                }
22070                            } else {
22071                                // Boost priority for top app UI and render threads
22072                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22073                                if (app.renderThreadTid != 0) {
22074                                    try {
22075                                        setThreadPriority(app.renderThreadTid,
22076                                                TOP_APP_PRIORITY_BOOST);
22077                                    } catch (IllegalArgumentException e) {
22078                                        // thread died, ignore
22079                                    }
22080                                }
22081                            }
22082                        }
22083                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22084                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22085                        mVrController.onTopProcChangedLocked(app);
22086                        if (mUseFifoUiScheduling) {
22087                            try {
22088                                // Reset UI pipeline to SCHED_OTHER
22089                                setThreadScheduler(app.pid, SCHED_OTHER, 0);
22090                                setThreadPriority(app.pid, app.savedPriority);
22091                                if (app.renderThreadTid != 0) {
22092                                    setThreadScheduler(app.renderThreadTid,
22093                                        SCHED_OTHER, 0);
22094                                    setThreadPriority(app.renderThreadTid, -4);
22095                                }
22096                            } catch (IllegalArgumentException e) {
22097                                Slog.w(TAG,
22098                                        "Failed to set scheduling policy, thread does not exist:\n"
22099                                                + e);
22100                            } catch (SecurityException e) {
22101                                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22102                            }
22103                        } else {
22104                            // Reset priority for top app UI and render threads
22105                            setThreadPriority(app.pid, 0);
22106                            if (app.renderThreadTid != 0) {
22107                                setThreadPriority(app.renderThreadTid, 0);
22108                            }
22109                        }
22110                    }
22111                } catch (Exception e) {
22112                    if (false) {
22113                        Slog.w(TAG, "Failed setting process group of " + app.pid
22114                                + " to " + app.curSchedGroup);
22115                        Slog.w(TAG, "at location", e);
22116                    }
22117                } finally {
22118                    Binder.restoreCallingIdentity(oldId);
22119                }
22120            }
22121        }
22122        if (app.repForegroundActivities != app.foregroundActivities) {
22123            app.repForegroundActivities = app.foregroundActivities;
22124            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22125        }
22126        if (app.repProcState != app.curProcState) {
22127            app.repProcState = app.curProcState;
22128            if (app.thread != null) {
22129                try {
22130                    if (false) {
22131                        //RuntimeException h = new RuntimeException("here");
22132                        Slog.i(TAG, "Sending new process state " + app.repProcState
22133                                + " to " + app /*, h*/);
22134                    }
22135                    app.thread.setProcessState(app.repProcState);
22136                } catch (RemoteException e) {
22137                }
22138            }
22139        }
22140        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22141                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22142            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22143                // Experimental code to more aggressively collect pss while
22144                // running test...  the problem is that this tends to collect
22145                // the data right when a process is transitioning between process
22146                // states, which well tend to give noisy data.
22147                long start = SystemClock.uptimeMillis();
22148                long pss = Debug.getPss(app.pid, mTmpLong, null);
22149                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22150                mPendingPssProcesses.remove(app);
22151                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22152                        + " to " + app.curProcState + ": "
22153                        + (SystemClock.uptimeMillis()-start) + "ms");
22154            }
22155            app.lastStateTime = now;
22156            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22157                    mTestPssMode, isSleepingLocked(), now);
22158            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22159                    + ProcessList.makeProcStateString(app.setProcState) + " to "
22160                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22161                    + (app.nextPssTime-now) + ": " + app);
22162        } else {
22163            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22164                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22165                    mTestPssMode)))) {
22166                requestPssLocked(app, app.setProcState);
22167                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22168                        mTestPssMode, isSleepingLocked(), now);
22169            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22170                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22171        }
22172        if (app.setProcState != app.curProcState) {
22173            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22174                String msg = "Proc state change of " + app.processName
22175                        + " to " + app.curProcState;
22176                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22177            }
22178            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22179            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22180            if (setImportant && !curImportant) {
22181                // This app is no longer something we consider important enough to allow to
22182                // use arbitrary amounts of battery power.  Note
22183                // its current CPU time to later know to kill it if
22184                // it is not behaving well.
22185                app.whenUnimportant = now;
22186                app.lastCpuTime = 0;
22187            }
22188            // Inform UsageStats of important process state change
22189            // Must be called before updating setProcState
22190            maybeUpdateUsageStatsLocked(app, nowElapsed);
22191
22192            app.setProcState = app.curProcState;
22193            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22194                app.notCachedSinceIdle = false;
22195            }
22196            if (!doingAll) {
22197                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22198            } else {
22199                app.procStateChanged = true;
22200            }
22201        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22202                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22203            // For apps that sit around for a long time in the interactive state, we need
22204            // to report this at least once a day so they don't go idle.
22205            maybeUpdateUsageStatsLocked(app, nowElapsed);
22206        }
22207
22208        if (changes != 0) {
22209            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22210                    "Changes in " + app + ": " + changes);
22211            int i = mPendingProcessChanges.size()-1;
22212            ProcessChangeItem item = null;
22213            while (i >= 0) {
22214                item = mPendingProcessChanges.get(i);
22215                if (item.pid == app.pid) {
22216                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22217                            "Re-using existing item: " + item);
22218                    break;
22219                }
22220                i--;
22221            }
22222            if (i < 0) {
22223                // No existing item in pending changes; need a new one.
22224                final int NA = mAvailProcessChanges.size();
22225                if (NA > 0) {
22226                    item = mAvailProcessChanges.remove(NA-1);
22227                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22228                            "Retrieving available item: " + item);
22229                } else {
22230                    item = new ProcessChangeItem();
22231                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22232                            "Allocating new item: " + item);
22233                }
22234                item.changes = 0;
22235                item.pid = app.pid;
22236                item.uid = app.info.uid;
22237                if (mPendingProcessChanges.size() == 0) {
22238                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22239                            "*** Enqueueing dispatch processes changed!");
22240                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22241                }
22242                mPendingProcessChanges.add(item);
22243            }
22244            item.changes |= changes;
22245            item.foregroundActivities = app.repForegroundActivities;
22246            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22247                    "Item " + Integer.toHexString(System.identityHashCode(item))
22248                    + " " + app.toShortString() + ": changes=" + item.changes
22249                    + " foreground=" + item.foregroundActivities
22250                    + " type=" + app.adjType + " source=" + app.adjSource
22251                    + " target=" + app.adjTarget);
22252        }
22253
22254        return success;
22255    }
22256
22257    private boolean isEphemeralLocked(int uid) {
22258        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22259        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22260            return false;
22261        }
22262        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22263                packages[0]);
22264    }
22265
22266    @VisibleForTesting
22267    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22268        final UidRecord.ChangeItem pendingChange;
22269        if (uidRec == null || uidRec.pendingChange == null) {
22270            if (mPendingUidChanges.size() == 0) {
22271                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22272                        "*** Enqueueing dispatch uid changed!");
22273                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22274            }
22275            final int NA = mAvailUidChanges.size();
22276            if (NA > 0) {
22277                pendingChange = mAvailUidChanges.remove(NA-1);
22278                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22279                        "Retrieving available item: " + pendingChange);
22280            } else {
22281                pendingChange = new UidRecord.ChangeItem();
22282                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22283                        "Allocating new item: " + pendingChange);
22284            }
22285            if (uidRec != null) {
22286                uidRec.pendingChange = pendingChange;
22287                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22288                    // If this uid is going away, and we haven't yet reported it is gone,
22289                    // then do so now.
22290                    change |= UidRecord.CHANGE_IDLE;
22291                }
22292            } else if (uid < 0) {
22293                throw new IllegalArgumentException("No UidRecord or uid");
22294            }
22295            pendingChange.uidRecord = uidRec;
22296            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22297            mPendingUidChanges.add(pendingChange);
22298        } else {
22299            pendingChange = uidRec.pendingChange;
22300            // If there is no change in idle or active state, then keep whatever was pending.
22301            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22302                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22303                        | UidRecord.CHANGE_ACTIVE));
22304            }
22305            // If there is no change in cached or uncached state, then keep whatever was pending.
22306            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22307                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22308                        | UidRecord.CHANGE_UNCACHED));
22309            }
22310            // If this is a report of the UID being gone, then we shouldn't keep any previous
22311            // report of it being active or cached.  (That is, a gone uid is never active,
22312            // and never cached.)
22313            if ((change & UidRecord.CHANGE_GONE) != 0) {
22314                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22315                if (!uidRec.idle) {
22316                    // If this uid is going away, and we haven't yet reported it is gone,
22317                    // then do so now.
22318                    change |= UidRecord.CHANGE_IDLE;
22319                }
22320            }
22321        }
22322        pendingChange.change = change;
22323        pendingChange.processState = uidRec != null
22324                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22325        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22326        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22327        if (uidRec != null) {
22328            uidRec.lastReportedChange = change;
22329            uidRec.updateLastDispatchedProcStateSeq(change);
22330        }
22331
22332        // Directly update the power manager, since we sit on top of it and it is critical
22333        // it be kept in sync (so wake locks will be held as soon as appropriate).
22334        if (mLocalPowerManager != null) {
22335            // TO DO: dispatch cached/uncached changes here, so we don't need to report
22336            // all proc state changes.
22337            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22338                mLocalPowerManager.uidActive(pendingChange.uid);
22339            }
22340            if ((change & UidRecord.CHANGE_IDLE) != 0) {
22341                mLocalPowerManager.uidIdle(pendingChange.uid);
22342            }
22343            if ((change & UidRecord.CHANGE_GONE) != 0) {
22344                mLocalPowerManager.uidGone(pendingChange.uid);
22345            } else {
22346                mLocalPowerManager.updateUidProcState(pendingChange.uid,
22347                        pendingChange.processState);
22348            }
22349        }
22350    }
22351
22352    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22353            String authority) {
22354        if (app == null) return;
22355        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22356            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22357            if (userState == null) return;
22358            final long now = SystemClock.elapsedRealtime();
22359            Long lastReported = userState.mProviderLastReportedFg.get(authority);
22360            if (lastReported == null || lastReported < now - 60 * 1000L) {
22361                if (mSystemReady) {
22362                    // Cannot touch the user stats if not system ready
22363                    mUsageStatsService.reportContentProviderUsage(
22364                            authority, providerPkgName, app.userId);
22365                }
22366                userState.mProviderLastReportedFg.put(authority, now);
22367            }
22368        }
22369    }
22370
22371    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22372        if (DEBUG_USAGE_STATS) {
22373            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22374                    + "] state changes: old = " + app.setProcState + ", new = "
22375                    + app.curProcState);
22376        }
22377        if (mUsageStatsService == null) {
22378            return;
22379        }
22380        boolean isInteraction;
22381        // To avoid some abuse patterns, we are going to be careful about what we consider
22382        // to be an app interaction.  Being the top activity doesn't count while the display
22383        // is sleeping, nor do short foreground services.
22384        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22385            isInteraction = true;
22386            app.fgInteractionTime = 0;
22387        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22388            if (app.fgInteractionTime == 0) {
22389                app.fgInteractionTime = nowElapsed;
22390                isInteraction = false;
22391            } else {
22392                isInteraction = nowElapsed > app.fgInteractionTime
22393                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22394            }
22395        } else {
22396            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22397            app.fgInteractionTime = 0;
22398        }
22399        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22400                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22401            app.interactionEventTime = nowElapsed;
22402            String[] packages = app.getPackageList();
22403            if (packages != null) {
22404                for (int i = 0; i < packages.length; i++) {
22405                    mUsageStatsService.reportEvent(packages[i], app.userId,
22406                            UsageEvents.Event.SYSTEM_INTERACTION);
22407                }
22408            }
22409        }
22410        app.reportedInteraction = isInteraction;
22411        if (!isInteraction) {
22412            app.interactionEventTime = 0;
22413        }
22414    }
22415
22416    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22417        if (proc.thread != null) {
22418            if (proc.baseProcessTracker != null) {
22419                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22420            }
22421        }
22422    }
22423
22424    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22425            ProcessRecord TOP_APP, boolean doingAll, long now) {
22426        if (app.thread == null) {
22427            return false;
22428        }
22429
22430        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22431
22432        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22433    }
22434
22435    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22436            boolean oomAdj) {
22437        if (isForeground != proc.foregroundServices) {
22438            proc.foregroundServices = isForeground;
22439            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22440                    proc.info.uid);
22441            if (isForeground) {
22442                if (curProcs == null) {
22443                    curProcs = new ArrayList<ProcessRecord>();
22444                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22445                }
22446                if (!curProcs.contains(proc)) {
22447                    curProcs.add(proc);
22448                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22449                            proc.info.packageName, proc.info.uid);
22450                }
22451            } else {
22452                if (curProcs != null) {
22453                    if (curProcs.remove(proc)) {
22454                        mBatteryStatsService.noteEvent(
22455                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22456                                proc.info.packageName, proc.info.uid);
22457                        if (curProcs.size() <= 0) {
22458                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22459                        }
22460                    }
22461                }
22462            }
22463            if (oomAdj) {
22464                updateOomAdjLocked();
22465            }
22466        }
22467    }
22468
22469    private final ActivityRecord resumedAppLocked() {
22470        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22471        String pkg;
22472        int uid;
22473        if (act != null) {
22474            pkg = act.packageName;
22475            uid = act.info.applicationInfo.uid;
22476        } else {
22477            pkg = null;
22478            uid = -1;
22479        }
22480        // Has the UID or resumed package name changed?
22481        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22482                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22483            if (mCurResumedPackage != null) {
22484                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22485                        mCurResumedPackage, mCurResumedUid);
22486            }
22487            mCurResumedPackage = pkg;
22488            mCurResumedUid = uid;
22489            if (mCurResumedPackage != null) {
22490                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22491                        mCurResumedPackage, mCurResumedUid);
22492            }
22493        }
22494        return act;
22495    }
22496
22497    /**
22498     * Update OomAdj for a specific process.
22499     * @param app The process to update
22500     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22501     *                  if necessary, or skip.
22502     * @return whether updateOomAdjLocked(app) was successful.
22503     */
22504    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22505        final ActivityRecord TOP_ACT = resumedAppLocked();
22506        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22507        final boolean wasCached = app.cached;
22508
22509        mAdjSeq++;
22510
22511        // This is the desired cached adjusment we want to tell it to use.
22512        // If our app is currently cached, we know it, and that is it.  Otherwise,
22513        // we don't know it yet, and it needs to now be cached we will then
22514        // need to do a complete oom adj.
22515        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22516                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22517        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22518                SystemClock.uptimeMillis());
22519        if (oomAdjAll
22520                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22521            // Changed to/from cached state, so apps after it in the LRU
22522            // list may also be changed.
22523            updateOomAdjLocked();
22524        }
22525        return success;
22526    }
22527
22528    final void updateOomAdjLocked() {
22529        final ActivityRecord TOP_ACT = resumedAppLocked();
22530        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22531        final long now = SystemClock.uptimeMillis();
22532        final long nowElapsed = SystemClock.elapsedRealtime();
22533        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22534        final int N = mLruProcesses.size();
22535
22536        if (false) {
22537            RuntimeException e = new RuntimeException();
22538            e.fillInStackTrace();
22539            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22540        }
22541
22542        // Reset state in all uid records.
22543        for (int i=mActiveUids.size()-1; i>=0; i--) {
22544            final UidRecord uidRec = mActiveUids.valueAt(i);
22545            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22546                    "Starting update of " + uidRec);
22547            uidRec.reset();
22548        }
22549
22550        mStackSupervisor.rankTaskLayersIfNeeded();
22551
22552        mAdjSeq++;
22553        mNewNumServiceProcs = 0;
22554        mNewNumAServiceProcs = 0;
22555
22556        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22557        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22558
22559        // Let's determine how many processes we have running vs.
22560        // how many slots we have for background processes; we may want
22561        // to put multiple processes in a slot of there are enough of
22562        // them.
22563        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22564                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22565        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22566        if (numEmptyProcs > cachedProcessLimit) {
22567            // If there are more empty processes than our limit on cached
22568            // processes, then use the cached process limit for the factor.
22569            // This ensures that the really old empty processes get pushed
22570            // down to the bottom, so if we are running low on memory we will
22571            // have a better chance at keeping around more cached processes
22572            // instead of a gazillion empty processes.
22573            numEmptyProcs = cachedProcessLimit;
22574        }
22575        int emptyFactor = numEmptyProcs/numSlots;
22576        if (emptyFactor < 1) emptyFactor = 1;
22577        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22578        if (cachedFactor < 1) cachedFactor = 1;
22579        int stepCached = 0;
22580        int stepEmpty = 0;
22581        int numCached = 0;
22582        int numEmpty = 0;
22583        int numTrimming = 0;
22584
22585        mNumNonCachedProcs = 0;
22586        mNumCachedHiddenProcs = 0;
22587
22588        // First update the OOM adjustment for each of the
22589        // application processes based on their current state.
22590        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22591        int nextCachedAdj = curCachedAdj+1;
22592        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22593        int nextEmptyAdj = curEmptyAdj+2;
22594        for (int i=N-1; i>=0; i--) {
22595            ProcessRecord app = mLruProcesses.get(i);
22596            if (!app.killedByAm && app.thread != null) {
22597                app.procStateChanged = false;
22598                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22599
22600                // If we haven't yet assigned the final cached adj
22601                // to the process, do that now.
22602                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22603                    switch (app.curProcState) {
22604                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22605                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22606                            // This process is a cached process holding activities...
22607                            // assign it the next cached value for that type, and then
22608                            // step that cached level.
22609                            app.curRawAdj = curCachedAdj;
22610                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22611                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22612                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22613                                    + ")");
22614                            if (curCachedAdj != nextCachedAdj) {
22615                                stepCached++;
22616                                if (stepCached >= cachedFactor) {
22617                                    stepCached = 0;
22618                                    curCachedAdj = nextCachedAdj;
22619                                    nextCachedAdj += 2;
22620                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22621                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22622                                    }
22623                                }
22624                            }
22625                            break;
22626                        default:
22627                            // For everything else, assign next empty cached process
22628                            // level and bump that up.  Note that this means that
22629                            // long-running services that have dropped down to the
22630                            // cached level will be treated as empty (since their process
22631                            // state is still as a service), which is what we want.
22632                            app.curRawAdj = curEmptyAdj;
22633                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22634                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22635                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22636                                    + ")");
22637                            if (curEmptyAdj != nextEmptyAdj) {
22638                                stepEmpty++;
22639                                if (stepEmpty >= emptyFactor) {
22640                                    stepEmpty = 0;
22641                                    curEmptyAdj = nextEmptyAdj;
22642                                    nextEmptyAdj += 2;
22643                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22644                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22645                                    }
22646                                }
22647                            }
22648                            break;
22649                    }
22650                }
22651
22652                applyOomAdjLocked(app, true, now, nowElapsed);
22653
22654                // Count the number of process types.
22655                switch (app.curProcState) {
22656                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22657                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22658                        mNumCachedHiddenProcs++;
22659                        numCached++;
22660                        if (numCached > cachedProcessLimit) {
22661                            app.kill("cached #" + numCached, true);
22662                        }
22663                        break;
22664                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22665                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22666                                && app.lastActivityTime < oldTime) {
22667                            app.kill("empty for "
22668                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22669                                    / 1000) + "s", true);
22670                        } else {
22671                            numEmpty++;
22672                            if (numEmpty > emptyProcessLimit) {
22673                                app.kill("empty #" + numEmpty, true);
22674                            }
22675                        }
22676                        break;
22677                    default:
22678                        mNumNonCachedProcs++;
22679                        break;
22680                }
22681
22682                if (app.isolated && app.services.size() <= 0) {
22683                    // If this is an isolated process, and there are no
22684                    // services running in it, then the process is no longer
22685                    // needed.  We agressively kill these because we can by
22686                    // definition not re-use the same process again, and it is
22687                    // good to avoid having whatever code was running in them
22688                    // left sitting around after no longer needed.
22689                    app.kill("isolated not needed", true);
22690                } else {
22691                    // Keeping this process, update its uid.
22692                    final UidRecord uidRec = app.uidRecord;
22693                    if (uidRec != null) {
22694                        uidRec.ephemeral = app.info.isInstantApp();
22695                        if (uidRec.curProcState > app.curProcState) {
22696                            uidRec.curProcState = app.curProcState;
22697                        }
22698                        if (app.foregroundServices) {
22699                            uidRec.foregroundServices = true;
22700                        }
22701                    }
22702                }
22703
22704                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22705                        && !app.killedByAm) {
22706                    numTrimming++;
22707                }
22708            }
22709        }
22710
22711        incrementProcStateSeqAndNotifyAppsLocked();
22712
22713        mNumServiceProcs = mNewNumServiceProcs;
22714
22715        // Now determine the memory trimming level of background processes.
22716        // Unfortunately we need to start at the back of the list to do this
22717        // properly.  We only do this if the number of background apps we
22718        // are managing to keep around is less than half the maximum we desire;
22719        // if we are keeping a good number around, we'll let them use whatever
22720        // memory they want.
22721        final int numCachedAndEmpty = numCached + numEmpty;
22722        int memFactor;
22723        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22724                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22725            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22726                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22727            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22728                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22729            } else {
22730                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22731            }
22732        } else {
22733            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22734        }
22735        // We always allow the memory level to go up (better).  We only allow it to go
22736        // down if we are in a state where that is allowed, *and* the total number of processes
22737        // has gone down since last time.
22738        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22739                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22740                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22741        if (memFactor > mLastMemoryLevel) {
22742            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22743                memFactor = mLastMemoryLevel;
22744                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22745            }
22746        }
22747        if (memFactor != mLastMemoryLevel) {
22748            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22749        }
22750        mLastMemoryLevel = memFactor;
22751        mLastNumProcesses = mLruProcesses.size();
22752        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22753        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22754        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22755            if (mLowRamStartTime == 0) {
22756                mLowRamStartTime = now;
22757            }
22758            int step = 0;
22759            int fgTrimLevel;
22760            switch (memFactor) {
22761                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22762                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22763                    break;
22764                case ProcessStats.ADJ_MEM_FACTOR_LOW:
22765                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22766                    break;
22767                default:
22768                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22769                    break;
22770            }
22771            int factor = numTrimming/3;
22772            int minFactor = 2;
22773            if (mHomeProcess != null) minFactor++;
22774            if (mPreviousProcess != null) minFactor++;
22775            if (factor < minFactor) factor = minFactor;
22776            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22777            for (int i=N-1; i>=0; i--) {
22778                ProcessRecord app = mLruProcesses.get(i);
22779                if (allChanged || app.procStateChanged) {
22780                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22781                    app.procStateChanged = false;
22782                }
22783                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22784                        && !app.killedByAm) {
22785                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
22786                        try {
22787                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22788                                    "Trimming memory of " + app.processName + " to " + curLevel);
22789                            app.thread.scheduleTrimMemory(curLevel);
22790                        } catch (RemoteException e) {
22791                        }
22792                        if (false) {
22793                            // For now we won't do this; our memory trimming seems
22794                            // to be good enough at this point that destroying
22795                            // activities causes more harm than good.
22796                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22797                                    && app != mHomeProcess && app != mPreviousProcess) {
22798                                // Need to do this on its own message because the stack may not
22799                                // be in a consistent state at this point.
22800                                // For these apps we will also finish their activities
22801                                // to help them free memory.
22802                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22803                            }
22804                        }
22805                    }
22806                    app.trimMemoryLevel = curLevel;
22807                    step++;
22808                    if (step >= factor) {
22809                        step = 0;
22810                        switch (curLevel) {
22811                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22812                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22813                                break;
22814                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22815                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22816                                break;
22817                        }
22818                    }
22819                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22820                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22821                            && app.thread != null) {
22822                        try {
22823                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22824                                    "Trimming memory of heavy-weight " + app.processName
22825                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22826                            app.thread.scheduleTrimMemory(
22827                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22828                        } catch (RemoteException e) {
22829                        }
22830                    }
22831                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22832                } else {
22833                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22834                            || app.systemNoUi) && app.pendingUiClean) {
22835                        // If this application is now in the background and it
22836                        // had done UI, then give it the special trim level to
22837                        // have it free UI resources.
22838                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22839                        if (app.trimMemoryLevel < level && app.thread != null) {
22840                            try {
22841                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22842                                        "Trimming memory of bg-ui " + app.processName
22843                                        + " to " + level);
22844                                app.thread.scheduleTrimMemory(level);
22845                            } catch (RemoteException e) {
22846                            }
22847                        }
22848                        app.pendingUiClean = false;
22849                    }
22850                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22851                        try {
22852                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22853                                    "Trimming memory of fg " + app.processName
22854                                    + " to " + fgTrimLevel);
22855                            app.thread.scheduleTrimMemory(fgTrimLevel);
22856                        } catch (RemoteException e) {
22857                        }
22858                    }
22859                    app.trimMemoryLevel = fgTrimLevel;
22860                }
22861            }
22862        } else {
22863            if (mLowRamStartTime != 0) {
22864                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22865                mLowRamStartTime = 0;
22866            }
22867            for (int i=N-1; i>=0; i--) {
22868                ProcessRecord app = mLruProcesses.get(i);
22869                if (allChanged || app.procStateChanged) {
22870                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22871                    app.procStateChanged = false;
22872                }
22873                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22874                        || app.systemNoUi) && app.pendingUiClean) {
22875                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22876                            && app.thread != null) {
22877                        try {
22878                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22879                                    "Trimming memory of ui hidden " + app.processName
22880                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22881                            app.thread.scheduleTrimMemory(
22882                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22883                        } catch (RemoteException e) {
22884                        }
22885                    }
22886                    app.pendingUiClean = false;
22887                }
22888                app.trimMemoryLevel = 0;
22889            }
22890        }
22891
22892        if (mAlwaysFinishActivities) {
22893            // Need to do this on its own message because the stack may not
22894            // be in a consistent state at this point.
22895            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22896        }
22897
22898        if (allChanged) {
22899            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22900        }
22901
22902        ArrayList<UidRecord> becameIdle = null;
22903
22904        // Update from any uid changes.
22905        if (mLocalPowerManager != null) {
22906            mLocalPowerManager.startUidChanges();
22907        }
22908        for (int i=mActiveUids.size()-1; i>=0; i--) {
22909            final UidRecord uidRec = mActiveUids.valueAt(i);
22910            int uidChange = UidRecord.CHANGE_PROCSTATE;
22911            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22912                    && (uidRec.setProcState != uidRec.curProcState
22913                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
22914                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22915                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22916                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22917                        + " to " + uidRec.curWhitelist);
22918                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22919                        && !uidRec.curWhitelist) {
22920                    // UID is now in the background (and not on the temp whitelist).  Was it
22921                    // previously in the foreground (or on the temp whitelist)?
22922                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22923                            || uidRec.setWhitelist) {
22924                        uidRec.lastBackgroundTime = nowElapsed;
22925                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22926                            // Note: the background settle time is in elapsed realtime, while
22927                            // the handler time base is uptime.  All this means is that we may
22928                            // stop background uids later than we had intended, but that only
22929                            // happens because the device was sleeping so we are okay anyway.
22930                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22931                                    mConstants.BACKGROUND_SETTLE_TIME);
22932                        }
22933                    }
22934                    if (uidRec.idle && !uidRec.setIdle) {
22935                        uidChange = UidRecord.CHANGE_IDLE;
22936                        if (becameIdle == null) {
22937                            becameIdle = new ArrayList<>();
22938                        }
22939                        becameIdle.add(uidRec);
22940                    }
22941                } else {
22942                    if (uidRec.idle) {
22943                        uidChange = UidRecord.CHANGE_ACTIVE;
22944                        EventLogTags.writeAmUidActive(uidRec.uid);
22945                        uidRec.idle = false;
22946                    }
22947                    uidRec.lastBackgroundTime = 0;
22948                }
22949                final boolean wasCached = uidRec.setProcState
22950                        > ActivityManager.PROCESS_STATE_RECEIVER;
22951                final boolean isCached = uidRec.curProcState
22952                        > ActivityManager.PROCESS_STATE_RECEIVER;
22953                if (wasCached != isCached ||
22954                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22955                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22956                }
22957                uidRec.setProcState = uidRec.curProcState;
22958                uidRec.setWhitelist = uidRec.curWhitelist;
22959                uidRec.setIdle = uidRec.idle;
22960                enqueueUidChangeLocked(uidRec, -1, uidChange);
22961                noteUidProcessState(uidRec.uid, uidRec.curProcState);
22962                if (uidRec.foregroundServices) {
22963                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
22964                }
22965            }
22966        }
22967        if (mLocalPowerManager != null) {
22968            mLocalPowerManager.finishUidChanges();
22969        }
22970
22971        if (becameIdle != null) {
22972            // If we have any new uids that became idle this time, we need to make sure
22973            // they aren't left with running services.
22974            for (int i = becameIdle.size() - 1; i >= 0; i--) {
22975                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22976            }
22977        }
22978
22979        if (mProcessStats.shouldWriteNowLocked(now)) {
22980            mHandler.post(new Runnable() {
22981                @Override public void run() {
22982                    synchronized (ActivityManagerService.this) {
22983                        mProcessStats.writeStateAsyncLocked();
22984                    }
22985                }
22986            });
22987        }
22988
22989        if (DEBUG_OOM_ADJ) {
22990            final long duration = SystemClock.uptimeMillis() - now;
22991            if (false) {
22992                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22993                        new RuntimeException("here").fillInStackTrace());
22994            } else {
22995                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22996            }
22997        }
22998    }
22999
23000    @Override
23001    public void makePackageIdle(String packageName, int userId) {
23002        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23003                != PackageManager.PERMISSION_GRANTED) {
23004            String msg = "Permission Denial: makePackageIdle() from pid="
23005                    + Binder.getCallingPid()
23006                    + ", uid=" + Binder.getCallingUid()
23007                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23008            Slog.w(TAG, msg);
23009            throw new SecurityException(msg);
23010        }
23011        final int callingPid = Binder.getCallingPid();
23012        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23013                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23014        long callingId = Binder.clearCallingIdentity();
23015        synchronized(this) {
23016            try {
23017                IPackageManager pm = AppGlobals.getPackageManager();
23018                int pkgUid = -1;
23019                try {
23020                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23021                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23022                } catch (RemoteException e) {
23023                }
23024                if (pkgUid == -1) {
23025                    throw new IllegalArgumentException("Unknown package name " + packageName);
23026                }
23027
23028                if (mLocalPowerManager != null) {
23029                    mLocalPowerManager.startUidChanges();
23030                }
23031                final int appId = UserHandle.getAppId(pkgUid);
23032                final int N = mActiveUids.size();
23033                for (int i=N-1; i>=0; i--) {
23034                    final UidRecord uidRec = mActiveUids.valueAt(i);
23035                    final long bgTime = uidRec.lastBackgroundTime;
23036                    if (bgTime > 0 && !uidRec.idle) {
23037                        if (UserHandle.getAppId(uidRec.uid) == appId) {
23038                            if (userId == UserHandle.USER_ALL ||
23039                                    userId == UserHandle.getUserId(uidRec.uid)) {
23040                                EventLogTags.writeAmUidIdle(uidRec.uid);
23041                                uidRec.idle = true;
23042                                uidRec.setIdle = true;
23043                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23044                                        + " from package " + packageName + " user " + userId);
23045                                doStopUidLocked(uidRec.uid, uidRec);
23046                            }
23047                        }
23048                    }
23049                }
23050            } finally {
23051                if (mLocalPowerManager != null) {
23052                    mLocalPowerManager.finishUidChanges();
23053                }
23054                Binder.restoreCallingIdentity(callingId);
23055            }
23056        }
23057    }
23058
23059    final void idleUids() {
23060        synchronized (this) {
23061            final int N = mActiveUids.size();
23062            if (N <= 0) {
23063                return;
23064            }
23065            final long nowElapsed = SystemClock.elapsedRealtime();
23066            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23067            long nextTime = 0;
23068            if (mLocalPowerManager != null) {
23069                mLocalPowerManager.startUidChanges();
23070            }
23071            for (int i=N-1; i>=0; i--) {
23072                final UidRecord uidRec = mActiveUids.valueAt(i);
23073                final long bgTime = uidRec.lastBackgroundTime;
23074                if (bgTime > 0 && !uidRec.idle) {
23075                    if (bgTime <= maxBgTime) {
23076                        EventLogTags.writeAmUidIdle(uidRec.uid);
23077                        uidRec.idle = true;
23078                        uidRec.setIdle = true;
23079                        doStopUidLocked(uidRec.uid, uidRec);
23080                    } else {
23081                        if (nextTime == 0 || nextTime > bgTime) {
23082                            nextTime = bgTime;
23083                        }
23084                    }
23085                }
23086            }
23087            if (mLocalPowerManager != null) {
23088                mLocalPowerManager.finishUidChanges();
23089            }
23090            if (nextTime > 0) {
23091                mHandler.removeMessages(IDLE_UIDS_MSG);
23092                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23093                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23094            }
23095        }
23096    }
23097
23098    /**
23099     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23100     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23101     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23102     */
23103    @VisibleForTesting
23104    @GuardedBy("this")
23105    void incrementProcStateSeqAndNotifyAppsLocked() {
23106        if (mWaitForNetworkTimeoutMs <= 0) {
23107            return;
23108        }
23109        // Used for identifying which uids need to block for network.
23110        ArrayList<Integer> blockingUids = null;
23111        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23112            final UidRecord uidRec = mActiveUids.valueAt(i);
23113            // If the network is not restricted for uid, then nothing to do here.
23114            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23115                continue;
23116            }
23117            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23118                continue;
23119            }
23120            // If process state is not changed, then there's nothing to do.
23121            if (uidRec.setProcState == uidRec.curProcState) {
23122                continue;
23123            }
23124            final int blockState = getBlockStateForUid(uidRec);
23125            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23126            // there's nothing the app needs to do in this scenario.
23127            if (blockState == NETWORK_STATE_NO_CHANGE) {
23128                continue;
23129            }
23130            synchronized (uidRec.networkStateLock) {
23131                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23132                if (blockState == NETWORK_STATE_BLOCK) {
23133                    if (blockingUids == null) {
23134                        blockingUids = new ArrayList<>();
23135                    }
23136                    blockingUids.add(uidRec.uid);
23137                } else {
23138                    if (DEBUG_NETWORK) {
23139                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23140                                + " threads for uid: " + uidRec);
23141                    }
23142                    if (uidRec.waitingForNetwork) {
23143                        uidRec.networkStateLock.notifyAll();
23144                    }
23145                }
23146            }
23147        }
23148
23149        // There are no uids that need to block, so nothing more to do.
23150        if (blockingUids == null) {
23151            return;
23152        }
23153
23154        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23155            final ProcessRecord app = mLruProcesses.get(i);
23156            if (!blockingUids.contains(app.uid)) {
23157                continue;
23158            }
23159            if (!app.killedByAm && app.thread != null) {
23160                final UidRecord uidRec = mActiveUids.get(app.uid);
23161                try {
23162                    if (DEBUG_NETWORK) {
23163                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23164                                + uidRec);
23165                    }
23166                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23167                } catch (RemoteException ignored) {
23168                }
23169            }
23170        }
23171    }
23172
23173    /**
23174     * Checks if the uid is coming from background to foreground or vice versa and returns
23175     * appropriate block state based on this.
23176     *
23177     * @return blockState based on whether the uid is coming from background to foreground or
23178     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23179     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23180     *         {@link #NETWORK_STATE_NO_CHANGE}.
23181     */
23182    @VisibleForTesting
23183    int getBlockStateForUid(UidRecord uidRec) {
23184        // Denotes whether uid's process state is currently allowed network access.
23185        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23186                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23187        // Denotes whether uid's process state was previously allowed network access.
23188        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23189                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23190
23191        // When the uid is coming to foreground, AMS should inform the app thread that it should
23192        // block for the network rules to get updated before launching an activity.
23193        if (!wasAllowed && isAllowed) {
23194            return NETWORK_STATE_BLOCK;
23195        }
23196        // When the uid is going to background, AMS should inform the app thread that if an
23197        // activity launch is blocked for the network rules to get updated, it should be unblocked.
23198        if (wasAllowed && !isAllowed) {
23199            return NETWORK_STATE_UNBLOCK;
23200        }
23201        return NETWORK_STATE_NO_CHANGE;
23202    }
23203
23204    final void runInBackgroundDisabled(int uid) {
23205        synchronized (this) {
23206            UidRecord uidRec = mActiveUids.get(uid);
23207            if (uidRec != null) {
23208                // This uid is actually running...  should it be considered background now?
23209                if (uidRec.idle) {
23210                    doStopUidLocked(uidRec.uid, uidRec);
23211                }
23212            } else {
23213                // This uid isn't actually running...  still send a report about it being "stopped".
23214                doStopUidLocked(uid, null);
23215            }
23216        }
23217    }
23218
23219    final void doStopUidLocked(int uid, final UidRecord uidRec) {
23220        mServices.stopInBackgroundLocked(uid);
23221        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23222    }
23223
23224    /**
23225     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23226     */
23227    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23228            long duration, String tag) {
23229        if (DEBUG_WHITELISTS) {
23230            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23231                    + targetUid + ", " + duration + ")");
23232        }
23233
23234        synchronized (mPidsSelfLocked) {
23235            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23236            if (pr == null) {
23237                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23238                        + callerPid);
23239                return;
23240            }
23241            if (!pr.whitelistManager) {
23242                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23243                        != PackageManager.PERMISSION_GRANTED) {
23244                    if (DEBUG_WHITELISTS) {
23245                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23246                                + ": pid " + callerPid + " is not allowed");
23247                    }
23248                    return;
23249                }
23250            }
23251        }
23252
23253        tempWhitelistUidLocked(targetUid, duration, tag);
23254    }
23255
23256    /**
23257     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23258     */
23259    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23260        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23261        setUidTempWhitelistStateLocked(targetUid, true);
23262        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23263    }
23264
23265    void pushTempWhitelist() {
23266        final int N;
23267        final PendingTempWhitelist[] list;
23268
23269        // First copy out the pending changes...  we need to leave them in the map for now,
23270        // in case someone needs to check what is coming up while we don't have the lock held.
23271        synchronized(this) {
23272            N = mPendingTempWhitelist.size();
23273            list = new PendingTempWhitelist[N];
23274            for (int i = 0; i < N; i++) {
23275                list[i] = mPendingTempWhitelist.valueAt(i);
23276            }
23277        }
23278
23279        // Now safely dispatch changes to device idle controller.
23280        for (int i = 0; i < N; i++) {
23281            PendingTempWhitelist ptw = list[i];
23282            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23283                    ptw.duration, true, ptw.tag);
23284        }
23285
23286        // And now we can safely remove them from the map.
23287        synchronized(this) {
23288            for (int i = 0; i < N; i++) {
23289                PendingTempWhitelist ptw = list[i];
23290                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23291                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23292                    mPendingTempWhitelist.removeAt(index);
23293                }
23294            }
23295        }
23296    }
23297
23298    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23299        boolean changed = false;
23300        for (int i=mActiveUids.size()-1; i>=0; i--) {
23301            final UidRecord uidRec = mActiveUids.valueAt(i);
23302            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23303                uidRec.curWhitelist = onWhitelist;
23304                changed = true;
23305            }
23306        }
23307        if (changed) {
23308            updateOomAdjLocked();
23309        }
23310    }
23311
23312    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23313        boolean changed = false;
23314        final UidRecord uidRec = mActiveUids.get(uid);
23315        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23316            uidRec.curWhitelist = onWhitelist;
23317            updateOomAdjLocked();
23318        }
23319    }
23320
23321    final void trimApplications() {
23322        synchronized (this) {
23323            int i;
23324
23325            // First remove any unused application processes whose package
23326            // has been removed.
23327            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23328                final ProcessRecord app = mRemovedProcesses.get(i);
23329                if (app.activities.size() == 0
23330                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
23331                    Slog.i(
23332                        TAG, "Exiting empty application process "
23333                        + app.toShortString() + " ("
23334                        + (app.thread != null ? app.thread.asBinder() : null)
23335                        + ")\n");
23336                    if (app.pid > 0 && app.pid != MY_PID) {
23337                        app.kill("empty", false);
23338                    } else {
23339                        try {
23340                            app.thread.scheduleExit();
23341                        } catch (Exception e) {
23342                            // Ignore exceptions.
23343                        }
23344                    }
23345                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23346                    mRemovedProcesses.remove(i);
23347
23348                    if (app.persistent) {
23349                        addAppLocked(app.info, null, false, null /* ABI override */);
23350                    }
23351                }
23352            }
23353
23354            // Now update the oom adj for all processes.
23355            updateOomAdjLocked();
23356        }
23357    }
23358
23359    /** This method sends the specified signal to each of the persistent apps */
23360    public void signalPersistentProcesses(int sig) throws RemoteException {
23361        if (sig != SIGNAL_USR1) {
23362            throw new SecurityException("Only SIGNAL_USR1 is allowed");
23363        }
23364
23365        synchronized (this) {
23366            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23367                    != PackageManager.PERMISSION_GRANTED) {
23368                throw new SecurityException("Requires permission "
23369                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23370            }
23371
23372            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23373                ProcessRecord r = mLruProcesses.get(i);
23374                if (r.thread != null && r.persistent) {
23375                    sendSignal(r.pid, sig);
23376                }
23377            }
23378        }
23379    }
23380
23381    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23382        if (proc == null || proc == mProfileProc) {
23383            proc = mProfileProc;
23384            profileType = mProfileType;
23385            clearProfilerLocked();
23386        }
23387        if (proc == null) {
23388            return;
23389        }
23390        try {
23391            proc.thread.profilerControl(false, null, profileType);
23392        } catch (RemoteException e) {
23393            throw new IllegalStateException("Process disappeared");
23394        }
23395    }
23396
23397    private void clearProfilerLocked() {
23398        if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23399            try {
23400                mProfilerInfo.profileFd.close();
23401            } catch (IOException e) {
23402            }
23403        }
23404        mProfileApp = null;
23405        mProfileProc = null;
23406        mProfilerInfo = null;
23407    }
23408
23409    public boolean profileControl(String process, int userId, boolean start,
23410            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23411
23412        try {
23413            synchronized (this) {
23414                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23415                // its own permission.
23416                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23417                        != PackageManager.PERMISSION_GRANTED) {
23418                    throw new SecurityException("Requires permission "
23419                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23420                }
23421
23422                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23423                    throw new IllegalArgumentException("null profile info or fd");
23424                }
23425
23426                ProcessRecord proc = null;
23427                if (process != null) {
23428                    proc = findProcessLocked(process, userId, "profileControl");
23429                }
23430
23431                if (start && (proc == null || proc.thread == null)) {
23432                    throw new IllegalArgumentException("Unknown process: " + process);
23433                }
23434
23435                if (start) {
23436                    stopProfilerLocked(null, 0);
23437                    setProfileApp(proc.info, proc.processName, profilerInfo);
23438                    mProfileProc = proc;
23439                    mProfileType = profileType;
23440                    ParcelFileDescriptor fd = profilerInfo.profileFd;
23441                    try {
23442                        fd = fd.dup();
23443                    } catch (IOException e) {
23444                        fd = null;
23445                    }
23446                    profilerInfo.profileFd = fd;
23447                    proc.thread.profilerControl(start, profilerInfo, profileType);
23448                    fd = null;
23449                    try {
23450                        mProfilerInfo.profileFd.close();
23451                    } catch (IOException e) {
23452                    }
23453                    mProfilerInfo.profileFd = null;
23454                } else {
23455                    stopProfilerLocked(proc, profileType);
23456                    if (profilerInfo != null && profilerInfo.profileFd != null) {
23457                        try {
23458                            profilerInfo.profileFd.close();
23459                        } catch (IOException e) {
23460                        }
23461                    }
23462                }
23463
23464                return true;
23465            }
23466        } catch (RemoteException e) {
23467            throw new IllegalStateException("Process disappeared");
23468        } finally {
23469            if (profilerInfo != null && profilerInfo.profileFd != null) {
23470                try {
23471                    profilerInfo.profileFd.close();
23472                } catch (IOException e) {
23473                }
23474            }
23475        }
23476    }
23477
23478    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23479        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23480                userId, true, ALLOW_FULL_ONLY, callName, null);
23481        ProcessRecord proc = null;
23482        try {
23483            int pid = Integer.parseInt(process);
23484            synchronized (mPidsSelfLocked) {
23485                proc = mPidsSelfLocked.get(pid);
23486            }
23487        } catch (NumberFormatException e) {
23488        }
23489
23490        if (proc == null) {
23491            ArrayMap<String, SparseArray<ProcessRecord>> all
23492                    = mProcessNames.getMap();
23493            SparseArray<ProcessRecord> procs = all.get(process);
23494            if (procs != null && procs.size() > 0) {
23495                proc = procs.valueAt(0);
23496                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23497                    for (int i=1; i<procs.size(); i++) {
23498                        ProcessRecord thisProc = procs.valueAt(i);
23499                        if (thisProc.userId == userId) {
23500                            proc = thisProc;
23501                            break;
23502                        }
23503                    }
23504                }
23505            }
23506        }
23507
23508        return proc;
23509    }
23510
23511    public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23512            boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23513
23514        try {
23515            synchronized (this) {
23516                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23517                // its own permission (same as profileControl).
23518                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23519                        != PackageManager.PERMISSION_GRANTED) {
23520                    throw new SecurityException("Requires permission "
23521                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23522                }
23523
23524                if (fd == null) {
23525                    throw new IllegalArgumentException("null fd");
23526                }
23527
23528                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23529                if (proc == null || proc.thread == null) {
23530                    throw new IllegalArgumentException("Unknown process: " + process);
23531                }
23532
23533                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23534                if (!isDebuggable) {
23535                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23536                        throw new SecurityException("Process not debuggable: " + proc);
23537                    }
23538                }
23539
23540                proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23541                fd = null;
23542                return true;
23543            }
23544        } catch (RemoteException e) {
23545            throw new IllegalStateException("Process disappeared");
23546        } finally {
23547            if (fd != null) {
23548                try {
23549                    fd.close();
23550                } catch (IOException e) {
23551                }
23552            }
23553        }
23554    }
23555
23556    @Override
23557    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23558            String reportPackage) {
23559        if (processName != null) {
23560            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23561                    "setDumpHeapDebugLimit()");
23562        } else {
23563            synchronized (mPidsSelfLocked) {
23564                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23565                if (proc == null) {
23566                    throw new SecurityException("No process found for calling pid "
23567                            + Binder.getCallingPid());
23568                }
23569                if (!Build.IS_DEBUGGABLE
23570                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23571                    throw new SecurityException("Not running a debuggable build");
23572                }
23573                processName = proc.processName;
23574                uid = proc.uid;
23575                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23576                    throw new SecurityException("Package " + reportPackage + " is not running in "
23577                            + proc);
23578                }
23579            }
23580        }
23581        synchronized (this) {
23582            if (maxMemSize > 0) {
23583                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23584            } else {
23585                if (uid != 0) {
23586                    mMemWatchProcesses.remove(processName, uid);
23587                } else {
23588                    mMemWatchProcesses.getMap().remove(processName);
23589                }
23590            }
23591        }
23592    }
23593
23594    @Override
23595    public void dumpHeapFinished(String path) {
23596        synchronized (this) {
23597            if (Binder.getCallingPid() != mMemWatchDumpPid) {
23598                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23599                        + " does not match last pid " + mMemWatchDumpPid);
23600                return;
23601            }
23602            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23603                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23604                        + " does not match last path " + mMemWatchDumpFile);
23605                return;
23606            }
23607            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23608            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23609
23610            // Forced gc to clean up the remnant hprof fd.
23611            Runtime.getRuntime().gc();
23612        }
23613    }
23614
23615    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23616    public void monitor() {
23617        synchronized (this) { }
23618    }
23619
23620    void onCoreSettingsChange(Bundle settings) {
23621        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23622            ProcessRecord processRecord = mLruProcesses.get(i);
23623            try {
23624                if (processRecord.thread != null) {
23625                    processRecord.thread.setCoreSettings(settings);
23626                }
23627            } catch (RemoteException re) {
23628                /* ignore */
23629            }
23630        }
23631    }
23632
23633    // Multi-user methods
23634
23635    /**
23636     * Start user, if its not already running, but don't bring it to foreground.
23637     */
23638    @Override
23639    public boolean startUserInBackground(final int userId) {
23640        return mUserController.startUser(userId, /* foreground */ false);
23641    }
23642
23643    @Override
23644    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23645        return mUserController.unlockUser(userId, token, secret, listener);
23646    }
23647
23648    @Override
23649    public boolean switchUser(final int targetUserId) {
23650        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23651        int currentUserId;
23652        UserInfo targetUserInfo;
23653        synchronized (this) {
23654            currentUserId = mUserController.getCurrentUserIdLocked();
23655            targetUserInfo = mUserController.getUserInfo(targetUserId);
23656            if (targetUserId == currentUserId) {
23657                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23658                return true;
23659            }
23660            if (targetUserInfo == null) {
23661                Slog.w(TAG, "No user info for user #" + targetUserId);
23662                return false;
23663            }
23664            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23665                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23666                        + " when device is in demo mode");
23667                return false;
23668            }
23669            if (!targetUserInfo.supportsSwitchTo()) {
23670                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23671                return false;
23672            }
23673            if (targetUserInfo.isManagedProfile()) {
23674                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23675                return false;
23676            }
23677            mUserController.setTargetUserIdLocked(targetUserId);
23678        }
23679        if (mUserController.mUserSwitchUiEnabled) {
23680            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23681            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23682            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23683            mUiHandler.sendMessage(mHandler.obtainMessage(
23684                    START_USER_SWITCH_UI_MSG, userNames));
23685        } else {
23686            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23687            mHandler.sendMessage(mHandler.obtainMessage(
23688                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
23689        }
23690        return true;
23691    }
23692
23693    void scheduleStartProfilesLocked() {
23694        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23695            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23696                    DateUtils.SECOND_IN_MILLIS);
23697        }
23698    }
23699
23700    @Override
23701    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23702        return mUserController.stopUser(userId, force, callback);
23703    }
23704
23705    @Override
23706    public UserInfo getCurrentUser() {
23707        return mUserController.getCurrentUser();
23708    }
23709
23710    String getStartedUserState(int userId) {
23711        synchronized (this) {
23712            final UserState userState = mUserController.getStartedUserStateLocked(userId);
23713            return UserState.stateToString(userState.state);
23714        }
23715    }
23716
23717    @Override
23718    public boolean isUserRunning(int userId, int flags) {
23719        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23720                && checkCallingPermission(INTERACT_ACROSS_USERS)
23721                    != PackageManager.PERMISSION_GRANTED) {
23722            String msg = "Permission Denial: isUserRunning() from pid="
23723                    + Binder.getCallingPid()
23724                    + ", uid=" + Binder.getCallingUid()
23725                    + " requires " + INTERACT_ACROSS_USERS;
23726            Slog.w(TAG, msg);
23727            throw new SecurityException(msg);
23728        }
23729        synchronized (this) {
23730            return mUserController.isUserRunningLocked(userId, flags);
23731        }
23732    }
23733
23734    @Override
23735    public int[] getRunningUserIds() {
23736        if (checkCallingPermission(INTERACT_ACROSS_USERS)
23737                != PackageManager.PERMISSION_GRANTED) {
23738            String msg = "Permission Denial: isUserRunning() from pid="
23739                    + Binder.getCallingPid()
23740                    + ", uid=" + Binder.getCallingUid()
23741                    + " requires " + INTERACT_ACROSS_USERS;
23742            Slog.w(TAG, msg);
23743            throw new SecurityException(msg);
23744        }
23745        synchronized (this) {
23746            return mUserController.getStartedUserArrayLocked();
23747        }
23748    }
23749
23750    @Override
23751    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23752        mUserController.registerUserSwitchObserver(observer, name);
23753    }
23754
23755    @Override
23756    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23757        mUserController.unregisterUserSwitchObserver(observer);
23758    }
23759
23760    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23761        if (info == null) return null;
23762        ApplicationInfo newInfo = new ApplicationInfo(info);
23763        newInfo.initForUser(userId);
23764        return newInfo;
23765    }
23766
23767    public boolean isUserStopped(int userId) {
23768        synchronized (this) {
23769            return mUserController.getStartedUserStateLocked(userId) == null;
23770        }
23771    }
23772
23773    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23774        if (aInfo == null
23775                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23776            return aInfo;
23777        }
23778
23779        ActivityInfo info = new ActivityInfo(aInfo);
23780        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23781        return info;
23782    }
23783
23784    private boolean processSanityChecksLocked(ProcessRecord process) {
23785        if (process == null || process.thread == null) {
23786            return false;
23787        }
23788
23789        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23790        if (!isDebuggable) {
23791            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23792                return false;
23793            }
23794        }
23795
23796        return true;
23797    }
23798
23799    public boolean startBinderTracking() throws RemoteException {
23800        synchronized (this) {
23801            mBinderTransactionTrackingEnabled = true;
23802            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23803            // permission (same as profileControl).
23804            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23805                    != PackageManager.PERMISSION_GRANTED) {
23806                throw new SecurityException("Requires permission "
23807                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23808            }
23809
23810            for (int i = 0; i < mLruProcesses.size(); i++) {
23811                ProcessRecord process = mLruProcesses.get(i);
23812                if (!processSanityChecksLocked(process)) {
23813                    continue;
23814                }
23815                try {
23816                    process.thread.startBinderTracking();
23817                } catch (RemoteException e) {
23818                    Log.v(TAG, "Process disappared");
23819                }
23820            }
23821            return true;
23822        }
23823    }
23824
23825    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23826        try {
23827            synchronized (this) {
23828                mBinderTransactionTrackingEnabled = false;
23829                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23830                // permission (same as profileControl).
23831                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23832                        != PackageManager.PERMISSION_GRANTED) {
23833                    throw new SecurityException("Requires permission "
23834                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23835                }
23836
23837                if (fd == null) {
23838                    throw new IllegalArgumentException("null fd");
23839                }
23840
23841                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23842                pw.println("Binder transaction traces for all processes.\n");
23843                for (ProcessRecord process : mLruProcesses) {
23844                    if (!processSanityChecksLocked(process)) {
23845                        continue;
23846                    }
23847
23848                    pw.println("Traces for process: " + process.processName);
23849                    pw.flush();
23850                    try {
23851                        TransferPipe tp = new TransferPipe();
23852                        try {
23853                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23854                            tp.go(fd.getFileDescriptor());
23855                        } finally {
23856                            tp.kill();
23857                        }
23858                    } catch (IOException e) {
23859                        pw.println("Failure while dumping IPC traces from " + process +
23860                                ".  Exception: " + e);
23861                        pw.flush();
23862                    } catch (RemoteException e) {
23863                        pw.println("Got a RemoteException while dumping IPC traces from " +
23864                                process + ".  Exception: " + e);
23865                        pw.flush();
23866                    }
23867                }
23868                fd = null;
23869                return true;
23870            }
23871        } finally {
23872            if (fd != null) {
23873                try {
23874                    fd.close();
23875                } catch (IOException e) {
23876                }
23877            }
23878        }
23879    }
23880
23881    @VisibleForTesting
23882    final class LocalService extends ActivityManagerInternal {
23883        @Override
23884        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23885                int targetUserId) {
23886            synchronized (ActivityManagerService.this) {
23887                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23888                        targetPkg, intent, null, targetUserId);
23889            }
23890        }
23891
23892        @Override
23893        public String checkContentProviderAccess(String authority, int userId) {
23894            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23895        }
23896
23897        @Override
23898        public void onWakefulnessChanged(int wakefulness) {
23899            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23900        }
23901
23902        @Override
23903        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23904                String processName, String abiOverride, int uid, Runnable crashHandler) {
23905            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23906                    processName, abiOverride, uid, crashHandler);
23907        }
23908
23909        @Override
23910        public SleepToken acquireSleepToken(String tag, int displayId) {
23911            Preconditions.checkNotNull(tag);
23912            return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23913        }
23914
23915        @Override
23916        public ComponentName getHomeActivityForUser(int userId) {
23917            synchronized (ActivityManagerService.this) {
23918                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23919                return homeActivity == null ? null : homeActivity.realActivity;
23920            }
23921        }
23922
23923        @Override
23924        public void onUserRemoved(int userId) {
23925            synchronized (ActivityManagerService.this) {
23926                ActivityManagerService.this.onUserStoppedLocked(userId);
23927            }
23928            mBatteryStatsService.onUserRemoved(userId);
23929        }
23930
23931        @Override
23932        public void onLocalVoiceInteractionStarted(IBinder activity,
23933                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23934            synchronized (ActivityManagerService.this) {
23935                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23936                        voiceSession, voiceInteractor);
23937            }
23938        }
23939
23940        @Override
23941        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23942            synchronized (ActivityManagerService.this) {
23943                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23944                        reasons, timestamp);
23945            }
23946        }
23947
23948        @Override
23949        public void notifyAppTransitionFinished() {
23950            synchronized (ActivityManagerService.this) {
23951                mStackSupervisor.notifyAppTransitionDone();
23952            }
23953        }
23954
23955        @Override
23956        public void notifyAppTransitionCancelled() {
23957            synchronized (ActivityManagerService.this) {
23958                mStackSupervisor.notifyAppTransitionDone();
23959            }
23960        }
23961
23962        @Override
23963        public List<IBinder> getTopVisibleActivities() {
23964            synchronized (ActivityManagerService.this) {
23965                return mStackSupervisor.getTopVisibleActivities();
23966            }
23967        }
23968
23969        @Override
23970        public void notifyDockedStackMinimizedChanged(boolean minimized) {
23971            synchronized (ActivityManagerService.this) {
23972                mStackSupervisor.setDockedStackMinimized(minimized);
23973            }
23974        }
23975
23976        @Override
23977        public void killForegroundAppsForUser(int userHandle) {
23978            synchronized (ActivityManagerService.this) {
23979                final ArrayList<ProcessRecord> procs = new ArrayList<>();
23980                final int NP = mProcessNames.getMap().size();
23981                for (int ip = 0; ip < NP; ip++) {
23982                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23983                    final int NA = apps.size();
23984                    for (int ia = 0; ia < NA; ia++) {
23985                        final ProcessRecord app = apps.valueAt(ia);
23986                        if (app.persistent) {
23987                            // We don't kill persistent processes.
23988                            continue;
23989                        }
23990                        if (app.removed) {
23991                            procs.add(app);
23992                        } else if (app.userId == userHandle && app.foregroundActivities) {
23993                            app.removed = true;
23994                            procs.add(app);
23995                        }
23996                    }
23997                }
23998
23999                final int N = procs.size();
24000                for (int i = 0; i < N; i++) {
24001                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
24002                }
24003            }
24004        }
24005
24006        @Override
24007        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24008                long duration) {
24009            if (!(target instanceof PendingIntentRecord)) {
24010                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24011                return;
24012            }
24013            synchronized (ActivityManagerService.this) {
24014                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24015            }
24016        }
24017
24018        @Override
24019        public void setDeviceIdleWhitelist(int[] appids) {
24020            synchronized (ActivityManagerService.this) {
24021                mDeviceIdleWhitelist = appids;
24022            }
24023        }
24024
24025        @Override
24026        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24027            synchronized (ActivityManagerService.this) {
24028                mDeviceIdleTempWhitelist = appids;
24029                setAppIdTempWhitelistStateLocked(changingAppId, adding);
24030            }
24031        }
24032
24033        @Override
24034        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24035                int userId) {
24036            Preconditions.checkNotNull(values, "Configuration must not be null");
24037            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24038            synchronized (ActivityManagerService.this) {
24039                updateConfigurationLocked(values, null, false, true, userId,
24040                        false /* deferResume */);
24041            }
24042        }
24043
24044        @Override
24045        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24046                Bundle bOptions) {
24047            Preconditions.checkNotNull(intents, "intents");
24048            final String[] resolvedTypes = new String[intents.length];
24049            for (int i = 0; i < intents.length; i++) {
24050                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24051            }
24052
24053            // UID of the package on user userId.
24054            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24055            // packageUid may not be initialized.
24056            int packageUid = 0;
24057            try {
24058                packageUid = AppGlobals.getPackageManager().getPackageUid(
24059                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24060            } catch (RemoteException e) {
24061                // Shouldn't happen.
24062            }
24063
24064            synchronized (ActivityManagerService.this) {
24065                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24066                        /*resultTo*/ null, bOptions, userId);
24067            }
24068        }
24069
24070        @Override
24071        public int getUidProcessState(int uid) {
24072            return getUidState(uid);
24073        }
24074
24075        @Override
24076        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24077            synchronized (ActivityManagerService.this) {
24078
24079                // We might change the visibilities here, so prepare an empty app transition which
24080                // might be overridden later if we actually change visibilities.
24081                final boolean wasTransitionSet =
24082                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24083                if (!wasTransitionSet) {
24084                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
24085                            false /* alwaysKeepCurrent */);
24086                }
24087                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24088
24089                // If there was a transition set already we don't want to interfere with it as we
24090                // might be starting it too early.
24091                if (!wasTransitionSet) {
24092                    mWindowManager.executeAppTransition();
24093                }
24094            }
24095            if (callback != null) {
24096                callback.run();
24097            }
24098        }
24099
24100        @Override
24101        public boolean isSystemReady() {
24102            // no need to synchronize(this) just to read & return the value
24103            return mSystemReady;
24104        }
24105
24106        @Override
24107        public void notifyKeyguardTrustedChanged() {
24108            synchronized (ActivityManagerService.this) {
24109                if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24110                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24111                }
24112            }
24113        }
24114
24115        /**
24116         * Sets if the given pid has an overlay UI or not.
24117         *
24118         * @param pid The pid we are setting overlay UI for.
24119         * @param hasOverlayUi True if the process has overlay UI.
24120         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24121         */
24122        @Override
24123        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24124            synchronized (ActivityManagerService.this) {
24125                final ProcessRecord pr;
24126                synchronized (mPidsSelfLocked) {
24127                    pr = mPidsSelfLocked.get(pid);
24128                    if (pr == null) {
24129                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24130                        return;
24131                    }
24132                }
24133                if (pr.hasOverlayUi == hasOverlayUi) {
24134                    return;
24135                }
24136                pr.hasOverlayUi = hasOverlayUi;
24137                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24138                updateOomAdjLocked(pr, true);
24139            }
24140        }
24141
24142        /**
24143         * Called after the network policy rules are updated by
24144         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24145         * and {@param procStateSeq}.
24146         */
24147        @Override
24148        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24149            if (DEBUG_NETWORK) {
24150                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24151                        + uid + " seq: " + procStateSeq);
24152            }
24153            UidRecord record;
24154            synchronized (ActivityManagerService.this) {
24155                record = mActiveUids.get(uid);
24156                if (record == null) {
24157                    if (DEBUG_NETWORK) {
24158                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24159                                + " procStateSeq: " + procStateSeq);
24160                    }
24161                    return;
24162                }
24163            }
24164            synchronized (record.networkStateLock) {
24165                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24166                    if (DEBUG_NETWORK) {
24167                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24168                                + " been handled for uid: " + uid);
24169                    }
24170                    return;
24171                }
24172                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24173                if (record.curProcStateSeq > procStateSeq) {
24174                    if (DEBUG_NETWORK) {
24175                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24176                                + ", curProcstateSeq: " + record.curProcStateSeq
24177                                + ", procStateSeq: " + procStateSeq);
24178                    }
24179                    return;
24180                }
24181                if (record.waitingForNetwork) {
24182                    if (DEBUG_NETWORK) {
24183                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24184                                + ", procStateSeq: " + procStateSeq);
24185                    }
24186                    record.networkStateLock.notifyAll();
24187                }
24188            }
24189        }
24190
24191        /**
24192         * Called after virtual display Id is updated by
24193         * {@link com.android.server.vr.Vr2dDisplay} with a specific
24194         * {@param vrVr2dDisplayId}.
24195         */
24196        @Override
24197        public void setVr2dDisplayId(int vr2dDisplayId) {
24198            if (DEBUG_STACK) {
24199                Slog.d(TAG, "setVr2dDisplayId called for: " +
24200                        vr2dDisplayId);
24201            }
24202            synchronized (ActivityManagerService.this) {
24203                mVr2dDisplayId = vr2dDisplayId;
24204            }
24205        }
24206
24207        @Override
24208        public void saveANRState(String reason) {
24209            synchronized (ActivityManagerService.this) {
24210                final StringWriter sw = new StringWriter();
24211                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24212                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24213                if (reason != null) {
24214                    pw.println("  Reason: " + reason);
24215                }
24216                pw.println();
24217                mActivityStarter.dump(pw, "  ", null);
24218                pw.println();
24219                pw.println("-------------------------------------------------------------------------------");
24220                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24221                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24222                        "" /* header */);
24223                pw.println();
24224                pw.close();
24225
24226                mLastANRState = sw.toString();
24227            }
24228        }
24229
24230        @Override
24231        public void clearSavedANRState() {
24232            synchronized (ActivityManagerService.this) {
24233                mLastANRState = null;
24234            }
24235        }
24236
24237        @Override
24238        public void setFocusedActivity(IBinder token) {
24239            synchronized (ActivityManagerService.this) {
24240                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24241                if (r == null) {
24242                    throw new IllegalArgumentException(
24243                            "setFocusedActivity: No activity record matching token=" + token);
24244                }
24245                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24246                        r, "setFocusedActivity")) {
24247                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
24248                }
24249            }
24250        }
24251
24252        @Override
24253        public boolean hasRunningActivity(int uid, @Nullable String packageName) {
24254            if (packageName == null) return false;
24255
24256            synchronized (ActivityManagerService.this) {
24257                for (int i = 0; i < mLruProcesses.size(); i++) {
24258                    final ProcessRecord processRecord = mLruProcesses.get(i);
24259                    if (processRecord.uid == uid) {
24260                        for (int j = 0; j < processRecord.activities.size(); j++) {
24261                            final ActivityRecord activityRecord = processRecord.activities.get(j);
24262                            if (packageName.equals(activityRecord.packageName)) {
24263                                return true;
24264                            }
24265                        }
24266                    }
24267                }
24268            }
24269            return false;
24270        }
24271    }
24272
24273    /**
24274     * Called by app main thread to wait for the network policy rules to get updated.
24275     *
24276     * @param procStateSeq The sequence number indicating the process state change that the main
24277     *                     thread is interested in.
24278     */
24279    @Override
24280    public void waitForNetworkStateUpdate(long procStateSeq) {
24281        final int callingUid = Binder.getCallingUid();
24282        if (DEBUG_NETWORK) {
24283            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24284        }
24285        UidRecord record;
24286        synchronized (this) {
24287            record = mActiveUids.get(callingUid);
24288            if (record == null) {
24289                return;
24290            }
24291        }
24292        synchronized (record.networkStateLock) {
24293            if (record.lastDispatchedProcStateSeq < procStateSeq) {
24294                if (DEBUG_NETWORK) {
24295                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24296                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24297                            + " lastProcStateSeqDispatchedToObservers: "
24298                            + record.lastDispatchedProcStateSeq);
24299                }
24300                return;
24301            }
24302            if (record.curProcStateSeq > procStateSeq) {
24303                if (DEBUG_NETWORK) {
24304                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24305                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24306                            + ", procStateSeq: " + procStateSeq);
24307                }
24308                return;
24309            }
24310            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24311                if (DEBUG_NETWORK) {
24312                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24313                            + procStateSeq + ", so no need to wait. Uid: "
24314                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24315                            + record.lastNetworkUpdatedProcStateSeq);
24316                }
24317                return;
24318            }
24319            try {
24320                if (DEBUG_NETWORK) {
24321                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24322                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24323                }
24324                final long startTime = SystemClock.uptimeMillis();
24325                record.waitingForNetwork = true;
24326                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24327                record.waitingForNetwork = false;
24328                final long totalTime = SystemClock.uptimeMillis() - startTime;
24329                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24330                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24331                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24332                            + procStateSeq + " UidRec: " + record
24333                            + " validateUidRec: " + mValidateUids.get(callingUid));
24334                }
24335            } catch (InterruptedException e) {
24336                Thread.currentThread().interrupt();
24337            }
24338        }
24339    }
24340
24341    public void waitForBroadcastIdle(PrintWriter pw) {
24342        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24343        while (true) {
24344            boolean idle = true;
24345            synchronized (this) {
24346                for (BroadcastQueue queue : mBroadcastQueues) {
24347                    if (!queue.isIdle()) {
24348                        final String msg = "Waiting for queue " + queue + " to become idle...";
24349                        pw.println(msg);
24350                        pw.flush();
24351                        Slog.v(TAG, msg);
24352                        idle = false;
24353                    }
24354                }
24355            }
24356
24357            if (idle) {
24358                final String msg = "All broadcast queues are idle!";
24359                pw.println(msg);
24360                pw.flush();
24361                Slog.v(TAG, msg);
24362                return;
24363            } else {
24364                SystemClock.sleep(1000);
24365            }
24366        }
24367    }
24368
24369    /**
24370     * Return the user id of the last resumed activity.
24371     */
24372    @Override
24373    public @UserIdInt int getLastResumedActivityUserId() {
24374        enforceCallingPermission(
24375                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24376        synchronized (this) {
24377            if (mLastResumedActivity == null) {
24378                return mUserController.getCurrentUserIdLocked();
24379            }
24380            return mLastResumedActivity.userId;
24381        }
24382    }
24383
24384    /**
24385     * An implementation of IAppTask, that allows an app to manage its own tasks via
24386     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24387     * only the process that calls getAppTasks() can call the AppTask methods.
24388     */
24389    class AppTaskImpl extends IAppTask.Stub {
24390        private int mTaskId;
24391        private int mCallingUid;
24392
24393        public AppTaskImpl(int taskId, int callingUid) {
24394            mTaskId = taskId;
24395            mCallingUid = callingUid;
24396        }
24397
24398        private void checkCaller() {
24399            if (mCallingUid != Binder.getCallingUid()) {
24400                throw new SecurityException("Caller " + mCallingUid
24401                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24402            }
24403        }
24404
24405        @Override
24406        public void finishAndRemoveTask() {
24407            checkCaller();
24408
24409            synchronized (ActivityManagerService.this) {
24410                long origId = Binder.clearCallingIdentity();
24411                try {
24412                    // We remove the task from recents to preserve backwards
24413                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24414                            REMOVE_FROM_RECENTS)) {
24415                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24416                    }
24417                } finally {
24418                    Binder.restoreCallingIdentity(origId);
24419                }
24420            }
24421        }
24422
24423        @Override
24424        public ActivityManager.RecentTaskInfo getTaskInfo() {
24425            checkCaller();
24426
24427            synchronized (ActivityManagerService.this) {
24428                long origId = Binder.clearCallingIdentity();
24429                try {
24430                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24431                    if (tr == null) {
24432                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24433                    }
24434                    return createRecentTaskInfoFromTaskRecord(tr);
24435                } finally {
24436                    Binder.restoreCallingIdentity(origId);
24437                }
24438            }
24439        }
24440
24441        @Override
24442        public void moveToFront() {
24443            checkCaller();
24444            // Will bring task to front if it already has a root activity.
24445            final long origId = Binder.clearCallingIdentity();
24446            try {
24447                synchronized (this) {
24448                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24449                }
24450            } finally {
24451                Binder.restoreCallingIdentity(origId);
24452            }
24453        }
24454
24455        @Override
24456        public int startActivity(IBinder whoThread, String callingPackage,
24457                Intent intent, String resolvedType, Bundle bOptions) {
24458            checkCaller();
24459
24460            int callingUser = UserHandle.getCallingUserId();
24461            TaskRecord tr;
24462            IApplicationThread appThread;
24463            synchronized (ActivityManagerService.this) {
24464                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24465                if (tr == null) {
24466                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24467                }
24468                appThread = IApplicationThread.Stub.asInterface(whoThread);
24469                if (appThread == null) {
24470                    throw new IllegalArgumentException("Bad app thread " + appThread);
24471                }
24472            }
24473            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24474                    resolvedType, null, null, null, null, 0, 0, null, null,
24475                    null, bOptions, false, callingUser, tr, "AppTaskImpl");
24476        }
24477
24478        @Override
24479        public void setExcludeFromRecents(boolean exclude) {
24480            checkCaller();
24481
24482            synchronized (ActivityManagerService.this) {
24483                long origId = Binder.clearCallingIdentity();
24484                try {
24485                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24486                    if (tr == null) {
24487                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24488                    }
24489                    Intent intent = tr.getBaseIntent();
24490                    if (exclude) {
24491                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24492                    } else {
24493                        intent.setFlags(intent.getFlags()
24494                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24495                    }
24496                } finally {
24497                    Binder.restoreCallingIdentity(origId);
24498                }
24499            }
24500        }
24501    }
24502
24503    /**
24504     * Kill processes for the user with id userId and that depend on the package named packageName
24505     */
24506    @Override
24507    public void killPackageDependents(String packageName, int userId) {
24508        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24509        if (packageName == null) {
24510            throw new NullPointerException(
24511                    "Cannot kill the dependents of a package without its name.");
24512        }
24513
24514        long callingId = Binder.clearCallingIdentity();
24515        IPackageManager pm = AppGlobals.getPackageManager();
24516        int pkgUid = -1;
24517        try {
24518            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24519        } catch (RemoteException e) {
24520        }
24521        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24522            throw new IllegalArgumentException(
24523                    "Cannot kill dependents of non-existing package " + packageName);
24524        }
24525        try {
24526            synchronized(this) {
24527                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24528                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24529                        "dep: " + packageName);
24530            }
24531        } finally {
24532            Binder.restoreCallingIdentity(callingId);
24533        }
24534    }
24535
24536    @Override
24537    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24538            throws RemoteException {
24539        final long callingId = Binder.clearCallingIdentity();
24540        try {
24541            mKeyguardController.dismissKeyguard(token, callback);
24542        } finally {
24543            Binder.restoreCallingIdentity(callingId);
24544        }
24545    }
24546
24547    @Override
24548    public int restartUserInBackground(final int userId) {
24549        return mUserController.restartUser(userId, /* foreground */ false);
24550    }
24551
24552    @Override
24553    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24554        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24555                "scheduleApplicationInfoChanged()");
24556
24557        synchronized (this) {
24558            final long origId = Binder.clearCallingIdentity();
24559            try {
24560                updateApplicationInfoLocked(packageNames, userId);
24561            } finally {
24562                Binder.restoreCallingIdentity(origId);
24563            }
24564        }
24565    }
24566
24567    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24568        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24569        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24570            final ProcessRecord app = mLruProcesses.get(i);
24571            if (app.thread == null) {
24572                continue;
24573            }
24574
24575            if (userId != UserHandle.USER_ALL && app.userId != userId) {
24576                continue;
24577            }
24578
24579            final int packageCount = app.pkgList.size();
24580            for (int j = 0; j < packageCount; j++) {
24581                final String packageName = app.pkgList.keyAt(j);
24582                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24583                    try {
24584                        final ApplicationInfo ai = AppGlobals.getPackageManager()
24585                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24586                        if (ai != null) {
24587                            app.thread.scheduleApplicationInfoChanged(ai);
24588                        }
24589                    } catch (RemoteException e) {
24590                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24591                                    packageName, app));
24592                    }
24593                }
24594            }
24595        }
24596    }
24597
24598    /**
24599     * Attach an agent to the specified process (proces name or PID)
24600     */
24601    public void attachAgent(String process, String path) {
24602        try {
24603            synchronized (this) {
24604                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24605                if (proc == null || proc.thread == null) {
24606                    throw new IllegalArgumentException("Unknown process: " + process);
24607                }
24608
24609                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24610                if (!isDebuggable) {
24611                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24612                        throw new SecurityException("Process not debuggable: " + proc);
24613                    }
24614                }
24615
24616                proc.thread.attachAgent(path);
24617            }
24618        } catch (RemoteException e) {
24619            throw new IllegalStateException("Process disappeared");
24620        }
24621    }
24622
24623    @VisibleForTesting
24624    public static class Injector {
24625        private NetworkManagementInternal mNmi;
24626
24627        public Context getContext() {
24628            return null;
24629        }
24630
24631        public AppOpsService getAppOpsService(File file, Handler handler) {
24632            return new AppOpsService(file, handler);
24633        }
24634
24635        public Handler getUiHandler(ActivityManagerService service) {
24636            return service.new UiHandler();
24637        }
24638
24639        public boolean isNetworkRestrictedForUid(int uid) {
24640            if (ensureHasNetworkManagementInternal()) {
24641                return mNmi.isNetworkRestrictedForUid(uid);
24642            }
24643            return false;
24644        }
24645
24646        private boolean ensureHasNetworkManagementInternal() {
24647            if (mNmi == null) {
24648                mNmi = LocalServices.getService(NetworkManagementInternal.class);
24649            }
24650            return mNmi != null;
24651        }
24652    }
24653
24654    @Override
24655    public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24656            throws RemoteException {
24657        synchronized (this) {
24658            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24659            if (r == null) {
24660                return;
24661            }
24662            final long origId = Binder.clearCallingIdentity();
24663            try {
24664                r.setShowWhenLocked(showWhenLocked);
24665            } finally {
24666                Binder.restoreCallingIdentity(origId);
24667            }
24668        }
24669    }
24670
24671    @Override
24672    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24673        synchronized (this) {
24674            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24675            if (r == null) {
24676                return;
24677            }
24678            final long origId = Binder.clearCallingIdentity();
24679            try {
24680                r.setTurnScreenOn(turnScreenOn);
24681            } finally {
24682                Binder.restoreCallingIdentity(origId);
24683            }
24684        }
24685    }
24686}
24687