ActivityManagerService.java revision c05f5d12d9a1b98221833ec0919d081a869d2486
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.CHANGE_CONFIGURATION;
20import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21import static android.Manifest.permission.INTERACT_ACROSS_USERS;
22import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
23import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
24import static android.Manifest.permission.READ_FRAME_BUFFER;
25import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
26import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
27import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
28import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
29import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
30import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
31import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
32import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
33import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
34import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
35import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
36import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
37import static android.content.pm.PackageManager.GET_PROVIDERS;
38import static android.content.pm.PackageManager.MATCH_ANY_USER;
39import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
40import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
41import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
42import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
43import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
44import static android.content.pm.PackageManager.PERMISSION_GRANTED;
45import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
46import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
47import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
48import static android.os.Build.VERSION_CODES.N;
49import static android.os.Process.BLUETOOTH_UID;
50import static android.os.Process.FIRST_APPLICATION_UID;
51import static android.os.Process.FIRST_ISOLATED_UID;
52import static android.os.Process.LAST_ISOLATED_UID;
53import static android.os.Process.NFC_UID;
54import static android.os.Process.PHONE_UID;
55import static android.os.Process.PROC_CHAR;
56import static android.os.Process.PROC_OUT_LONG;
57import static android.os.Process.PROC_PARENS;
58import static android.os.Process.PROC_SPACE_TERM;
59import static android.os.Process.ProcessStartResult;
60import static android.os.Process.ROOT_UID;
61import static android.os.Process.SCHED_FIFO;
62import static android.os.Process.SCHED_OTHER;
63import static android.os.Process.SCHED_RESET_ON_FORK;
64import static android.os.Process.SHELL_UID;
65import static android.os.Process.SIGNAL_QUIT;
66import static android.os.Process.SIGNAL_USR1;
67import static android.os.Process.SYSTEM_UID;
68import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
69import static android.os.Process.THREAD_GROUP_DEFAULT;
70import static android.os.Process.THREAD_GROUP_TOP_APP;
71import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
72import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
73import static android.os.Process.getFreeMemory;
74import static android.os.Process.getTotalMemory;
75import static android.os.Process.isThreadInProcess;
76import static android.os.Process.killProcess;
77import static android.os.Process.killProcessQuiet;
78import static android.os.Process.myPid;
79import static android.os.Process.myUid;
80import static android.os.Process.readProcFile;
81import static android.os.Process.removeAllProcessGroups;
82import static android.os.Process.sendSignal;
83import static android.os.Process.setProcessGroup;
84import static android.os.Process.setThreadPriority;
85import static android.os.Process.setThreadScheduler;
86import static android.os.Process.startWebView;
87import static android.os.Process.zygoteProcess;
88import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
89import static android.provider.Settings.Global.DEBUG_APP;
90import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
91import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
92import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
93import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
94import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
95import static android.provider.Settings.System.FONT_SCALE;
96import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
97import static android.view.Display.DEFAULT_DISPLAY;
98import static android.view.Display.INVALID_DISPLAY;
99import static com.android.internal.util.XmlUtils.readBooleanAttribute;
100import static com.android.internal.util.XmlUtils.readIntAttribute;
101import static com.android.internal.util.XmlUtils.readLongAttribute;
102import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
103import static com.android.internal.util.XmlUtils.writeIntAttribute;
104import static com.android.internal.util.XmlUtils.writeLongAttribute;
105import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
106import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
107import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
108import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
109import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
110import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
111import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
112import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
113import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
114import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
115import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
116import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
117import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
118import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
119import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
120import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
121import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
122import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
123import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
124import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
125import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
126import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
127import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
128import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
139import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
140import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
141import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
142import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
143import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
144import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
145import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
146import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
147import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
148import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
152import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
153import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
154import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
155import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
156import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
157import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
158import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
159import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
160import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
161import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
162import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
163import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
164import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
165import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
166import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
167import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
168import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
169import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
170import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
171import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
172import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
173import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
174import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
175import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
176import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
177import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
178import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
179import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
180import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
181import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
182import static com.android.server.wm.AppTransition.TRANSIT_NONE;
183import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
184import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
185import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
186import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
187import static org.xmlpull.v1.XmlPullParser.START_TAG;
188
189import android.Manifest;
190import android.Manifest.permission;
191import android.annotation.NonNull;
192import android.annotation.Nullable;
193import android.annotation.UserIdInt;
194import android.app.Activity;
195import android.app.ActivityManager;
196import android.app.ActivityManager.RunningTaskInfo;
197import android.app.ActivityManager.StackId;
198import android.app.ActivityManager.StackInfo;
199import android.app.ActivityManager.TaskSnapshot;
200import android.app.ActivityManager.TaskThumbnailInfo;
201import android.app.ActivityManagerInternal;
202import android.app.ActivityManagerInternal.SleepToken;
203import android.app.ActivityOptions;
204import android.app.ActivityThread;
205import android.app.AlertDialog;
206import android.app.AppGlobals;
207import android.app.AppOpsManager;
208import android.app.ApplicationErrorReport;
209import android.app.ApplicationThreadConstants;
210import android.app.BroadcastOptions;
211import android.app.ContentProviderHolder;
212import android.app.Dialog;
213import android.app.IActivityContainer;
214import android.app.IActivityContainerCallback;
215import android.app.IActivityController;
216import android.app.IActivityManager;
217import android.app.IAppTask;
218import android.app.IApplicationThread;
219import android.app.IInstrumentationWatcher;
220import android.app.INotificationManager;
221import android.app.IProcessObserver;
222import android.app.IServiceConnection;
223import android.app.IStopUserCallback;
224import android.app.ITaskStackListener;
225import android.app.IUiAutomationConnection;
226import android.app.IUidObserver;
227import android.app.IUserSwitchObserver;
228import android.app.Instrumentation;
229import android.app.Notification;
230import android.app.NotificationManager;
231import android.app.PendingIntent;
232import android.app.PictureInPictureArgs;
233import android.app.ProfilerInfo;
234import android.app.RemoteAction;
235import android.app.WaitResult;
236import android.app.admin.DevicePolicyManager;
237import android.app.assist.AssistContent;
238import android.app.assist.AssistStructure;
239import android.app.backup.IBackupManager;
240import android.app.usage.UsageEvents;
241import android.app.usage.UsageStatsManagerInternal;
242import android.appwidget.AppWidgetManager;
243import android.content.ActivityNotFoundException;
244import android.content.BroadcastReceiver;
245import android.content.ClipData;
246import android.content.ComponentCallbacks2;
247import android.content.ComponentName;
248import android.content.ContentProvider;
249import android.content.ContentResolver;
250import android.content.Context;
251import android.content.DialogInterface;
252import android.content.IContentProvider;
253import android.content.IIntentReceiver;
254import android.content.IIntentSender;
255import android.content.Intent;
256import android.content.IntentFilter;
257import android.content.IntentSender;
258import android.content.pm.ActivityInfo;
259import android.content.pm.ApplicationInfo;
260import android.content.pm.ConfigurationInfo;
261import android.content.pm.IPackageDataObserver;
262import android.content.pm.IPackageManager;
263import android.content.pm.InstrumentationInfo;
264import android.content.pm.PackageInfo;
265import android.content.pm.PackageManager;
266import android.content.pm.PackageManager.NameNotFoundException;
267import android.content.pm.PackageManagerInternal;
268import android.content.pm.ParceledListSlice;
269import android.content.pm.PathPermission;
270import android.content.pm.PermissionInfo;
271import android.content.pm.ProviderInfo;
272import android.content.pm.ResolveInfo;
273import android.content.pm.SELinuxUtil;
274import android.content.pm.ServiceInfo;
275import android.content.pm.UserInfo;
276import android.content.res.CompatibilityInfo;
277import android.content.res.Configuration;
278import android.content.res.Resources;
279import android.database.ContentObserver;
280import android.graphics.Bitmap;
281import android.graphics.Point;
282import android.graphics.Rect;
283import android.location.LocationManager;
284import android.media.audiofx.AudioEffect;
285import android.metrics.LogMaker;
286import android.net.Proxy;
287import android.net.ProxyInfo;
288import android.net.Uri;
289import android.os.BatteryStats;
290import android.os.Binder;
291import android.os.Build;
292import android.os.Bundle;
293import android.os.Debug;
294import android.os.DropBoxManager;
295import android.os.Environment;
296import android.os.FactoryTest;
297import android.os.FileObserver;
298import android.os.FileUtils;
299import android.os.Handler;
300import android.os.IBinder;
301import android.os.IDeviceIdentifiersPolicyService;
302import android.os.IPermissionController;
303import android.os.IProcessInfoService;
304import android.os.IProgressListener;
305import android.os.LocaleList;
306import android.os.Looper;
307import android.os.Message;
308import android.os.Parcel;
309import android.os.ParcelFileDescriptor;
310import android.os.PersistableBundle;
311import android.os.PowerManager;
312import android.os.PowerManagerInternal;
313import android.os.Process;
314import android.os.RemoteCallbackList;
315import android.os.RemoteException;
316import android.os.ResultReceiver;
317import android.os.ServiceManager;
318import android.os.ShellCallback;
319import android.os.StrictMode;
320import android.os.SystemClock;
321import android.os.SystemProperties;
322import android.os.Trace;
323import android.os.TransactionTooLargeException;
324import android.os.UpdateLock;
325import android.os.UserHandle;
326import android.os.UserManager;
327import android.os.WorkSource;
328import android.os.storage.IStorageManager;
329import android.os.storage.StorageManager;
330import android.os.storage.StorageManagerInternal;
331import android.provider.Downloads;
332import android.provider.Settings;
333import android.service.voice.IVoiceInteractionSession;
334import android.service.voice.VoiceInteractionManagerInternal;
335import android.service.voice.VoiceInteractionSession;
336import android.telecom.TelecomManager;
337import android.text.TextUtils;
338import android.text.format.DateUtils;
339import android.text.format.Time;
340import android.text.style.SuggestionSpan;
341import android.util.ArrayMap;
342import android.util.ArraySet;
343import android.util.AtomicFile;
344import android.util.BootTimingsTraceLog;
345import android.util.DebugUtils;
346import android.util.DisplayMetrics;
347import android.util.EventLog;
348import android.util.Log;
349import android.util.Pair;
350import android.util.PrintWriterPrinter;
351import android.util.Slog;
352import android.util.SparseArray;
353import android.util.SparseIntArray;
354import android.util.TimeUtils;
355import android.util.Xml;
356import android.view.Gravity;
357import android.view.LayoutInflater;
358import android.view.View;
359import android.view.WindowManager;
360
361import com.android.server.job.JobSchedulerInternal;
362import com.google.android.collect.Lists;
363import com.google.android.collect.Maps;
364
365import com.android.internal.R;
366import com.android.internal.annotations.GuardedBy;
367import com.android.internal.annotations.VisibleForTesting;
368import com.android.internal.app.AssistUtils;
369import com.android.internal.app.DumpHeapActivity;
370import com.android.internal.app.IAppOpsCallback;
371import com.android.internal.app.IAppOpsService;
372import com.android.internal.app.IVoiceInteractor;
373import com.android.internal.app.ProcessMap;
374import com.android.internal.app.SystemUserHomeActivity;
375import com.android.internal.app.procstats.ProcessStats;
376import com.android.internal.logging.MetricsLogger;
377import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
378import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
379import com.android.internal.notification.SystemNotificationChannels;
380import com.android.internal.os.BackgroundThread;
381import com.android.internal.os.BatteryStatsImpl;
382import com.android.internal.os.IResultReceiver;
383import com.android.internal.os.ProcessCpuTracker;
384import com.android.internal.os.TransferPipe;
385import com.android.internal.os.Zygote;
386import com.android.internal.policy.IKeyguardDismissCallback;
387import com.android.internal.telephony.TelephonyIntents;
388import com.android.internal.util.ArrayUtils;
389import com.android.internal.util.DumpUtils;
390import com.android.internal.util.FastPrintWriter;
391import com.android.internal.util.FastXmlSerializer;
392import com.android.internal.util.MemInfoReader;
393import com.android.internal.util.Preconditions;
394import com.android.server.AppOpsService;
395import com.android.server.AttributeCache;
396import com.android.server.DeviceIdleController;
397import com.android.server.IntentResolver;
398import com.android.server.LocalServices;
399import com.android.server.LockGuard;
400import com.android.server.NetworkManagementInternal;
401import com.android.server.RescueParty;
402import com.android.server.ServiceThread;
403import com.android.server.SystemConfig;
404import com.android.server.SystemService;
405import com.android.server.SystemServiceManager;
406import com.android.server.ThreadPriorityBooster;
407import com.android.server.Watchdog;
408import com.android.server.am.ActivityStack.ActivityState;
409import com.android.server.firewall.IntentFirewall;
410import com.android.server.pm.Installer;
411import com.android.server.pm.Installer.InstallerException;
412import com.android.server.statusbar.StatusBarManagerInternal;
413import com.android.server.vr.VrManagerInternal;
414import com.android.server.wm.WindowManagerService;
415
416import org.xmlpull.v1.XmlPullParser;
417import org.xmlpull.v1.XmlPullParserException;
418import org.xmlpull.v1.XmlSerializer;
419
420import java.io.File;
421import java.io.FileDescriptor;
422import java.io.FileInputStream;
423import java.io.FileNotFoundException;
424import java.io.FileOutputStream;
425import java.io.IOException;
426import java.io.InputStreamReader;
427import java.io.PrintWriter;
428import java.io.StringWriter;
429import java.io.UnsupportedEncodingException;
430import java.lang.ref.WeakReference;
431import java.nio.charset.StandardCharsets;
432import java.util.ArrayList;
433import java.util.Arrays;
434import java.util.Collections;
435import java.util.Comparator;
436import java.util.HashMap;
437import java.util.HashSet;
438import java.util.Iterator;
439import java.util.List;
440import java.util.Locale;
441import java.util.Map;
442import java.util.Objects;
443import java.util.Set;
444import java.util.concurrent.CountDownLatch;
445import java.util.concurrent.atomic.AtomicBoolean;
446import java.util.concurrent.atomic.AtomicLong;
447
448import dalvik.system.VMRuntime;
449import libcore.io.IoUtils;
450import libcore.util.EmptyArray;
451
452public class ActivityManagerService extends IActivityManager.Stub
453        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
454
455    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
456    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
457    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
458    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
459    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
460    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
461    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
462    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
463    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
464    private static final String TAG_LRU = TAG + POSTFIX_LRU;
465    private static final String TAG_MU = TAG + POSTFIX_MU;
466    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
467    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
468    private static final String TAG_POWER = TAG + POSTFIX_POWER;
469    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
470    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
471    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
472    private static final String TAG_PSS = TAG + POSTFIX_PSS;
473    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
474    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
475    private static final String TAG_STACK = TAG + POSTFIX_STACK;
476    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
477    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
478    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
479    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
480    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
481
482    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
483    // here so that while the job scheduler can depend on AMS, the other way around
484    // need not be the case.
485    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
486
487    /** Control over CPU and battery monitoring */
488    // write battery stats every 30 minutes.
489    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
490    static final boolean MONITOR_CPU_USAGE = true;
491    // don't sample cpu less than every 5 seconds.
492    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
493    // wait possibly forever for next cpu sample.
494    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
495    static final boolean MONITOR_THREAD_CPU_USAGE = false;
496
497    // The flags that are set for all calls we make to the package manager.
498    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
499
500    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
501
502    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
503
504    // Amount of time after a call to stopAppSwitches() during which we will
505    // prevent further untrusted switches from happening.
506    static final long APP_SWITCH_DELAY_TIME = 5*1000;
507
508    // How long we wait for a launched process to attach to the activity manager
509    // before we decide it's never going to come up for real.
510    static final int PROC_START_TIMEOUT = 10*1000;
511    // How long we wait for an attached process to publish its content providers
512    // before we decide it must be hung.
513    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
514
515    // How long we will retain processes hosting content providers in the "last activity"
516    // state before allowing them to drop down to the regular cached LRU list.  This is
517    // to avoid thrashing of provider processes under low memory situations.
518    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
519
520    // How long we wait for a launched process to attach to the activity manager
521    // before we decide it's never going to come up for real, when the process was
522    // started with a wrapper for instrumentation (such as Valgrind) because it
523    // could take much longer than usual.
524    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
525
526    // How long to wait after going idle before forcing apps to GC.
527    static final int GC_TIMEOUT = 5*1000;
528
529    // The minimum amount of time between successive GC requests for a process.
530    static final int GC_MIN_INTERVAL = 60*1000;
531
532    // The minimum amount of time between successive PSS requests for a process.
533    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
534
535    // The minimum amount of time between successive PSS requests for a process
536    // when the request is due to the memory state being lowered.
537    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
538
539    // The rate at which we check for apps using excessive power -- 15 mins.
540    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
541
542    // The minimum sample duration we will allow before deciding we have
543    // enough data on wake locks to start killing things.
544    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
545
546    // The minimum sample duration we will allow before deciding we have
547    // enough data on CPU usage to start killing things.
548    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
549
550    // How long we allow a receiver to run before giving up on it.
551    static final int BROADCAST_FG_TIMEOUT = 10*1000;
552    static final int BROADCAST_BG_TIMEOUT = 60*1000;
553
554    // How long we wait until we timeout on key dispatching.
555    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
556
557    // How long we wait until we timeout on key dispatching during instrumentation.
558    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
559
560    // This is the amount of time an app needs to be running a foreground service before
561    // we will consider it to be doing interaction for usage stats.
562    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
563
564    // Maximum amount of time we will allow to elapse before re-reporting usage stats
565    // interaction with foreground processes.
566    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
567
568    // This is the amount of time we allow an app to settle after it goes into the background,
569    // before we start restricting what it can do.
570    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
571
572    // How long to wait in getAssistContextExtras for the activity and foreground services
573    // to respond with the result.
574    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
575
576    // How long top wait when going through the modern assist (which doesn't need to block
577    // on getting this result before starting to launch its UI).
578    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
579
580    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
581    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
582
583    // Maximum number of persisted Uri grants a package is allowed
584    static final int MAX_PERSISTED_URI_GRANTS = 128;
585
586    static final int MY_PID = myPid();
587
588    static final String[] EMPTY_STRING_ARRAY = new String[0];
589
590    // How many bytes to write into the dropbox log before truncating
591    static final int DROPBOX_MAX_SIZE = 192 * 1024;
592    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
593    // as one line, but close enough for now.
594    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
595
596    // Access modes for handleIncomingUser.
597    static final int ALLOW_NON_FULL = 0;
598    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
599    static final int ALLOW_FULL_ONLY = 2;
600
601    // Necessary ApplicationInfo flags to mark an app as persistent
602    private static final int PERSISTENT_MASK =
603            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
604
605    // Intent sent when remote bugreport collection has been completed
606    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
607            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
608
609    // Used to indicate that an app transition should be animated.
610    static final boolean ANIMATE = true;
611
612    // Determines whether to take full screen screenshots
613    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
614
615    // STOPSHIP: Update default to a smaller value.
616    /**
617     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
618     */
619    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 2000; // 2 sec
620
621    /**
622     * State indicating that there is no need for any blocking for network.
623     */
624    @VisibleForTesting
625    static final int NETWORK_STATE_NO_CHANGE = 0;
626
627    /**
628     * State indicating that the main thread needs to be informed about the network wait.
629     */
630    @VisibleForTesting
631    static final int NETWORK_STATE_BLOCK = 1;
632
633    /**
634     * State indicating that any threads waiting for network state to get updated can be unblocked.
635     */
636    @VisibleForTesting
637    static final int NETWORK_STATE_UNBLOCK = 2;
638
639    // Max character limit for a notification title. If the notification title is larger than this
640    // the notification will not be legible to the user.
641    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
642
643    /** All system services */
644    SystemServiceManager mSystemServiceManager;
645    AssistUtils mAssistUtils;
646
647    private Installer mInstaller;
648
649    /** Run all ActivityStacks through this */
650    final ActivityStackSupervisor mStackSupervisor;
651    private final KeyguardController mKeyguardController;
652
653    final ActivityStarter mActivityStarter;
654
655    final TaskChangeNotificationController mTaskChangeNotificationController;
656
657    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
658
659    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
660
661    public final IntentFirewall mIntentFirewall;
662
663    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
664    // default action automatically.  Important for devices without direct input
665    // devices.
666    private boolean mShowDialogs = true;
667
668    private final VrController mVrController;
669
670    // VR Compatibility Display Id.
671    int mVrCompatibilityDisplayId = INVALID_DISPLAY;
672
673    // Whether we should use SCHED_FIFO for UI and RenderThreads.
674    private boolean mUseFifoUiScheduling = false;
675
676    BroadcastQueue mFgBroadcastQueue;
677    BroadcastQueue mBgBroadcastQueue;
678    // Convenient for easy iteration over the queues. Foreground is first
679    // so that dispatch of foreground broadcasts gets precedence.
680    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
681
682    BroadcastStats mLastBroadcastStats;
683    BroadcastStats mCurBroadcastStats;
684
685    BroadcastQueue broadcastQueueForIntent(Intent intent) {
686        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
687        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
688                "Broadcast intent " + intent + " on "
689                + (isFg ? "foreground" : "background") + " queue");
690        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
691    }
692
693    /**
694     * The last resumed activity. This is identical to the current resumed activity most
695     * of the time but could be different when we're pausing one activity before we resume
696     * another activity.
697     */
698    private ActivityRecord mLastResumedActivity;
699
700    /**
701     * If non-null, we are tracking the time the user spends in the currently focused app.
702     */
703    private AppTimeTracker mCurAppTimeTracker;
704
705    /**
706     * List of intents that were used to start the most recent tasks.
707     */
708    final RecentTasks mRecentTasks;
709
710    /**
711     * For addAppTask: cached of the last activity component that was added.
712     */
713    ComponentName mLastAddedTaskComponent;
714
715    /**
716     * For addAppTask: cached of the last activity uid that was added.
717     */
718    int mLastAddedTaskUid;
719
720    /**
721     * For addAppTask: cached of the last ActivityInfo that was added.
722     */
723    ActivityInfo mLastAddedTaskActivity;
724
725    /**
726     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
727     */
728    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
729
730    /**
731     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
732     */
733    String mDeviceOwnerName;
734
735    final UserController mUserController;
736
737    final AppErrors mAppErrors;
738
739    /**
740     * Indicates the maximum time spent waiting for the network rules to get updated.
741     */
742    @VisibleForTesting
743    long mWaitForNetworkTimeoutMs;
744
745    public boolean canShowErrorDialogs() {
746        return mShowDialogs && !mSleeping && !mShuttingDown
747                && !mKeyguardController.isKeyguardShowing();
748    }
749
750    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
751            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
752
753    static void boostPriorityForLockedSection() {
754        sThreadPriorityBooster.boost();
755    }
756
757    static void resetPriorityAfterLockedSection() {
758        sThreadPriorityBooster.reset();
759    }
760
761    public class PendingAssistExtras extends Binder implements Runnable {
762        public final ActivityRecord activity;
763        public boolean isHome;
764        public final Bundle extras;
765        public final Intent intent;
766        public final String hint;
767        public final IResultReceiver receiver;
768        public final int userHandle;
769        public boolean haveResult = false;
770        public Bundle result = null;
771        public AssistStructure structure = null;
772        public AssistContent content = null;
773        public Bundle receiverExtras;
774
775        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
776                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
777            activity = _activity;
778            extras = _extras;
779            intent = _intent;
780            hint = _hint;
781            receiver = _receiver;
782            receiverExtras = _receiverExtras;
783            userHandle = _userHandle;
784        }
785
786        @Override
787        public void run() {
788            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
789            synchronized (this) {
790                haveResult = true;
791                notifyAll();
792            }
793            pendingAssistExtrasTimedOut(this);
794        }
795    }
796
797    final ArrayList<PendingAssistExtras> mPendingAssistExtras
798            = new ArrayList<PendingAssistExtras>();
799
800    /**
801     * Process management.
802     */
803    final ProcessList mProcessList = new ProcessList();
804
805    /**
806     * All of the applications we currently have running organized by name.
807     * The keys are strings of the application package name (as
808     * returned by the package manager), and the keys are ApplicationRecord
809     * objects.
810     */
811    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
812
813    /**
814     * Tracking long-term execution of processes to look for abuse and other
815     * bad app behavior.
816     */
817    final ProcessStatsService mProcessStats;
818
819    /**
820     * The currently running isolated processes.
821     */
822    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
823
824    /**
825     * Counter for assigning isolated process uids, to avoid frequently reusing the
826     * same ones.
827     */
828    int mNextIsolatedProcessUid = 0;
829
830    /**
831     * The currently running heavy-weight process, if any.
832     */
833    ProcessRecord mHeavyWeightProcess = null;
834
835    /**
836     * Non-persistent appId whitelist for background restrictions
837     */
838    int[] mBackgroundAppIdWhitelist = new int[] {
839            BLUETOOTH_UID
840    };
841
842    /**
843     * Broadcast actions that will always be deliverable to unlaunched/background apps
844     */
845    ArraySet<String> mBackgroundLaunchBroadcasts;
846
847    /**
848     * All of the processes we currently have running organized by pid.
849     * The keys are the pid running the application.
850     *
851     * <p>NOTE: This object is protected by its own lock, NOT the global
852     * activity manager lock!
853     */
854    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
855
856    /**
857     * All of the processes that have been forced to be foreground.  The key
858     * is the pid of the caller who requested it (we hold a death
859     * link on it).
860     */
861    abstract class ForegroundToken implements IBinder.DeathRecipient {
862        int pid;
863        IBinder token;
864    }
865    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
866
867    /**
868     * List of records for processes that someone had tried to start before the
869     * system was ready.  We don't start them at that point, but ensure they
870     * are started by the time booting is complete.
871     */
872    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
873
874    /**
875     * List of persistent applications that are in the process
876     * of being started.
877     */
878    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
879
880    /**
881     * Processes that are being forcibly torn down.
882     */
883    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
884
885    /**
886     * List of running applications, sorted by recent usage.
887     * The first entry in the list is the least recently used.
888     */
889    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
890
891    /**
892     * Where in mLruProcesses that the processes hosting activities start.
893     */
894    int mLruProcessActivityStart = 0;
895
896    /**
897     * Where in mLruProcesses that the processes hosting services start.
898     * This is after (lower index) than mLruProcessesActivityStart.
899     */
900    int mLruProcessServiceStart = 0;
901
902    /**
903     * List of processes that should gc as soon as things are idle.
904     */
905    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
906
907    /**
908     * Processes we want to collect PSS data from.
909     */
910    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
911
912    private boolean mBinderTransactionTrackingEnabled = false;
913
914    /**
915     * Last time we requested PSS data of all processes.
916     */
917    long mLastFullPssTime = SystemClock.uptimeMillis();
918
919    /**
920     * If set, the next time we collect PSS data we should do a full collection
921     * with data from native processes and the kernel.
922     */
923    boolean mFullPssPending = false;
924
925    /**
926     * This is the process holding what we currently consider to be
927     * the "home" activity.
928     */
929    ProcessRecord mHomeProcess;
930
931    /**
932     * This is the process holding the activity the user last visited that
933     * is in a different process from the one they are currently in.
934     */
935    ProcessRecord mPreviousProcess;
936
937    /**
938     * The time at which the previous process was last visible.
939     */
940    long mPreviousProcessVisibleTime;
941
942    /**
943     * Track all uids that have actively running processes.
944     */
945    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
946
947    /**
948     * This is for verifying the UID report flow.
949     */
950    static final boolean VALIDATE_UID_STATES = true;
951    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
952
953    /**
954     * Packages that the user has asked to have run in screen size
955     * compatibility mode instead of filling the screen.
956     */
957    final CompatModePackages mCompatModePackages;
958
959    /**
960     * Set of IntentSenderRecord objects that are currently active.
961     */
962    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
963            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
964
965    /**
966     * Fingerprints (hashCode()) of stack traces that we've
967     * already logged DropBox entries for.  Guarded by itself.  If
968     * something (rogue user app) forces this over
969     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
970     */
971    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
972    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
973
974    /**
975     * Strict Mode background batched logging state.
976     *
977     * The string buffer is guarded by itself, and its lock is also
978     * used to determine if another batched write is already
979     * in-flight.
980     */
981    private final StringBuilder mStrictModeBuffer = new StringBuilder();
982
983    /**
984     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
985     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
986     */
987    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
988
989    /**
990     * Resolver for broadcast intents to registered receivers.
991     * Holds BroadcastFilter (subclass of IntentFilter).
992     */
993    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
994            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
995        @Override
996        protected boolean allowFilterResult(
997                BroadcastFilter filter, List<BroadcastFilter> dest) {
998            IBinder target = filter.receiverList.receiver.asBinder();
999            for (int i = dest.size() - 1; i >= 0; i--) {
1000                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1001                    return false;
1002                }
1003            }
1004            return true;
1005        }
1006
1007        @Override
1008        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1009            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1010                    || userId == filter.owningUserId) {
1011                return super.newResult(filter, match, userId);
1012            }
1013            return null;
1014        }
1015
1016        @Override
1017        protected BroadcastFilter[] newArray(int size) {
1018            return new BroadcastFilter[size];
1019        }
1020
1021        @Override
1022        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1023            return packageName.equals(filter.packageName);
1024        }
1025    };
1026
1027    /**
1028     * State of all active sticky broadcasts per user.  Keys are the action of the
1029     * sticky Intent, values are an ArrayList of all broadcasted intents with
1030     * that action (which should usually be one).  The SparseArray is keyed
1031     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1032     * for stickies that are sent to all users.
1033     */
1034    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1035            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1036
1037    final ActiveServices mServices;
1038
1039    final static class Association {
1040        final int mSourceUid;
1041        final String mSourceProcess;
1042        final int mTargetUid;
1043        final ComponentName mTargetComponent;
1044        final String mTargetProcess;
1045
1046        int mCount;
1047        long mTime;
1048
1049        int mNesting;
1050        long mStartTime;
1051
1052        // states of the source process when the bind occurred.
1053        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1054        long mLastStateUptime;
1055        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1056                - ActivityManager.MIN_PROCESS_STATE+1];
1057
1058        Association(int sourceUid, String sourceProcess, int targetUid,
1059                ComponentName targetComponent, String targetProcess) {
1060            mSourceUid = sourceUid;
1061            mSourceProcess = sourceProcess;
1062            mTargetUid = targetUid;
1063            mTargetComponent = targetComponent;
1064            mTargetProcess = targetProcess;
1065        }
1066    }
1067
1068    /**
1069     * When service association tracking is enabled, this is all of the associations we
1070     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1071     * -> association data.
1072     */
1073    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1074            mAssociations = new SparseArray<>();
1075    boolean mTrackingAssociations;
1076
1077    /**
1078     * Backup/restore process management
1079     */
1080    String mBackupAppName = null;
1081    BackupRecord mBackupTarget = null;
1082
1083    final ProviderMap mProviderMap;
1084
1085    /**
1086     * List of content providers who have clients waiting for them.  The
1087     * application is currently being launched and the provider will be
1088     * removed from this list once it is published.
1089     */
1090    final ArrayList<ContentProviderRecord> mLaunchingProviders
1091            = new ArrayList<ContentProviderRecord>();
1092
1093    /**
1094     * File storing persisted {@link #mGrantedUriPermissions}.
1095     */
1096    private final AtomicFile mGrantFile;
1097
1098    /** XML constants used in {@link #mGrantFile} */
1099    private static final String TAG_URI_GRANTS = "uri-grants";
1100    private static final String TAG_URI_GRANT = "uri-grant";
1101    private static final String ATTR_USER_HANDLE = "userHandle";
1102    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1103    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1104    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1105    private static final String ATTR_TARGET_PKG = "targetPkg";
1106    private static final String ATTR_URI = "uri";
1107    private static final String ATTR_MODE_FLAGS = "modeFlags";
1108    private static final String ATTR_CREATED_TIME = "createdTime";
1109    private static final String ATTR_PREFIX = "prefix";
1110
1111    /**
1112     * Global set of specific {@link Uri} permissions that have been granted.
1113     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1114     * to {@link UriPermission#uri} to {@link UriPermission}.
1115     */
1116    @GuardedBy("this")
1117    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1118            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1119
1120    public static class GrantUri {
1121        public final int sourceUserId;
1122        public final Uri uri;
1123        public boolean prefix;
1124
1125        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1126            this.sourceUserId = sourceUserId;
1127            this.uri = uri;
1128            this.prefix = prefix;
1129        }
1130
1131        @Override
1132        public int hashCode() {
1133            int hashCode = 1;
1134            hashCode = 31 * hashCode + sourceUserId;
1135            hashCode = 31 * hashCode + uri.hashCode();
1136            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1137            return hashCode;
1138        }
1139
1140        @Override
1141        public boolean equals(Object o) {
1142            if (o instanceof GrantUri) {
1143                GrantUri other = (GrantUri) o;
1144                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1145                        && prefix == other.prefix;
1146            }
1147            return false;
1148        }
1149
1150        @Override
1151        public String toString() {
1152            String result = uri.toString() + " [user " + sourceUserId + "]";
1153            if (prefix) result += " [prefix]";
1154            return result;
1155        }
1156
1157        public String toSafeString() {
1158            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1159            if (prefix) result += " [prefix]";
1160            return result;
1161        }
1162
1163        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1164            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1165                    ContentProvider.getUriWithoutUserId(uri), false);
1166        }
1167    }
1168
1169    CoreSettingsObserver mCoreSettingsObserver;
1170
1171    FontScaleSettingObserver mFontScaleSettingObserver;
1172
1173    private final class FontScaleSettingObserver extends ContentObserver {
1174        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1175
1176        public FontScaleSettingObserver() {
1177            super(mHandler);
1178            ContentResolver resolver = mContext.getContentResolver();
1179            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1180        }
1181
1182        @Override
1183        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1184            if (mFontScaleUri.equals(uri)) {
1185                updateFontScaleIfNeeded(userId);
1186            }
1187        }
1188    }
1189
1190    /**
1191     * Thread-local storage used to carry caller permissions over through
1192     * indirect content-provider access.
1193     */
1194    private class Identity {
1195        public final IBinder token;
1196        public final int pid;
1197        public final int uid;
1198
1199        Identity(IBinder _token, int _pid, int _uid) {
1200            token = _token;
1201            pid = _pid;
1202            uid = _uid;
1203        }
1204    }
1205
1206    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1207
1208    /**
1209     * All information we have collected about the runtime performance of
1210     * any user id that can impact battery performance.
1211     */
1212    final BatteryStatsService mBatteryStatsService;
1213
1214    /**
1215     * Information about component usage
1216     */
1217    UsageStatsManagerInternal mUsageStatsService;
1218
1219    /**
1220     * Access to DeviceIdleController service.
1221     */
1222    DeviceIdleController.LocalService mLocalDeviceIdleController;
1223
1224    /**
1225     * Set of app ids that are whitelisted for device idle and thus background check.
1226     */
1227    int[] mDeviceIdleWhitelist = new int[0];
1228
1229    /**
1230     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1231     */
1232    int[] mDeviceIdleTempWhitelist = new int[0];
1233
1234    static final class PendingTempWhitelist {
1235        final int targetUid;
1236        final long duration;
1237        final String tag;
1238
1239        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1240            targetUid = _targetUid;
1241            duration = _duration;
1242            tag = _tag;
1243        }
1244    }
1245
1246    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1247
1248    /**
1249     * Information about and control over application operations
1250     */
1251    final AppOpsService mAppOpsService;
1252
1253    /** Current sequencing integer of the configuration, for skipping old configurations. */
1254    private int mConfigurationSeq;
1255
1256    /**
1257     * Temp object used when global and/or display override configuration is updated. It is also
1258     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1259     * anyone...
1260     */
1261    private Configuration mTempConfig = new Configuration();
1262
1263    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1264            new UpdateConfigurationResult();
1265    private static final class UpdateConfigurationResult {
1266        // Configuration changes that were updated.
1267        int changes;
1268        // If the activity was relaunched to match the new configuration.
1269        boolean activityRelaunched;
1270
1271        void reset() {
1272            changes = 0;
1273            activityRelaunched = false;
1274        }
1275    }
1276
1277    boolean mSuppressResizeConfigChanges;
1278
1279    /**
1280     * Hardware-reported OpenGLES version.
1281     */
1282    final int GL_ES_VERSION;
1283
1284    /**
1285     * List of initialization arguments to pass to all processes when binding applications to them.
1286     * For example, references to the commonly used services.
1287     */
1288    HashMap<String, IBinder> mAppBindArgs;
1289    HashMap<String, IBinder> mIsolatedAppBindArgs;
1290
1291    /**
1292     * Temporary to avoid allocations.  Protected by main lock.
1293     */
1294    final StringBuilder mStringBuilder = new StringBuilder(256);
1295
1296    /**
1297     * Used to control how we initialize the service.
1298     */
1299    ComponentName mTopComponent;
1300    String mTopAction = Intent.ACTION_MAIN;
1301    String mTopData;
1302
1303    volatile boolean mProcessesReady = false;
1304    volatile boolean mSystemReady = false;
1305    volatile boolean mOnBattery = false;
1306    volatile int mFactoryTest;
1307
1308    @GuardedBy("this") boolean mBooting = false;
1309    @GuardedBy("this") boolean mCallFinishBooting = false;
1310    @GuardedBy("this") boolean mBootAnimationComplete = false;
1311    @GuardedBy("this") boolean mLaunchWarningShown = false;
1312    @GuardedBy("this") boolean mCheckedForSetup = false;
1313
1314    final Context mContext;
1315
1316    /**
1317     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1318     * change at runtime. Use mContext for non-UI purposes.
1319     */
1320    final Context mUiContext;
1321
1322    /**
1323     * The time at which we will allow normal application switches again,
1324     * after a call to {@link #stopAppSwitches()}.
1325     */
1326    long mAppSwitchesAllowedTime;
1327
1328    /**
1329     * This is set to true after the first switch after mAppSwitchesAllowedTime
1330     * is set; any switches after that will clear the time.
1331     */
1332    boolean mDidAppSwitch;
1333
1334    /**
1335     * Last time (in realtime) at which we checked for power usage.
1336     */
1337    long mLastPowerCheckRealtime;
1338
1339    /**
1340     * Last time (in uptime) at which we checked for power usage.
1341     */
1342    long mLastPowerCheckUptime;
1343
1344    /**
1345     * Set while we are wanting to sleep, to prevent any
1346     * activities from being started/resumed.
1347     *
1348     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1349     *
1350     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1351     * while in the sleep state until there is a pending transition out of sleep, in which case
1352     * mSleeping is set to false, and remains false while awake.
1353     *
1354     * Whether mSleeping can quickly toggled between true/false without the device actually
1355     * display changing states is undefined.
1356     */
1357    private boolean mSleeping = false;
1358
1359    /**
1360     * The process state used for processes that are running the top activities.
1361     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1362     */
1363    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1364
1365    /**
1366     * Set while we are running a voice interaction.  This overrides
1367     * sleeping while it is active.
1368     */
1369    private IVoiceInteractionSession mRunningVoice;
1370
1371    /**
1372     * For some direct access we need to power manager.
1373     */
1374    PowerManagerInternal mLocalPowerManager;
1375
1376    /**
1377     * We want to hold a wake lock while running a voice interaction session, since
1378     * this may happen with the screen off and we need to keep the CPU running to
1379     * be able to continue to interact with the user.
1380     */
1381    PowerManager.WakeLock mVoiceWakeLock;
1382
1383    /**
1384     * State of external calls telling us if the device is awake or asleep.
1385     */
1386    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1387
1388    /**
1389     * A list of tokens that cause the top activity to be put to sleep.
1390     * They are used by components that may hide and block interaction with underlying
1391     * activities.
1392     */
1393    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1394
1395    /**
1396     * Set if we are shutting down the system, similar to sleeping.
1397     */
1398    boolean mShuttingDown = false;
1399
1400    /**
1401     * Current sequence id for oom_adj computation traversal.
1402     */
1403    int mAdjSeq = 0;
1404
1405    /**
1406     * Current sequence id for process LRU updating.
1407     */
1408    int mLruSeq = 0;
1409
1410    /**
1411     * Keep track of the non-cached/empty process we last found, to help
1412     * determine how to distribute cached/empty processes next time.
1413     */
1414    int mNumNonCachedProcs = 0;
1415
1416    /**
1417     * Keep track of the number of cached hidden procs, to balance oom adj
1418     * distribution between those and empty procs.
1419     */
1420    int mNumCachedHiddenProcs = 0;
1421
1422    /**
1423     * Keep track of the number of service processes we last found, to
1424     * determine on the next iteration which should be B services.
1425     */
1426    int mNumServiceProcs = 0;
1427    int mNewNumAServiceProcs = 0;
1428    int mNewNumServiceProcs = 0;
1429
1430    /**
1431     * Allow the current computed overall memory level of the system to go down?
1432     * This is set to false when we are killing processes for reasons other than
1433     * memory management, so that the now smaller process list will not be taken as
1434     * an indication that memory is tighter.
1435     */
1436    boolean mAllowLowerMemLevel = false;
1437
1438    /**
1439     * The last computed memory level, for holding when we are in a state that
1440     * processes are going away for other reasons.
1441     */
1442    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1443
1444    /**
1445     * The last total number of process we have, to determine if changes actually look
1446     * like a shrinking number of process due to lower RAM.
1447     */
1448    int mLastNumProcesses;
1449
1450    /**
1451     * The uptime of the last time we performed idle maintenance.
1452     */
1453    long mLastIdleTime = SystemClock.uptimeMillis();
1454
1455    /**
1456     * Total time spent with RAM that has been added in the past since the last idle time.
1457     */
1458    long mLowRamTimeSinceLastIdle = 0;
1459
1460    /**
1461     * If RAM is currently low, when that horrible situation started.
1462     */
1463    long mLowRamStartTime = 0;
1464
1465    /**
1466     * For reporting to battery stats the current top application.
1467     */
1468    private String mCurResumedPackage = null;
1469    private int mCurResumedUid = -1;
1470
1471    /**
1472     * For reporting to battery stats the apps currently running foreground
1473     * service.  The ProcessMap is package/uid tuples; each of these contain
1474     * an array of the currently foreground processes.
1475     */
1476    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1477            = new ProcessMap<ArrayList<ProcessRecord>>();
1478
1479    /**
1480     * This is set if we had to do a delayed dexopt of an app before launching
1481     * it, to increase the ANR timeouts in that case.
1482     */
1483    boolean mDidDexOpt;
1484
1485    /**
1486     * Set if the systemServer made a call to enterSafeMode.
1487     */
1488    boolean mSafeMode;
1489
1490    /**
1491     * If true, we are running under a test environment so will sample PSS from processes
1492     * much more rapidly to try to collect better data when the tests are rapidly
1493     * running through apps.
1494     */
1495    boolean mTestPssMode = false;
1496
1497    String mDebugApp = null;
1498    boolean mWaitForDebugger = false;
1499    boolean mDebugTransient = false;
1500    String mOrigDebugApp = null;
1501    boolean mOrigWaitForDebugger = false;
1502    boolean mAlwaysFinishActivities = false;
1503    boolean mForceResizableActivities;
1504    boolean mSupportsMultiWindow;
1505    boolean mSupportsSplitScreenMultiWindow;
1506    boolean mSupportsFreeformWindowManagement;
1507    boolean mSupportsPictureInPicture;
1508    boolean mSupportsMultiDisplay;
1509    boolean mSupportsLeanbackOnly;
1510    IActivityController mController = null;
1511    boolean mControllerIsAMonkey = false;
1512    String mProfileApp = null;
1513    ProcessRecord mProfileProc = null;
1514    String mProfileFile;
1515    ParcelFileDescriptor mProfileFd;
1516    int mSamplingInterval = 0;
1517    boolean mAutoStopProfiler = false;
1518    boolean mStreamingOutput = false;
1519    int mProfileType = 0;
1520    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1521    String mMemWatchDumpProcName;
1522    String mMemWatchDumpFile;
1523    int mMemWatchDumpPid;
1524    int mMemWatchDumpUid;
1525    String mTrackAllocationApp = null;
1526    String mNativeDebuggingApp = null;
1527
1528    final long[] mTmpLong = new long[2];
1529
1530    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1531
1532    /**
1533     * A global counter for generating sequence numbers.
1534     * This value will be used when incrementing sequence numbers in individual uidRecords.
1535     *
1536     * Having a global counter ensures that seq numbers are monotonically increasing for a
1537     * particular uid even when the uidRecord is re-created.
1538     */
1539    @GuardedBy("this")
1540    @VisibleForTesting
1541    long mProcStateSeqCounter = 0;
1542
1543    private final Injector mInjector;
1544
1545    static final class ProcessChangeItem {
1546        static final int CHANGE_ACTIVITIES = 1<<0;
1547        int changes;
1548        int uid;
1549        int pid;
1550        int processState;
1551        boolean foregroundActivities;
1552    }
1553
1554    static final class UidObserverRegistration {
1555        final int uid;
1556        final String pkg;
1557        final int which;
1558        final int cutpoint;
1559
1560        final SparseIntArray lastProcStates;
1561
1562        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1563            uid = _uid;
1564            pkg = _pkg;
1565            which = _which;
1566            cutpoint = _cutpoint;
1567            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1568                lastProcStates = new SparseIntArray();
1569            } else {
1570                lastProcStates = null;
1571            }
1572        }
1573    }
1574
1575    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1576    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1577
1578    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1579    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1580
1581    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1582    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1583
1584    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1585    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1586
1587    /**
1588     * Runtime CPU use collection thread.  This object's lock is used to
1589     * perform synchronization with the thread (notifying it to run).
1590     */
1591    final Thread mProcessCpuThread;
1592
1593    /**
1594     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1595     * Must acquire this object's lock when accessing it.
1596     * NOTE: this lock will be held while doing long operations (trawling
1597     * through all processes in /proc), so it should never be acquired by
1598     * any critical paths such as when holding the main activity manager lock.
1599     */
1600    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1601            MONITOR_THREAD_CPU_USAGE);
1602    final AtomicLong mLastCpuTime = new AtomicLong(0);
1603    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1604    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1605
1606    long mLastWriteTime = 0;
1607
1608    /**
1609     * Used to retain an update lock when the foreground activity is in
1610     * immersive mode.
1611     */
1612    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1613
1614    /**
1615     * Set to true after the system has finished booting.
1616     */
1617    boolean mBooted = false;
1618
1619    WindowManagerService mWindowManager;
1620    final ActivityThread mSystemThread;
1621
1622    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1623        final ProcessRecord mApp;
1624        final int mPid;
1625        final IApplicationThread mAppThread;
1626
1627        AppDeathRecipient(ProcessRecord app, int pid,
1628                IApplicationThread thread) {
1629            if (DEBUG_ALL) Slog.v(
1630                TAG, "New death recipient " + this
1631                + " for thread " + thread.asBinder());
1632            mApp = app;
1633            mPid = pid;
1634            mAppThread = thread;
1635        }
1636
1637        @Override
1638        public void binderDied() {
1639            if (DEBUG_ALL) Slog.v(
1640                TAG, "Death received in " + this
1641                + " for thread " + mAppThread.asBinder());
1642            synchronized(ActivityManagerService.this) {
1643                appDiedLocked(mApp, mPid, mAppThread, true);
1644            }
1645        }
1646    }
1647
1648    static final int SHOW_ERROR_UI_MSG = 1;
1649    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1650    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1651    static final int UPDATE_CONFIGURATION_MSG = 4;
1652    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1653    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1654    static final int SERVICE_TIMEOUT_MSG = 12;
1655    static final int UPDATE_TIME_ZONE = 13;
1656    static final int SHOW_UID_ERROR_UI_MSG = 14;
1657    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1658    static final int PROC_START_TIMEOUT_MSG = 20;
1659    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1660    static final int KILL_APPLICATION_MSG = 22;
1661    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1662    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1663    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1664    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1665    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1666    static final int CLEAR_DNS_CACHE_MSG = 28;
1667    static final int UPDATE_HTTP_PROXY_MSG = 29;
1668    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1669    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1670    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1671    static final int REPORT_MEM_USAGE_MSG = 33;
1672    static final int REPORT_USER_SWITCH_MSG = 34;
1673    static final int CONTINUE_USER_SWITCH_MSG = 35;
1674    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1675    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1676    static final int PERSIST_URI_GRANTS_MSG = 38;
1677    static final int REQUEST_ALL_PSS_MSG = 39;
1678    static final int START_PROFILES_MSG = 40;
1679    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1680    static final int SYSTEM_USER_START_MSG = 42;
1681    static final int SYSTEM_USER_CURRENT_MSG = 43;
1682    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1683    static final int FINISH_BOOTING_MSG = 45;
1684    static final int START_USER_SWITCH_UI_MSG = 46;
1685    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1686    static final int DISMISS_DIALOG_UI_MSG = 48;
1687    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1688    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1689    static final int DELETE_DUMPHEAP_MSG = 51;
1690    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1691    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1692    static final int REPORT_TIME_TRACKER_MSG = 54;
1693    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1694    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1695    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1696    static final int IDLE_UIDS_MSG = 58;
1697    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1698    static final int LOG_STACK_STATE = 60;
1699    static final int VR_MODE_CHANGE_MSG = 61;
1700    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1701    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1702    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1703    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1704    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1705    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1706    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1707    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1708    static final int START_USER_SWITCH_FG_MSG = 712;
1709
1710    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1711    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1712    static final int FIRST_COMPAT_MODE_MSG = 300;
1713    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1714
1715    static ServiceThread sKillThread = null;
1716    static KillHandler sKillHandler = null;
1717
1718    CompatModeDialog mCompatModeDialog;
1719    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1720    long mLastMemUsageReportTime = 0;
1721
1722    /**
1723     * Flag whether the current user is a "monkey", i.e. whether
1724     * the UI is driven by a UI automation tool.
1725     */
1726    private boolean mUserIsMonkey;
1727
1728    /** Flag whether the device has a Recents UI */
1729    boolean mHasRecents;
1730
1731    /** The dimensions of the thumbnails in the Recents UI. */
1732    int mThumbnailWidth;
1733    int mThumbnailHeight;
1734    float mFullscreenThumbnailScale;
1735
1736    final ServiceThread mHandlerThread;
1737    final MainHandler mHandler;
1738    final Handler mUiHandler;
1739
1740    final ActivityManagerConstants mConstants;
1741
1742    PackageManagerInternal mPackageManagerInt;
1743
1744    // VoiceInteraction session ID that changes for each new request except when
1745    // being called for multiwindow assist in a single session.
1746    private int mViSessionId = 1000;
1747
1748    final boolean mPermissionReviewRequired;
1749
1750    /**
1751     * Current global configuration information. Contains general settings for the entire system,
1752     * also corresponds to the merged configuration of the default display.
1753     */
1754    Configuration getGlobalConfiguration() {
1755        return mStackSupervisor.getConfiguration();
1756    }
1757
1758    final class KillHandler extends Handler {
1759        static final int KILL_PROCESS_GROUP_MSG = 4000;
1760
1761        public KillHandler(Looper looper) {
1762            super(looper, null, true);
1763        }
1764
1765        @Override
1766        public void handleMessage(Message msg) {
1767            switch (msg.what) {
1768                case KILL_PROCESS_GROUP_MSG:
1769                {
1770                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1771                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1772                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1773                }
1774                break;
1775
1776                default:
1777                    super.handleMessage(msg);
1778            }
1779        }
1780    }
1781
1782    final class UiHandler extends Handler {
1783        public UiHandler() {
1784            super(com.android.server.UiThread.get().getLooper(), null, true);
1785        }
1786
1787        @Override
1788        public void handleMessage(Message msg) {
1789            switch (msg.what) {
1790            case SHOW_ERROR_UI_MSG: {
1791                mAppErrors.handleShowAppErrorUi(msg);
1792                ensureBootCompleted();
1793            } break;
1794            case SHOW_NOT_RESPONDING_UI_MSG: {
1795                mAppErrors.handleShowAnrUi(msg);
1796                ensureBootCompleted();
1797            } break;
1798            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1799                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1800                synchronized (ActivityManagerService.this) {
1801                    ProcessRecord proc = (ProcessRecord) data.get("app");
1802                    if (proc == null) {
1803                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1804                        break;
1805                    }
1806                    if (proc.crashDialog != null) {
1807                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1808                        return;
1809                    }
1810                    AppErrorResult res = (AppErrorResult) data.get("result");
1811                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1812                        Dialog d = new StrictModeViolationDialog(mContext,
1813                                ActivityManagerService.this, res, proc);
1814                        d.show();
1815                        proc.crashDialog = d;
1816                    } else {
1817                        // The device is asleep, so just pretend that the user
1818                        // saw a crash dialog and hit "force quit".
1819                        res.set(0);
1820                    }
1821                }
1822                ensureBootCompleted();
1823            } break;
1824            case SHOW_FACTORY_ERROR_UI_MSG: {
1825                Dialog d = new FactoryErrorDialog(
1826                        mUiContext, msg.getData().getCharSequence("msg"));
1827                d.show();
1828                ensureBootCompleted();
1829            } break;
1830            case WAIT_FOR_DEBUGGER_UI_MSG: {
1831                synchronized (ActivityManagerService.this) {
1832                    ProcessRecord app = (ProcessRecord)msg.obj;
1833                    if (msg.arg1 != 0) {
1834                        if (!app.waitedForDebugger) {
1835                            Dialog d = new AppWaitingForDebuggerDialog(
1836                                    ActivityManagerService.this,
1837                                    mUiContext, app);
1838                            app.waitDialog = d;
1839                            app.waitedForDebugger = true;
1840                            d.show();
1841                        }
1842                    } else {
1843                        if (app.waitDialog != null) {
1844                            app.waitDialog.dismiss();
1845                            app.waitDialog = null;
1846                        }
1847                    }
1848                }
1849            } break;
1850            case SHOW_UID_ERROR_UI_MSG: {
1851                if (mShowDialogs) {
1852                    AlertDialog d = new BaseErrorDialog(mUiContext);
1853                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1854                    d.setCancelable(false);
1855                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1856                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1857                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1858                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1859                    d.show();
1860                }
1861            } break;
1862            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1863                if (mShowDialogs) {
1864                    AlertDialog d = new BaseErrorDialog(mUiContext);
1865                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1866                    d.setCancelable(false);
1867                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1868                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1869                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1870                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1871                    d.show();
1872                }
1873            } break;
1874            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1875                synchronized (ActivityManagerService.this) {
1876                    ActivityRecord ar = (ActivityRecord) msg.obj;
1877                    if (mCompatModeDialog != null) {
1878                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1879                                ar.info.applicationInfo.packageName)) {
1880                            return;
1881                        }
1882                        mCompatModeDialog.dismiss();
1883                        mCompatModeDialog = null;
1884                    }
1885                    if (ar != null && false) {
1886                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1887                                ar.packageName)) {
1888                            int mode = mCompatModePackages.computeCompatModeLocked(
1889                                    ar.info.applicationInfo);
1890                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1891                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1892                                mCompatModeDialog = new CompatModeDialog(
1893                                        ActivityManagerService.this, mUiContext,
1894                                        ar.info.applicationInfo);
1895                                mCompatModeDialog.show();
1896                            }
1897                        }
1898                    }
1899                }
1900                break;
1901            }
1902            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1903                synchronized (ActivityManagerService.this) {
1904                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1905                    if (mUnsupportedDisplaySizeDialog != null) {
1906                        mUnsupportedDisplaySizeDialog.dismiss();
1907                        mUnsupportedDisplaySizeDialog = null;
1908                    }
1909                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1910                            ar.packageName)) {
1911                        // TODO(multi-display): Show dialog on appropriate display.
1912                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1913                                ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1914                        mUnsupportedDisplaySizeDialog.show();
1915                    }
1916                }
1917                break;
1918            }
1919            case START_USER_SWITCH_UI_MSG: {
1920                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1921                break;
1922            }
1923            case DISMISS_DIALOG_UI_MSG: {
1924                final Dialog d = (Dialog) msg.obj;
1925                d.dismiss();
1926                break;
1927            }
1928            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1929                dispatchProcessesChanged();
1930                break;
1931            }
1932            case DISPATCH_PROCESS_DIED_UI_MSG: {
1933                final int pid = msg.arg1;
1934                final int uid = msg.arg2;
1935                dispatchProcessDied(pid, uid);
1936                break;
1937            }
1938            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1939                dispatchUidsChanged();
1940            } break;
1941            case PUSH_TEMP_WHITELIST_UI_MSG: {
1942                pushTempWhitelist();
1943            } break;
1944            }
1945        }
1946    }
1947
1948    final class MainHandler extends Handler {
1949        public MainHandler(Looper looper) {
1950            super(looper, null, true);
1951        }
1952
1953        @Override
1954        public void handleMessage(Message msg) {
1955            switch (msg.what) {
1956            case UPDATE_CONFIGURATION_MSG: {
1957                final ContentResolver resolver = mContext.getContentResolver();
1958                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1959                        msg.arg1);
1960            } break;
1961            case GC_BACKGROUND_PROCESSES_MSG: {
1962                synchronized (ActivityManagerService.this) {
1963                    performAppGcsIfAppropriateLocked();
1964                }
1965            } break;
1966            case SERVICE_TIMEOUT_MSG: {
1967                if (mDidDexOpt) {
1968                    mDidDexOpt = false;
1969                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1970                    nmsg.obj = msg.obj;
1971                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1972                    return;
1973                }
1974                mServices.serviceTimeout((ProcessRecord)msg.obj);
1975            } break;
1976            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1977                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1978            } break;
1979            case SERVICE_FOREGROUND_CRASH_MSG: {
1980                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1981            } break;
1982            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1983                RemoteCallbackList<IResultReceiver> callbacks
1984                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
1985                int N = callbacks.beginBroadcast();
1986                for (int i = 0; i < N; i++) {
1987                    try {
1988                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1989                    } catch (RemoteException e) {
1990                    }
1991                }
1992                callbacks.finishBroadcast();
1993            } break;
1994            case UPDATE_TIME_ZONE: {
1995                synchronized (ActivityManagerService.this) {
1996                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1997                        ProcessRecord r = mLruProcesses.get(i);
1998                        if (r.thread != null) {
1999                            try {
2000                                r.thread.updateTimeZone();
2001                            } catch (RemoteException ex) {
2002                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2003                            }
2004                        }
2005                    }
2006                }
2007            } break;
2008            case CLEAR_DNS_CACHE_MSG: {
2009                synchronized (ActivityManagerService.this) {
2010                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2011                        ProcessRecord r = mLruProcesses.get(i);
2012                        if (r.thread != null) {
2013                            try {
2014                                r.thread.clearDnsCache();
2015                            } catch (RemoteException ex) {
2016                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2017                            }
2018                        }
2019                    }
2020                }
2021            } break;
2022            case UPDATE_HTTP_PROXY_MSG: {
2023                ProxyInfo proxy = (ProxyInfo)msg.obj;
2024                String host = "";
2025                String port = "";
2026                String exclList = "";
2027                Uri pacFileUrl = Uri.EMPTY;
2028                if (proxy != null) {
2029                    host = proxy.getHost();
2030                    port = Integer.toString(proxy.getPort());
2031                    exclList = proxy.getExclusionListAsString();
2032                    pacFileUrl = proxy.getPacFileUrl();
2033                }
2034                synchronized (ActivityManagerService.this) {
2035                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2036                        ProcessRecord r = mLruProcesses.get(i);
2037                        if (r.thread != null) {
2038                            try {
2039                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2040                            } catch (RemoteException ex) {
2041                                Slog.w(TAG, "Failed to update http proxy for: " +
2042                                        r.info.processName);
2043                            }
2044                        }
2045                    }
2046                }
2047            } break;
2048            case PROC_START_TIMEOUT_MSG: {
2049                if (mDidDexOpt) {
2050                    mDidDexOpt = false;
2051                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2052                    nmsg.obj = msg.obj;
2053                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
2054                    return;
2055                }
2056                ProcessRecord app = (ProcessRecord)msg.obj;
2057                synchronized (ActivityManagerService.this) {
2058                    processStartTimedOutLocked(app);
2059                }
2060            } break;
2061            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2062                ProcessRecord app = (ProcessRecord)msg.obj;
2063                synchronized (ActivityManagerService.this) {
2064                    processContentProviderPublishTimedOutLocked(app);
2065                }
2066            } break;
2067            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2068                synchronized (ActivityManagerService.this) {
2069                    mActivityStarter.doPendingActivityLaunchesLocked(true);
2070                }
2071            } break;
2072            case KILL_APPLICATION_MSG: {
2073                synchronized (ActivityManagerService.this) {
2074                    final int appId = msg.arg1;
2075                    final int userId = msg.arg2;
2076                    Bundle bundle = (Bundle)msg.obj;
2077                    String pkg = bundle.getString("pkg");
2078                    String reason = bundle.getString("reason");
2079                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2080                            false, userId, reason);
2081                }
2082            } break;
2083            case FINALIZE_PENDING_INTENT_MSG: {
2084                ((PendingIntentRecord)msg.obj).completeFinalize();
2085            } break;
2086            case POST_HEAVY_NOTIFICATION_MSG: {
2087                INotificationManager inm = NotificationManager.getService();
2088                if (inm == null) {
2089                    return;
2090                }
2091
2092                ActivityRecord root = (ActivityRecord)msg.obj;
2093                ProcessRecord process = root.app;
2094                if (process == null) {
2095                    return;
2096                }
2097
2098                try {
2099                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2100                    String text = mContext.getString(R.string.heavy_weight_notification,
2101                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2102                    Notification notification =
2103                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2104                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2105                            .setWhen(0)
2106                            .setOngoing(true)
2107                            .setTicker(text)
2108                            .setColor(mContext.getColor(
2109                                    com.android.internal.R.color.system_notification_accent_color))
2110                            .setContentTitle(text)
2111                            .setContentText(
2112                                    mContext.getText(R.string.heavy_weight_notification_detail))
2113                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2114                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2115                                    new UserHandle(root.userId)))
2116                            .build();
2117                    try {
2118                        inm.enqueueNotificationWithTag("android", "android", null,
2119                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2120                                notification, root.userId);
2121                    } catch (RuntimeException e) {
2122                        Slog.w(ActivityManagerService.TAG,
2123                                "Error showing notification for heavy-weight app", e);
2124                    } catch (RemoteException e) {
2125                    }
2126                } catch (NameNotFoundException e) {
2127                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2128                }
2129            } break;
2130            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2131                INotificationManager inm = NotificationManager.getService();
2132                if (inm == null) {
2133                    return;
2134                }
2135                try {
2136                    inm.cancelNotificationWithTag("android", null,
2137                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2138                } catch (RuntimeException e) {
2139                    Slog.w(ActivityManagerService.TAG,
2140                            "Error canceling notification for service", e);
2141                } catch (RemoteException e) {
2142                }
2143            } break;
2144            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2145                synchronized (ActivityManagerService.this) {
2146                    checkExcessivePowerUsageLocked(true);
2147                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2148                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2149                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
2150                }
2151            } break;
2152            case REPORT_MEM_USAGE_MSG: {
2153                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2154                Thread thread = new Thread() {
2155                    @Override public void run() {
2156                        reportMemUsage(memInfos);
2157                    }
2158                };
2159                thread.start();
2160                break;
2161            }
2162            case START_USER_SWITCH_FG_MSG: {
2163                mUserController.startUserInForeground(msg.arg1);
2164                break;
2165            }
2166            case REPORT_USER_SWITCH_MSG: {
2167                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2168                break;
2169            }
2170            case CONTINUE_USER_SWITCH_MSG: {
2171                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2172                break;
2173            }
2174            case USER_SWITCH_TIMEOUT_MSG: {
2175                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2176                break;
2177            }
2178            case IMMERSIVE_MODE_LOCK_MSG: {
2179                final boolean nextState = (msg.arg1 != 0);
2180                if (mUpdateLock.isHeld() != nextState) {
2181                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2182                            "Applying new update lock state '" + nextState
2183                            + "' for " + (ActivityRecord)msg.obj);
2184                    if (nextState) {
2185                        mUpdateLock.acquire();
2186                    } else {
2187                        mUpdateLock.release();
2188                    }
2189                }
2190                break;
2191            }
2192            case PERSIST_URI_GRANTS_MSG: {
2193                writeGrantedUriPermissions();
2194                break;
2195            }
2196            case REQUEST_ALL_PSS_MSG: {
2197                synchronized (ActivityManagerService.this) {
2198                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2199                }
2200                break;
2201            }
2202            case START_PROFILES_MSG: {
2203                synchronized (ActivityManagerService.this) {
2204                    mUserController.startProfilesLocked();
2205                }
2206                break;
2207            }
2208            case UPDATE_TIME_PREFERENCE_MSG: {
2209                // The user's time format preference might have changed.
2210                // For convenience we re-use the Intent extra values.
2211                synchronized (ActivityManagerService.this) {
2212                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2213                        ProcessRecord r = mLruProcesses.get(i);
2214                        if (r.thread != null) {
2215                            try {
2216                                r.thread.updateTimePrefs(msg.arg1);
2217                            } catch (RemoteException ex) {
2218                                Slog.w(TAG, "Failed to update preferences for: "
2219                                        + r.info.processName);
2220                            }
2221                        }
2222                    }
2223                }
2224                break;
2225            }
2226            case SYSTEM_USER_START_MSG: {
2227                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2228                        Integer.toString(msg.arg1), msg.arg1);
2229                mSystemServiceManager.startUser(msg.arg1);
2230                break;
2231            }
2232            case SYSTEM_USER_UNLOCK_MSG: {
2233                final int userId = msg.arg1;
2234                mSystemServiceManager.unlockUser(userId);
2235                synchronized (ActivityManagerService.this) {
2236                    mRecentTasks.loadUserRecentsLocked(userId);
2237                }
2238                if (userId == UserHandle.USER_SYSTEM) {
2239                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2240                }
2241                installEncryptionUnawareProviders(userId);
2242                mUserController.finishUserUnlocked((UserState) msg.obj);
2243                break;
2244            }
2245            case SYSTEM_USER_CURRENT_MSG: {
2246                mBatteryStatsService.noteEvent(
2247                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2248                        Integer.toString(msg.arg2), msg.arg2);
2249                mBatteryStatsService.noteEvent(
2250                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2251                        Integer.toString(msg.arg1), msg.arg1);
2252                mSystemServiceManager.switchUser(msg.arg1);
2253                break;
2254            }
2255            case ENTER_ANIMATION_COMPLETE_MSG: {
2256                synchronized (ActivityManagerService.this) {
2257                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2258                    if (r != null && r.app != null && r.app.thread != null) {
2259                        try {
2260                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2261                        } catch (RemoteException e) {
2262                        }
2263                    }
2264                }
2265                break;
2266            }
2267            case FINISH_BOOTING_MSG: {
2268                if (msg.arg1 != 0) {
2269                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2270                    finishBooting();
2271                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2272                }
2273                if (msg.arg2 != 0) {
2274                    enableScreenAfterBoot();
2275                }
2276                break;
2277            }
2278            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2279                try {
2280                    Locale l = (Locale) msg.obj;
2281                    IBinder service = ServiceManager.getService("mount");
2282                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2283                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2284                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2285                } catch (RemoteException e) {
2286                    Log.e(TAG, "Error storing locale for decryption UI", e);
2287                }
2288                break;
2289            }
2290            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2291                final int uid = msg.arg1;
2292                final byte[] firstPacket = (byte[]) msg.obj;
2293
2294                synchronized (mPidsSelfLocked) {
2295                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2296                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2297                        if (p.uid == uid) {
2298                            try {
2299                                p.thread.notifyCleartextNetwork(firstPacket);
2300                            } catch (RemoteException ignored) {
2301                            }
2302                        }
2303                    }
2304                }
2305                break;
2306            }
2307            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2308                final String procName;
2309                final int uid;
2310                final long memLimit;
2311                final String reportPackage;
2312                synchronized (ActivityManagerService.this) {
2313                    procName = mMemWatchDumpProcName;
2314                    uid = mMemWatchDumpUid;
2315                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2316                    if (val == null) {
2317                        val = mMemWatchProcesses.get(procName, 0);
2318                    }
2319                    if (val != null) {
2320                        memLimit = val.first;
2321                        reportPackage = val.second;
2322                    } else {
2323                        memLimit = 0;
2324                        reportPackage = null;
2325                    }
2326                }
2327                if (procName == null) {
2328                    return;
2329                }
2330
2331                if (DEBUG_PSS) Slog.d(TAG_PSS,
2332                        "Showing dump heap notification from " + procName + "/" + uid);
2333
2334                INotificationManager inm = NotificationManager.getService();
2335                if (inm == null) {
2336                    return;
2337                }
2338
2339                String text = mContext.getString(R.string.dump_heap_notification, procName);
2340
2341
2342                Intent deleteIntent = new Intent();
2343                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2344                Intent intent = new Intent();
2345                intent.setClassName("android", DumpHeapActivity.class.getName());
2346                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2347                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2348                if (reportPackage != null) {
2349                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2350                }
2351                int userId = UserHandle.getUserId(uid);
2352                Notification notification =
2353                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2354                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2355                        .setWhen(0)
2356                        .setOngoing(true)
2357                        .setAutoCancel(true)
2358                        .setTicker(text)
2359                        .setColor(mContext.getColor(
2360                                com.android.internal.R.color.system_notification_accent_color))
2361                        .setContentTitle(text)
2362                        .setContentText(
2363                                mContext.getText(R.string.dump_heap_notification_detail))
2364                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2365                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2366                                new UserHandle(userId)))
2367                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2368                                deleteIntent, 0, UserHandle.SYSTEM))
2369                        .build();
2370
2371                try {
2372                    inm.enqueueNotificationWithTag("android", "android", null,
2373                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2374                            notification, userId);
2375                } catch (RuntimeException e) {
2376                    Slog.w(ActivityManagerService.TAG,
2377                            "Error showing notification for dump heap", e);
2378                } catch (RemoteException e) {
2379                }
2380            } break;
2381            case DELETE_DUMPHEAP_MSG: {
2382                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2383                        null, DumpHeapActivity.JAVA_URI,
2384                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2385                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2386                        UserHandle.myUserId());
2387                synchronized (ActivityManagerService.this) {
2388                    mMemWatchDumpFile = null;
2389                    mMemWatchDumpProcName = null;
2390                    mMemWatchDumpPid = -1;
2391                    mMemWatchDumpUid = -1;
2392                }
2393            } break;
2394            case FOREGROUND_PROFILE_CHANGED_MSG: {
2395                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2396            } break;
2397            case REPORT_TIME_TRACKER_MSG: {
2398                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2399                tracker.deliverResult(mContext);
2400            } break;
2401            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2402                mUserController.dispatchUserSwitchComplete(msg.arg1);
2403            } break;
2404            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2405                mUserController.dispatchLockedBootComplete(msg.arg1);
2406            } break;
2407            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2408                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2409                try {
2410                    connection.shutdown();
2411                } catch (RemoteException e) {
2412                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2413                }
2414                // Only a UiAutomation can set this flag and now that
2415                // it is finished we make sure it is reset to its default.
2416                mUserIsMonkey = false;
2417            } break;
2418            case IDLE_UIDS_MSG: {
2419                idleUids();
2420            } break;
2421            case VR_MODE_CHANGE_MSG: {
2422                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2423                    return;
2424                }
2425                synchronized (ActivityManagerService.this) {
2426                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2427                    mWindowManager.disableNonVrUi(disableNonVrUi);
2428                    if (disableNonVrUi) {
2429                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2430                        // then remove the pinned stack.
2431                        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2432                                PINNED_STACK_ID);
2433                        if (pinnedStack != null) {
2434                            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2435                        }
2436                    }
2437                }
2438            } break;
2439            case NOTIFY_VR_SLEEPING_MSG: {
2440                notifyVrManagerOfSleepState(msg.arg1 != 0);
2441            } break;
2442            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2443                synchronized (ActivityManagerService.this) {
2444                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2445                        ProcessRecord r = mLruProcesses.get(i);
2446                        if (r.thread != null) {
2447                            try {
2448                                r.thread.handleTrustStorageUpdate();
2449                            } catch (RemoteException ex) {
2450                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2451                                        r.info.processName);
2452                            }
2453                        }
2454                    }
2455                }
2456            } break;
2457            }
2458        }
2459    };
2460
2461    static final int COLLECT_PSS_BG_MSG = 1;
2462
2463    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2464        @Override
2465        public void handleMessage(Message msg) {
2466            switch (msg.what) {
2467            case COLLECT_PSS_BG_MSG: {
2468                long start = SystemClock.uptimeMillis();
2469                MemInfoReader memInfo = null;
2470                synchronized (ActivityManagerService.this) {
2471                    if (mFullPssPending) {
2472                        mFullPssPending = false;
2473                        memInfo = new MemInfoReader();
2474                    }
2475                }
2476                if (memInfo != null) {
2477                    updateCpuStatsNow();
2478                    long nativeTotalPss = 0;
2479                    final List<ProcessCpuTracker.Stats> stats;
2480                    synchronized (mProcessCpuTracker) {
2481                        stats = mProcessCpuTracker.getStats( (st)-> {
2482                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2483                        });
2484                    }
2485                    final int N = stats.size();
2486                    for (int j = 0; j < N; j++) {
2487                        synchronized (mPidsSelfLocked) {
2488                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2489                                // This is one of our own processes; skip it.
2490                                continue;
2491                            }
2492                        }
2493                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2494                    }
2495                    memInfo.readMemInfo();
2496                    synchronized (ActivityManagerService.this) {
2497                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2498                                + (SystemClock.uptimeMillis()-start) + "ms");
2499                        final long cachedKb = memInfo.getCachedSizeKb();
2500                        final long freeKb = memInfo.getFreeSizeKb();
2501                        final long zramKb = memInfo.getZramTotalSizeKb();
2502                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2503                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2504                                kernelKb*1024, nativeTotalPss*1024);
2505                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2506                                nativeTotalPss);
2507                    }
2508                }
2509
2510                int num = 0;
2511                long[] tmp = new long[2];
2512                do {
2513                    ProcessRecord proc;
2514                    int procState;
2515                    int pid;
2516                    long lastPssTime;
2517                    synchronized (ActivityManagerService.this) {
2518                        if (mPendingPssProcesses.size() <= 0) {
2519                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2520                                    "Collected PSS of " + num + " processes in "
2521                                    + (SystemClock.uptimeMillis() - start) + "ms");
2522                            mPendingPssProcesses.clear();
2523                            return;
2524                        }
2525                        proc = mPendingPssProcesses.remove(0);
2526                        procState = proc.pssProcState;
2527                        lastPssTime = proc.lastPssTime;
2528                        if (proc.thread != null && procState == proc.setProcState
2529                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2530                                        < SystemClock.uptimeMillis()) {
2531                            pid = proc.pid;
2532                        } else {
2533                            proc = null;
2534                            pid = 0;
2535                        }
2536                    }
2537                    if (proc != null) {
2538                        long pss = Debug.getPss(pid, tmp, null);
2539                        synchronized (ActivityManagerService.this) {
2540                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2541                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2542                                num++;
2543                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2544                                        SystemClock.uptimeMillis());
2545                            }
2546                        }
2547                    }
2548                } while (true);
2549            }
2550            }
2551        }
2552    };
2553
2554    public void setSystemProcess() {
2555        try {
2556            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2557            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2558            ServiceManager.addService("meminfo", new MemBinder(this));
2559            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2560            ServiceManager.addService("dbinfo", new DbBinder(this));
2561            if (MONITOR_CPU_USAGE) {
2562                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2563            }
2564            ServiceManager.addService("permission", new PermissionController(this));
2565            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2566
2567            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2568                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2569            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2570
2571            synchronized (this) {
2572                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2573                app.persistent = true;
2574                app.pid = MY_PID;
2575                app.maxAdj = ProcessList.SYSTEM_ADJ;
2576                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2577                synchronized (mPidsSelfLocked) {
2578                    mPidsSelfLocked.put(app.pid, app);
2579                }
2580                updateLruProcessLocked(app, false, null);
2581                updateOomAdjLocked();
2582            }
2583        } catch (PackageManager.NameNotFoundException e) {
2584            throw new RuntimeException(
2585                    "Unable to find android system package", e);
2586        }
2587    }
2588
2589    public void setWindowManager(WindowManagerService wm) {
2590        mWindowManager = wm;
2591        mStackSupervisor.setWindowManager(wm);
2592        mActivityStarter.setWindowManager(wm);
2593    }
2594
2595    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2596        mUsageStatsService = usageStatsManager;
2597    }
2598
2599    public void startObservingNativeCrashes() {
2600        final NativeCrashListener ncl = new NativeCrashListener(this);
2601        ncl.start();
2602    }
2603
2604    public IAppOpsService getAppOpsService() {
2605        return mAppOpsService;
2606    }
2607
2608    static class MemBinder extends Binder {
2609        ActivityManagerService mActivityManagerService;
2610        MemBinder(ActivityManagerService activityManagerService) {
2611            mActivityManagerService = activityManagerService;
2612        }
2613
2614        @Override
2615        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2616            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2617                    "meminfo", pw)) return;
2618            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2619        }
2620    }
2621
2622    static class GraphicsBinder extends Binder {
2623        ActivityManagerService mActivityManagerService;
2624        GraphicsBinder(ActivityManagerService activityManagerService) {
2625            mActivityManagerService = activityManagerService;
2626        }
2627
2628        @Override
2629        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2630            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2631                    "gfxinfo", pw)) return;
2632            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2633        }
2634    }
2635
2636    static class DbBinder extends Binder {
2637        ActivityManagerService mActivityManagerService;
2638        DbBinder(ActivityManagerService activityManagerService) {
2639            mActivityManagerService = activityManagerService;
2640        }
2641
2642        @Override
2643        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2644            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2645                    "dbinfo", pw)) return;
2646            mActivityManagerService.dumpDbInfo(fd, pw, args);
2647        }
2648    }
2649
2650    static class CpuBinder extends Binder {
2651        ActivityManagerService mActivityManagerService;
2652        CpuBinder(ActivityManagerService activityManagerService) {
2653            mActivityManagerService = activityManagerService;
2654        }
2655
2656        @Override
2657        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2658            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2659                    "cpuinfo", pw)) return;
2660            synchronized (mActivityManagerService.mProcessCpuTracker) {
2661                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2662                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2663                        SystemClock.uptimeMillis()));
2664            }
2665        }
2666    }
2667
2668    public static final class Lifecycle extends SystemService {
2669        private final ActivityManagerService mService;
2670
2671        public Lifecycle(Context context) {
2672            super(context);
2673            mService = new ActivityManagerService(context);
2674        }
2675
2676        @Override
2677        public void onStart() {
2678            mService.start();
2679        }
2680
2681        public ActivityManagerService getService() {
2682            return mService;
2683        }
2684    }
2685
2686    @VisibleForTesting
2687    public ActivityManagerService(Injector injector) {
2688        mInjector = injector;
2689        mContext = mInjector.getContext();
2690        mUiContext = null;
2691        GL_ES_VERSION = 0;
2692        mActivityStarter = null;
2693        mAppErrors = null;
2694        mAppOpsService = mInjector.getAppOpsService(null, null);
2695        mBatteryStatsService = null;
2696        mCompatModePackages = null;
2697        mConstants = null;
2698        mGrantFile = null;
2699        mHandler = null;
2700        mHandlerThread = null;
2701        mIntentFirewall = null;
2702        mKeyguardController = null;
2703        mPermissionReviewRequired = false;
2704        mProcessCpuThread = null;
2705        mProcessStats = null;
2706        mProviderMap = null;
2707        mRecentTasks = null;
2708        mServices = null;
2709        mStackSupervisor = null;
2710        mSystemThread = null;
2711        mTaskChangeNotificationController = null;
2712        mUiHandler = injector.getUiHandler(null);
2713        mUserController = null;
2714        mVrController = null;
2715    }
2716
2717    // Note: This method is invoked on the main thread but may need to attach various
2718    // handlers to other threads.  So take care to be explicit about the looper.
2719    public ActivityManagerService(Context systemContext) {
2720        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2721        mInjector = new Injector();
2722        mContext = systemContext;
2723
2724        mFactoryTest = FactoryTest.getMode();
2725        mSystemThread = ActivityThread.currentActivityThread();
2726        mUiContext = mSystemThread.getSystemUiContext();
2727
2728        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2729
2730        mPermissionReviewRequired = mContext.getResources().getBoolean(
2731                com.android.internal.R.bool.config_permissionReviewRequired);
2732
2733        mHandlerThread = new ServiceThread(TAG,
2734                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2735        mHandlerThread.start();
2736        mHandler = new MainHandler(mHandlerThread.getLooper());
2737        mUiHandler = mInjector.getUiHandler(this);
2738
2739        mConstants = new ActivityManagerConstants(this, mHandler);
2740
2741        /* static; one-time init here */
2742        if (sKillHandler == null) {
2743            sKillThread = new ServiceThread(TAG + ":kill",
2744                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2745            sKillThread.start();
2746            sKillHandler = new KillHandler(sKillThread.getLooper());
2747        }
2748
2749        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2750                "foreground", BROADCAST_FG_TIMEOUT, false);
2751        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2752                "background", BROADCAST_BG_TIMEOUT, true);
2753        mBroadcastQueues[0] = mFgBroadcastQueue;
2754        mBroadcastQueues[1] = mBgBroadcastQueue;
2755
2756        mServices = new ActiveServices(this);
2757        mProviderMap = new ProviderMap(this);
2758        mAppErrors = new AppErrors(mUiContext, this);
2759
2760        // TODO: Move creation of battery stats service outside of activity manager service.
2761        File dataDir = Environment.getDataDirectory();
2762        File systemDir = new File(dataDir, "system");
2763        systemDir.mkdirs();
2764        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2765        mBatteryStatsService.getActiveStatistics().readLocked();
2766        mBatteryStatsService.scheduleWriteToDisk();
2767        mOnBattery = DEBUG_POWER ? true
2768                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2769        mBatteryStatsService.getActiveStatistics().setCallback(this);
2770
2771        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2772
2773        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2774        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2775                new IAppOpsCallback.Stub() {
2776                    @Override public void opChanged(int op, int uid, String packageName) {
2777                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2778                            if (mAppOpsService.checkOperation(op, uid, packageName)
2779                                    != AppOpsManager.MODE_ALLOWED) {
2780                                runInBackgroundDisabled(uid);
2781                            }
2782                        }
2783                    }
2784                });
2785
2786        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2787
2788        mUserController = new UserController(this);
2789
2790        mVrController = new VrController(this);
2791
2792        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2793            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2794
2795        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2796            mUseFifoUiScheduling = true;
2797        }
2798
2799        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2800        mTempConfig.setToDefaults();
2801        mTempConfig.setLocales(LocaleList.getDefault());
2802        mConfigurationSeq = mTempConfig.seq = 1;
2803        mStackSupervisor = createStackSupervisor();
2804        mStackSupervisor.onConfigurationChanged(mTempConfig);
2805        mKeyguardController = mStackSupervisor.mKeyguardController;
2806        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2807        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2808        mTaskChangeNotificationController =
2809                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2810        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2811        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2812
2813        mProcessCpuThread = new Thread("CpuTracker") {
2814            @Override
2815            public void run() {
2816                synchronized (mProcessCpuTracker) {
2817                    mProcessCpuInitLatch.countDown();
2818                    mProcessCpuTracker.init();
2819                }
2820                while (true) {
2821                    try {
2822                        try {
2823                            synchronized(this) {
2824                                final long now = SystemClock.uptimeMillis();
2825                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2826                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2827                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2828                                //        + ", write delay=" + nextWriteDelay);
2829                                if (nextWriteDelay < nextCpuDelay) {
2830                                    nextCpuDelay = nextWriteDelay;
2831                                }
2832                                if (nextCpuDelay > 0) {
2833                                    mProcessCpuMutexFree.set(true);
2834                                    this.wait(nextCpuDelay);
2835                                }
2836                            }
2837                        } catch (InterruptedException e) {
2838                        }
2839                        updateCpuStatsNow();
2840                    } catch (Exception e) {
2841                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2842                    }
2843                }
2844            }
2845        };
2846
2847        Watchdog.getInstance().addMonitor(this);
2848        Watchdog.getInstance().addThread(mHandler);
2849    }
2850
2851    protected ActivityStackSupervisor createStackSupervisor() {
2852        return new ActivityStackSupervisor(this, mHandler.getLooper());
2853    }
2854
2855    public void setSystemServiceManager(SystemServiceManager mgr) {
2856        mSystemServiceManager = mgr;
2857    }
2858
2859    public void setInstaller(Installer installer) {
2860        mInstaller = installer;
2861    }
2862
2863    private void start() {
2864        removeAllProcessGroups();
2865        mProcessCpuThread.start();
2866
2867        mBatteryStatsService.publish(mContext);
2868        mAppOpsService.publish(mContext);
2869        Slog.d("AppOps", "AppOpsService published");
2870        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2871        // Wait for the synchronized block started in mProcessCpuThread,
2872        // so that any other acccess to mProcessCpuTracker from main thread
2873        // will be blocked during mProcessCpuTracker initialization.
2874        try {
2875            mProcessCpuInitLatch.await();
2876        } catch (InterruptedException e) {
2877            Slog.wtf(TAG, "Interrupted wait during start", e);
2878            Thread.currentThread().interrupt();
2879            throw new IllegalStateException("Interrupted wait during start");
2880        }
2881    }
2882
2883    void onUserStoppedLocked(int userId) {
2884        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2885    }
2886
2887    public void initPowerManagement() {
2888        mStackSupervisor.initPowerManagement();
2889        mBatteryStatsService.initPowerManagement();
2890        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2891        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2892        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2893        mVoiceWakeLock.setReferenceCounted(false);
2894    }
2895
2896    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2897        if (mBackgroundLaunchBroadcasts == null) {
2898            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2899        }
2900        return mBackgroundLaunchBroadcasts;
2901    }
2902
2903    @Override
2904    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2905            throws RemoteException {
2906        if (code == SYSPROPS_TRANSACTION) {
2907            // We need to tell all apps about the system property change.
2908            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2909            synchronized(this) {
2910                final int NP = mProcessNames.getMap().size();
2911                for (int ip=0; ip<NP; ip++) {
2912                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2913                    final int NA = apps.size();
2914                    for (int ia=0; ia<NA; ia++) {
2915                        ProcessRecord app = apps.valueAt(ia);
2916                        if (app.thread != null) {
2917                            procs.add(app.thread.asBinder());
2918                        }
2919                    }
2920                }
2921            }
2922
2923            int N = procs.size();
2924            for (int i=0; i<N; i++) {
2925                Parcel data2 = Parcel.obtain();
2926                try {
2927                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2928                            Binder.FLAG_ONEWAY);
2929                } catch (RemoteException e) {
2930                }
2931                data2.recycle();
2932            }
2933        }
2934        try {
2935            return super.onTransact(code, data, reply, flags);
2936        } catch (RuntimeException e) {
2937            // The activity manager only throws security exceptions, so let's
2938            // log all others.
2939            if (!(e instanceof SecurityException)) {
2940                Slog.wtf(TAG, "Activity Manager Crash", e);
2941            }
2942            throw e;
2943        }
2944    }
2945
2946    void updateCpuStats() {
2947        final long now = SystemClock.uptimeMillis();
2948        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2949            return;
2950        }
2951        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2952            synchronized (mProcessCpuThread) {
2953                mProcessCpuThread.notify();
2954            }
2955        }
2956    }
2957
2958    void updateCpuStatsNow() {
2959        synchronized (mProcessCpuTracker) {
2960            mProcessCpuMutexFree.set(false);
2961            final long now = SystemClock.uptimeMillis();
2962            boolean haveNewCpuStats = false;
2963
2964            if (MONITOR_CPU_USAGE &&
2965                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2966                mLastCpuTime.set(now);
2967                mProcessCpuTracker.update();
2968                if (mProcessCpuTracker.hasGoodLastStats()) {
2969                    haveNewCpuStats = true;
2970                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2971                    //Slog.i(TAG, "Total CPU usage: "
2972                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2973
2974                    // Slog the cpu usage if the property is set.
2975                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2976                        int user = mProcessCpuTracker.getLastUserTime();
2977                        int system = mProcessCpuTracker.getLastSystemTime();
2978                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2979                        int irq = mProcessCpuTracker.getLastIrqTime();
2980                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2981                        int idle = mProcessCpuTracker.getLastIdleTime();
2982
2983                        int total = user + system + iowait + irq + softIrq + idle;
2984                        if (total == 0) total = 1;
2985
2986                        EventLog.writeEvent(EventLogTags.CPU,
2987                                ((user+system+iowait+irq+softIrq) * 100) / total,
2988                                (user * 100) / total,
2989                                (system * 100) / total,
2990                                (iowait * 100) / total,
2991                                (irq * 100) / total,
2992                                (softIrq * 100) / total);
2993                    }
2994                }
2995            }
2996
2997            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2998            synchronized(bstats) {
2999                synchronized(mPidsSelfLocked) {
3000                    if (haveNewCpuStats) {
3001                        if (bstats.startAddingCpuLocked()) {
3002                            int totalUTime = 0;
3003                            int totalSTime = 0;
3004                            final int N = mProcessCpuTracker.countStats();
3005                            for (int i=0; i<N; i++) {
3006                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3007                                if (!st.working) {
3008                                    continue;
3009                                }
3010                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3011                                totalUTime += st.rel_utime;
3012                                totalSTime += st.rel_stime;
3013                                if (pr != null) {
3014                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3015                                    if (ps == null || !ps.isActive()) {
3016                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3017                                                pr.info.uid, pr.processName);
3018                                    }
3019                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3020                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3021                                } else {
3022                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3023                                    if (ps == null || !ps.isActive()) {
3024                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3025                                                bstats.mapUid(st.uid), st.name);
3026                                    }
3027                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3028                                }
3029                            }
3030                            final int userTime = mProcessCpuTracker.getLastUserTime();
3031                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3032                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3033                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3034                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3035                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3036                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3037                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3038                        }
3039                    }
3040                }
3041
3042                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3043                    mLastWriteTime = now;
3044                    mBatteryStatsService.scheduleWriteToDisk();
3045                }
3046            }
3047        }
3048    }
3049
3050    @Override
3051    public void batteryNeedsCpuUpdate() {
3052        updateCpuStatsNow();
3053    }
3054
3055    @Override
3056    public void batteryPowerChanged(boolean onBattery) {
3057        // When plugging in, update the CPU stats first before changing
3058        // the plug state.
3059        updateCpuStatsNow();
3060        synchronized (this) {
3061            synchronized(mPidsSelfLocked) {
3062                mOnBattery = DEBUG_POWER ? true : onBattery;
3063            }
3064        }
3065    }
3066
3067    @Override
3068    public void batterySendBroadcast(Intent intent) {
3069        synchronized (this) {
3070            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3071                    AppOpsManager.OP_NONE, null, false, false,
3072                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3073        }
3074    }
3075
3076    /**
3077     * Initialize the application bind args. These are passed to each
3078     * process when the bindApplication() IPC is sent to the process. They're
3079     * lazily setup to make sure the services are running when they're asked for.
3080     */
3081    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3082        // Isolated processes won't get this optimization, so that we don't
3083        // violate the rules about which services they have access to.
3084        if (isolated) {
3085            if (mIsolatedAppBindArgs == null) {
3086                mIsolatedAppBindArgs = new HashMap<>();
3087                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3088            }
3089            return mIsolatedAppBindArgs;
3090        }
3091
3092        if (mAppBindArgs == null) {
3093            mAppBindArgs = new HashMap<>();
3094
3095            // Setup the application init args
3096            mAppBindArgs.put("package", ServiceManager.getService("package"));
3097            mAppBindArgs.put("window", ServiceManager.getService("window"));
3098            mAppBindArgs.put(Context.ALARM_SERVICE,
3099                    ServiceManager.getService(Context.ALARM_SERVICE));
3100        }
3101        return mAppBindArgs;
3102    }
3103
3104    /**
3105     * Update AMS states when an activity is resumed. This should only be called by
3106     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3107     */
3108    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3109        final TaskRecord task = r.getTask();
3110        if (task.isApplicationTask()) {
3111            if (mCurAppTimeTracker != r.appTimeTracker) {
3112                // We are switching app tracking.  Complete the current one.
3113                if (mCurAppTimeTracker != null) {
3114                    mCurAppTimeTracker.stop();
3115                    mHandler.obtainMessage(
3116                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3117                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3118                    mCurAppTimeTracker = null;
3119                }
3120                if (r.appTimeTracker != null) {
3121                    mCurAppTimeTracker = r.appTimeTracker;
3122                    startTimeTrackingFocusedActivityLocked();
3123                }
3124            } else {
3125                startTimeTrackingFocusedActivityLocked();
3126            }
3127        } else {
3128            r.appTimeTracker = null;
3129        }
3130        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3131        // TODO: Probably not, because we don't want to resume voice on switching
3132        // back to this activity
3133        if (task.voiceInteractor != null) {
3134            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3135        } else {
3136            finishRunningVoiceLocked();
3137
3138            if (mLastResumedActivity != null) {
3139                final IVoiceInteractionSession session;
3140
3141                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3142                if (lastResumedActivityTask != null
3143                        && lastResumedActivityTask.voiceSession != null) {
3144                    session = lastResumedActivityTask.voiceSession;
3145                } else {
3146                    session = mLastResumedActivity.voiceSession;
3147                }
3148
3149                if (session != null) {
3150                    // We had been in a voice interaction session, but now focused has
3151                    // move to something different.  Just finish the session, we can't
3152                    // return to it and retain the proper state and synchronization with
3153                    // the voice interaction service.
3154                    finishVoiceTask(session);
3155                }
3156            }
3157        }
3158
3159        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3160            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3161            mHandler.obtainMessage(
3162                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3163        }
3164        mLastResumedActivity = r;
3165
3166        mWindowManager.setFocusedApp(r.appToken, true);
3167
3168        applyUpdateLockStateLocked(r);
3169        applyUpdateVrModeLocked(r);
3170
3171        EventLogTags.writeAmSetResumedActivity(
3172                r == null ? -1 : r.userId,
3173                r == null ? "NULL" : r.shortComponentName,
3174                reason);
3175    }
3176
3177    @Override
3178    public void setFocusedStack(int stackId) {
3179        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3180        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3181        final long callingId = Binder.clearCallingIdentity();
3182        try {
3183            synchronized (this) {
3184                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3185                if (stack == null) {
3186                    return;
3187                }
3188                final ActivityRecord r = stack.topRunningActivityLocked();
3189                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3190                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3191                }
3192            }
3193        } finally {
3194            Binder.restoreCallingIdentity(callingId);
3195        }
3196    }
3197
3198    @Override
3199    public void setFocusedTask(int taskId) {
3200        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3201        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3202        final long callingId = Binder.clearCallingIdentity();
3203        try {
3204            synchronized (this) {
3205                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3206                if (task == null) {
3207                    return;
3208                }
3209                final ActivityRecord r = task.topRunningActivityLocked();
3210                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3211                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3212                }
3213            }
3214        } finally {
3215            Binder.restoreCallingIdentity(callingId);
3216        }
3217    }
3218
3219    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3220    @Override
3221    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3222        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3223        mTaskChangeNotificationController.registerTaskStackListener(listener);
3224    }
3225
3226    /**
3227     * Unregister a task stack listener so that it stops receiving callbacks.
3228     */
3229    @Override
3230    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3231         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3232         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3233     }
3234
3235    @Override
3236    public void notifyActivityDrawn(IBinder token) {
3237        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3238        synchronized (this) {
3239            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3240            if (r != null) {
3241                r.getStack().notifyActivityDrawnLocked(r);
3242            }
3243        }
3244    }
3245
3246    final void applyUpdateLockStateLocked(ActivityRecord r) {
3247        // Modifications to the UpdateLock state are done on our handler, outside
3248        // the activity manager's locks.  The new state is determined based on the
3249        // state *now* of the relevant activity record.  The object is passed to
3250        // the handler solely for logging detail, not to be consulted/modified.
3251        final boolean nextState = r != null && r.immersive;
3252        mHandler.sendMessage(
3253                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3254    }
3255
3256    final void applyUpdateVrModeLocked(ActivityRecord r) {
3257        mHandler.sendMessage(
3258                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3259    }
3260
3261    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3262        mHandler.sendMessage(
3263                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3264    }
3265
3266    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3267        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3268        if (vrService == null) {
3269            return;
3270        }
3271        vrService.onSleepStateChanged(isSleeping);
3272    }
3273
3274    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3275        Message msg = Message.obtain();
3276        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3277        msg.obj = r.getTask().askedCompatMode ? null : r;
3278        mUiHandler.sendMessage(msg);
3279    }
3280
3281    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3282        final Configuration globalConfig = getGlobalConfiguration();
3283        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3284                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3285            final Message msg = Message.obtain();
3286            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3287            msg.obj = r;
3288            mUiHandler.sendMessage(msg);
3289        }
3290    }
3291
3292    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3293            String what, Object obj, ProcessRecord srcApp) {
3294        app.lastActivityTime = now;
3295
3296        if (app.activities.size() > 0) {
3297            // Don't want to touch dependent processes that are hosting activities.
3298            return index;
3299        }
3300
3301        int lrui = mLruProcesses.lastIndexOf(app);
3302        if (lrui < 0) {
3303            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3304                    + what + " " + obj + " from " + srcApp);
3305            return index;
3306        }
3307
3308        if (lrui >= index) {
3309            // Don't want to cause this to move dependent processes *back* in the
3310            // list as if they were less frequently used.
3311            return index;
3312        }
3313
3314        if (lrui >= mLruProcessActivityStart) {
3315            // Don't want to touch dependent processes that are hosting activities.
3316            return index;
3317        }
3318
3319        mLruProcesses.remove(lrui);
3320        if (index > 0) {
3321            index--;
3322        }
3323        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3324                + " in LRU list: " + app);
3325        mLruProcesses.add(index, app);
3326        return index;
3327    }
3328
3329    static void killProcessGroup(int uid, int pid) {
3330        if (sKillHandler != null) {
3331            sKillHandler.sendMessage(
3332                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3333        } else {
3334            Slog.w(TAG, "Asked to kill process group before system bringup!");
3335            Process.killProcessGroup(uid, pid);
3336        }
3337    }
3338
3339    final void removeLruProcessLocked(ProcessRecord app) {
3340        int lrui = mLruProcesses.lastIndexOf(app);
3341        if (lrui >= 0) {
3342            if (!app.killed) {
3343                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3344                killProcessQuiet(app.pid);
3345                killProcessGroup(app.uid, app.pid);
3346            }
3347            if (lrui <= mLruProcessActivityStart) {
3348                mLruProcessActivityStart--;
3349            }
3350            if (lrui <= mLruProcessServiceStart) {
3351                mLruProcessServiceStart--;
3352            }
3353            mLruProcesses.remove(lrui);
3354        }
3355    }
3356
3357    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3358            ProcessRecord client) {
3359        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3360                || app.treatLikeActivity;
3361        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3362        if (!activityChange && hasActivity) {
3363            // The process has activities, so we are only allowing activity-based adjustments
3364            // to move it.  It should be kept in the front of the list with other
3365            // processes that have activities, and we don't want those to change their
3366            // order except due to activity operations.
3367            return;
3368        }
3369
3370        mLruSeq++;
3371        final long now = SystemClock.uptimeMillis();
3372        app.lastActivityTime = now;
3373
3374        // First a quick reject: if the app is already at the position we will
3375        // put it, then there is nothing to do.
3376        if (hasActivity) {
3377            final int N = mLruProcesses.size();
3378            if (N > 0 && mLruProcesses.get(N-1) == app) {
3379                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3380                return;
3381            }
3382        } else {
3383            if (mLruProcessServiceStart > 0
3384                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3385                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3386                return;
3387            }
3388        }
3389
3390        int lrui = mLruProcesses.lastIndexOf(app);
3391
3392        if (app.persistent && lrui >= 0) {
3393            // We don't care about the position of persistent processes, as long as
3394            // they are in the list.
3395            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3396            return;
3397        }
3398
3399        /* In progress: compute new position first, so we can avoid doing work
3400           if the process is not actually going to move.  Not yet working.
3401        int addIndex;
3402        int nextIndex;
3403        boolean inActivity = false, inService = false;
3404        if (hasActivity) {
3405            // Process has activities, put it at the very tipsy-top.
3406            addIndex = mLruProcesses.size();
3407            nextIndex = mLruProcessServiceStart;
3408            inActivity = true;
3409        } else if (hasService) {
3410            // Process has services, put it at the top of the service list.
3411            addIndex = mLruProcessActivityStart;
3412            nextIndex = mLruProcessServiceStart;
3413            inActivity = true;
3414            inService = true;
3415        } else  {
3416            // Process not otherwise of interest, it goes to the top of the non-service area.
3417            addIndex = mLruProcessServiceStart;
3418            if (client != null) {
3419                int clientIndex = mLruProcesses.lastIndexOf(client);
3420                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3421                        + app);
3422                if (clientIndex >= 0 && addIndex > clientIndex) {
3423                    addIndex = clientIndex;
3424                }
3425            }
3426            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3427        }
3428
3429        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3430                + mLruProcessActivityStart + "): " + app);
3431        */
3432
3433        if (lrui >= 0) {
3434            if (lrui < mLruProcessActivityStart) {
3435                mLruProcessActivityStart--;
3436            }
3437            if (lrui < mLruProcessServiceStart) {
3438                mLruProcessServiceStart--;
3439            }
3440            /*
3441            if (addIndex > lrui) {
3442                addIndex--;
3443            }
3444            if (nextIndex > lrui) {
3445                nextIndex--;
3446            }
3447            */
3448            mLruProcesses.remove(lrui);
3449        }
3450
3451        /*
3452        mLruProcesses.add(addIndex, app);
3453        if (inActivity) {
3454            mLruProcessActivityStart++;
3455        }
3456        if (inService) {
3457            mLruProcessActivityStart++;
3458        }
3459        */
3460
3461        int nextIndex;
3462        if (hasActivity) {
3463            final int N = mLruProcesses.size();
3464            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3465                // Process doesn't have activities, but has clients with
3466                // activities...  move it up, but one below the top (the top
3467                // should always have a real activity).
3468                if (DEBUG_LRU) Slog.d(TAG_LRU,
3469                        "Adding to second-top of LRU activity list: " + app);
3470                mLruProcesses.add(N - 1, app);
3471                // To keep it from spamming the LRU list (by making a bunch of clients),
3472                // we will push down any other entries owned by the app.
3473                final int uid = app.info.uid;
3474                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3475                    ProcessRecord subProc = mLruProcesses.get(i);
3476                    if (subProc.info.uid == uid) {
3477                        // We want to push this one down the list.  If the process after
3478                        // it is for the same uid, however, don't do so, because we don't
3479                        // want them internally to be re-ordered.
3480                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3481                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3482                                    "Pushing uid " + uid + " swapping at " + i + ": "
3483                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3484                            ProcessRecord tmp = mLruProcesses.get(i);
3485                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3486                            mLruProcesses.set(i - 1, tmp);
3487                            i--;
3488                        }
3489                    } else {
3490                        // A gap, we can stop here.
3491                        break;
3492                    }
3493                }
3494            } else {
3495                // Process has activities, put it at the very tipsy-top.
3496                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3497                mLruProcesses.add(app);
3498            }
3499            nextIndex = mLruProcessServiceStart;
3500        } else if (hasService) {
3501            // Process has services, put it at the top of the service list.
3502            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3503            mLruProcesses.add(mLruProcessActivityStart, app);
3504            nextIndex = mLruProcessServiceStart;
3505            mLruProcessActivityStart++;
3506        } else  {
3507            // Process not otherwise of interest, it goes to the top of the non-service area.
3508            int index = mLruProcessServiceStart;
3509            if (client != null) {
3510                // If there is a client, don't allow the process to be moved up higher
3511                // in the list than that client.
3512                int clientIndex = mLruProcesses.lastIndexOf(client);
3513                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3514                        + " when updating " + app);
3515                if (clientIndex <= lrui) {
3516                    // Don't allow the client index restriction to push it down farther in the
3517                    // list than it already is.
3518                    clientIndex = lrui;
3519                }
3520                if (clientIndex >= 0 && index > clientIndex) {
3521                    index = clientIndex;
3522                }
3523            }
3524            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3525            mLruProcesses.add(index, app);
3526            nextIndex = index-1;
3527            mLruProcessActivityStart++;
3528            mLruProcessServiceStart++;
3529        }
3530
3531        // If the app is currently using a content provider or service,
3532        // bump those processes as well.
3533        for (int j=app.connections.size()-1; j>=0; j--) {
3534            ConnectionRecord cr = app.connections.valueAt(j);
3535            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3536                    && cr.binding.service.app != null
3537                    && cr.binding.service.app.lruSeq != mLruSeq
3538                    && !cr.binding.service.app.persistent) {
3539                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3540                        "service connection", cr, app);
3541            }
3542        }
3543        for (int j=app.conProviders.size()-1; j>=0; j--) {
3544            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3545            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3546                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3547                        "provider reference", cpr, app);
3548            }
3549        }
3550    }
3551
3552    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3553        if (uid == SYSTEM_UID) {
3554            // The system gets to run in any process.  If there are multiple
3555            // processes with the same uid, just pick the first (this
3556            // should never happen).
3557            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3558            if (procs == null) return null;
3559            final int procCount = procs.size();
3560            for (int i = 0; i < procCount; i++) {
3561                final int procUid = procs.keyAt(i);
3562                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3563                    // Don't use an app process or different user process for system component.
3564                    continue;
3565                }
3566                return procs.valueAt(i);
3567            }
3568        }
3569        ProcessRecord proc = mProcessNames.get(processName, uid);
3570        if (false && proc != null && !keepIfLarge
3571                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3572                && proc.lastCachedPss >= 4000) {
3573            // Turn this condition on to cause killing to happen regularly, for testing.
3574            if (proc.baseProcessTracker != null) {
3575                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3576            }
3577            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3578        } else if (proc != null && !keepIfLarge
3579                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3580                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3581            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3582            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3583                if (proc.baseProcessTracker != null) {
3584                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3585                }
3586                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3587            }
3588        }
3589        return proc;
3590    }
3591
3592    void notifyPackageUse(String packageName, int reason) {
3593        IPackageManager pm = AppGlobals.getPackageManager();
3594        try {
3595            pm.notifyPackageUse(packageName, reason);
3596        } catch (RemoteException e) {
3597        }
3598    }
3599
3600    boolean isNextTransitionForward() {
3601        int transit = mWindowManager.getPendingAppTransition();
3602        return transit == TRANSIT_ACTIVITY_OPEN
3603                || transit == TRANSIT_TASK_OPEN
3604                || transit == TRANSIT_TASK_TO_FRONT;
3605    }
3606
3607    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3608            String processName, String abiOverride, int uid, Runnable crashHandler) {
3609        synchronized(this) {
3610            ApplicationInfo info = new ApplicationInfo();
3611            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3612            // For isolated processes, the former contains the parent's uid and the latter the
3613            // actual uid of the isolated process.
3614            // In the special case introduced by this method (which is, starting an isolated
3615            // process directly from the SystemServer without an actual parent app process) the
3616            // closest thing to a parent's uid is SYSTEM_UID.
3617            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3618            // the |isolated| logic in the ProcessRecord constructor.
3619            info.uid = SYSTEM_UID;
3620            info.processName = processName;
3621            info.className = entryPoint;
3622            info.packageName = "android";
3623            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3624            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3625                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3626                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3627                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3628                    crashHandler);
3629            return proc != null ? proc.pid : 0;
3630        }
3631    }
3632
3633    final ProcessRecord startProcessLocked(String processName,
3634            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3635            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3636            boolean isolated, boolean keepIfLarge) {
3637        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3638                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3639                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3640                null /* crashHandler */);
3641    }
3642
3643    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3644            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3645            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3646            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3647        long startTime = SystemClock.elapsedRealtime();
3648        ProcessRecord app;
3649        if (!isolated) {
3650            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3651            checkTime(startTime, "startProcess: after getProcessRecord");
3652
3653            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3654                // If we are in the background, then check to see if this process
3655                // is bad.  If so, we will just silently fail.
3656                if (mAppErrors.isBadProcessLocked(info)) {
3657                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3658                            + "/" + info.processName);
3659                    return null;
3660                }
3661            } else {
3662                // When the user is explicitly starting a process, then clear its
3663                // crash count so that we won't make it bad until they see at
3664                // least one crash dialog again, and make the process good again
3665                // if it had been bad.
3666                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3667                        + "/" + info.processName);
3668                mAppErrors.resetProcessCrashTimeLocked(info);
3669                if (mAppErrors.isBadProcessLocked(info)) {
3670                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3671                            UserHandle.getUserId(info.uid), info.uid,
3672                            info.processName);
3673                    mAppErrors.clearBadProcessLocked(info);
3674                    if (app != null) {
3675                        app.bad = false;
3676                    }
3677                }
3678            }
3679        } else {
3680            // If this is an isolated process, it can't re-use an existing process.
3681            app = null;
3682        }
3683
3684        // We don't have to do anything more if:
3685        // (1) There is an existing application record; and
3686        // (2) The caller doesn't think it is dead, OR there is no thread
3687        //     object attached to it so we know it couldn't have crashed; and
3688        // (3) There is a pid assigned to it, so it is either starting or
3689        //     already running.
3690        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3691                + " app=" + app + " knownToBeDead=" + knownToBeDead
3692                + " thread=" + (app != null ? app.thread : null)
3693                + " pid=" + (app != null ? app.pid : -1));
3694        if (app != null && app.pid > 0) {
3695            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3696                // We already have the app running, or are waiting for it to
3697                // come up (we have a pid but not yet its thread), so keep it.
3698                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3699                // If this is a new package in the process, add the package to the list
3700                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3701                checkTime(startTime, "startProcess: done, added package to proc");
3702                return app;
3703            }
3704
3705            // An application record is attached to a previous process,
3706            // clean it up now.
3707            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3708            checkTime(startTime, "startProcess: bad proc running, killing");
3709            killProcessGroup(app.uid, app.pid);
3710            handleAppDiedLocked(app, true, true);
3711            checkTime(startTime, "startProcess: done killing old proc");
3712        }
3713
3714        String hostingNameStr = hostingName != null
3715                ? hostingName.flattenToShortString() : null;
3716
3717        if (app == null) {
3718            checkTime(startTime, "startProcess: creating new process record");
3719            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3720            if (app == null) {
3721                Slog.w(TAG, "Failed making new process record for "
3722                        + processName + "/" + info.uid + " isolated=" + isolated);
3723                return null;
3724            }
3725            app.crashHandler = crashHandler;
3726            checkTime(startTime, "startProcess: done creating new process record");
3727        } else {
3728            // If this is a new package in the process, add the package to the list
3729            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3730            checkTime(startTime, "startProcess: added package to existing proc");
3731        }
3732
3733        // If the system is not ready yet, then hold off on starting this
3734        // process until it is.
3735        if (!mProcessesReady
3736                && !isAllowedWhileBooting(info)
3737                && !allowWhileBooting) {
3738            if (!mProcessesOnHold.contains(app)) {
3739                mProcessesOnHold.add(app);
3740            }
3741            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3742                    "System not ready, putting on hold: " + app);
3743            checkTime(startTime, "startProcess: returning with proc on hold");
3744            return app;
3745        }
3746
3747        checkTime(startTime, "startProcess: stepping in to startProcess");
3748        startProcessLocked(
3749                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3750        checkTime(startTime, "startProcess: done starting proc!");
3751        return (app.pid != 0) ? app : null;
3752    }
3753
3754    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3755        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3756    }
3757
3758    private final void startProcessLocked(ProcessRecord app,
3759            String hostingType, String hostingNameStr) {
3760        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3761                null /* entryPoint */, null /* entryPointArgs */);
3762    }
3763
3764    private final void startProcessLocked(ProcessRecord app, String hostingType,
3765            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3766        long startTime = SystemClock.elapsedRealtime();
3767        if (app.pid > 0 && app.pid != MY_PID) {
3768            checkTime(startTime, "startProcess: removing from pids map");
3769            synchronized (mPidsSelfLocked) {
3770                mPidsSelfLocked.remove(app.pid);
3771                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3772            }
3773            checkTime(startTime, "startProcess: done removing from pids map");
3774            app.setPid(0);
3775        }
3776
3777        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3778                "startProcessLocked removing on hold: " + app);
3779        mProcessesOnHold.remove(app);
3780
3781        checkTime(startTime, "startProcess: starting to update cpu stats");
3782        updateCpuStats();
3783        checkTime(startTime, "startProcess: done updating cpu stats");
3784
3785        try {
3786            try {
3787                final int userId = UserHandle.getUserId(app.uid);
3788                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3789            } catch (RemoteException e) {
3790                throw e.rethrowAsRuntimeException();
3791            }
3792
3793            int uid = app.uid;
3794            int[] gids = null;
3795            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3796            if (!app.isolated) {
3797                int[] permGids = null;
3798                try {
3799                    checkTime(startTime, "startProcess: getting gids from package manager");
3800                    final IPackageManager pm = AppGlobals.getPackageManager();
3801                    permGids = pm.getPackageGids(app.info.packageName,
3802                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3803                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3804                            StorageManagerInternal.class);
3805                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3806                            app.info.packageName);
3807                } catch (RemoteException e) {
3808                    throw e.rethrowAsRuntimeException();
3809                }
3810
3811                /*
3812                 * Add shared application and profile GIDs so applications can share some
3813                 * resources like shared libraries and access user-wide resources
3814                 */
3815                if (ArrayUtils.isEmpty(permGids)) {
3816                    gids = new int[3];
3817                } else {
3818                    gids = new int[permGids.length + 3];
3819                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3820                }
3821                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3822                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3823                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3824            }
3825            checkTime(startTime, "startProcess: building args");
3826            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3827                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3828                        && mTopComponent != null
3829                        && app.processName.equals(mTopComponent.getPackageName())) {
3830                    uid = 0;
3831                }
3832                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3833                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3834                    uid = 0;
3835                }
3836            }
3837            int debugFlags = 0;
3838            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3839                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3840                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3841                // Also turn on CheckJNI for debuggable apps. It's quite
3842                // awkward to turn on otherwise.
3843                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3844            }
3845            // Run the app in safe mode if its manifest requests so or the
3846            // system is booted in safe mode.
3847            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3848                mSafeMode == true) {
3849                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3850            }
3851            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3852                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3853            }
3854            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3855            if ("true".equals(genDebugInfoProperty)) {
3856                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3857            }
3858            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3859                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3860            }
3861            if ("1".equals(SystemProperties.get("debug.assert"))) {
3862                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3863            }
3864            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3865                // Enable all debug flags required by the native debugger.
3866                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3867                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3868                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3869                mNativeDebuggingApp = null;
3870            }
3871
3872            String invokeWith = null;
3873            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3874                // Debuggable apps may include a wrapper script with their library directory.
3875                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3876                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3877                try {
3878                    if (new File(wrapperFileName).exists()) {
3879                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3880                    }
3881                } finally {
3882                    StrictMode.setThreadPolicy(oldPolicy);
3883                }
3884            }
3885
3886            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3887            if (requiredAbi == null) {
3888                requiredAbi = Build.SUPPORTED_ABIS[0];
3889            }
3890
3891            String instructionSet = null;
3892            if (app.info.primaryCpuAbi != null) {
3893                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3894            }
3895
3896            app.gids = gids;
3897            app.requiredAbi = requiredAbi;
3898            app.instructionSet = instructionSet;
3899
3900            // the per-user SELinux context must be set
3901            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3902                Slog.wtf(TAG, "SELinux tag not defined",
3903                        new IllegalStateException("SELinux tag not defined for "
3904                        + app.info.packageName + " (uid " + app.uid + ")"));
3905            }
3906            final String seInfo = app.info.seInfo
3907                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3908            // Start the process.  It will either succeed and return a result containing
3909            // the PID of the new process, or else throw a RuntimeException.
3910            boolean isActivityProcess = (entryPoint == null);
3911            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3912            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3913                    app.processName);
3914            checkTime(startTime, "startProcess: asking zygote to start proc");
3915            ProcessStartResult startResult;
3916            if (hostingType.equals("webview_service")) {
3917                startResult = startWebView(entryPoint,
3918                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3919                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3920                        app.info.dataDir, null, entryPointArgs);
3921            } else {
3922                startResult = Process.start(entryPoint,
3923                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3924                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3925                        app.info.dataDir, invokeWith, entryPointArgs);
3926            }
3927            checkTime(startTime, "startProcess: returned from zygote!");
3928            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3929
3930            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3931            checkTime(startTime, "startProcess: done updating battery stats");
3932
3933            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3934                    UserHandle.getUserId(uid), startResult.pid, uid,
3935                    app.processName, hostingType,
3936                    hostingNameStr != null ? hostingNameStr : "");
3937
3938            try {
3939                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3940                        seInfo, app.info.sourceDir, startResult.pid);
3941            } catch (RemoteException ex) {
3942                // Ignore
3943            }
3944
3945            if (app.persistent) {
3946                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3947            }
3948
3949            checkTime(startTime, "startProcess: building log message");
3950            StringBuilder buf = mStringBuilder;
3951            buf.setLength(0);
3952            buf.append("Start proc ");
3953            buf.append(startResult.pid);
3954            buf.append(':');
3955            buf.append(app.processName);
3956            buf.append('/');
3957            UserHandle.formatUid(buf, uid);
3958            if (!isActivityProcess) {
3959                buf.append(" [");
3960                buf.append(entryPoint);
3961                buf.append("]");
3962            }
3963            buf.append(" for ");
3964            buf.append(hostingType);
3965            if (hostingNameStr != null) {
3966                buf.append(" ");
3967                buf.append(hostingNameStr);
3968            }
3969            Slog.i(TAG, buf.toString());
3970            app.setPid(startResult.pid);
3971            app.usingWrapper = startResult.usingWrapper;
3972            app.removed = false;
3973            app.killed = false;
3974            app.killedByAm = false;
3975            checkTime(startTime, "startProcess: starting to update pids map");
3976            ProcessRecord oldApp;
3977            synchronized (mPidsSelfLocked) {
3978                oldApp = mPidsSelfLocked.get(startResult.pid);
3979            }
3980            // If there is already an app occupying that pid that hasn't been cleaned up
3981            if (oldApp != null && !app.isolated) {
3982                // Clean up anything relating to this pid first
3983                Slog.w(TAG, "Reusing pid " + startResult.pid
3984                        + " while app is still mapped to it");
3985                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3986                        true /*replacingPid*/);
3987            }
3988            synchronized (mPidsSelfLocked) {
3989                this.mPidsSelfLocked.put(startResult.pid, app);
3990                if (isActivityProcess) {
3991                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3992                    msg.obj = app;
3993                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3994                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3995                }
3996            }
3997            checkTime(startTime, "startProcess: done updating pids map");
3998        } catch (RuntimeException e) {
3999            Slog.e(TAG, "Failure starting process " + app.processName, e);
4000
4001            // Something went very wrong while trying to start this process; one
4002            // common case is when the package is frozen due to an active
4003            // upgrade. To recover, clean up any active bookkeeping related to
4004            // starting this process. (We already invoked this method once when
4005            // the package was initially frozen through KILL_APPLICATION_MSG, so
4006            // it doesn't hurt to use it again.)
4007            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4008                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4009        }
4010    }
4011
4012    void updateUsageStats(ActivityRecord component, boolean resumed) {
4013        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4014                "updateUsageStats: comp=" + component + "res=" + resumed);
4015        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4016        if (resumed) {
4017            if (mUsageStatsService != null) {
4018                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4019                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4020            }
4021            synchronized (stats) {
4022                stats.noteActivityResumedLocked(component.app.uid);
4023            }
4024        } else {
4025            if (mUsageStatsService != null) {
4026                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4027                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4028            }
4029            synchronized (stats) {
4030                stats.noteActivityPausedLocked(component.app.uid);
4031            }
4032        }
4033    }
4034
4035    Intent getHomeIntent() {
4036        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4037        intent.setComponent(mTopComponent);
4038        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4039        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4040            intent.addCategory(Intent.CATEGORY_HOME);
4041        }
4042        return intent;
4043    }
4044
4045    boolean startHomeActivityLocked(int userId, String reason) {
4046        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4047                && mTopAction == null) {
4048            // We are running in factory test mode, but unable to find
4049            // the factory test app, so just sit around displaying the
4050            // error message and don't try to start anything.
4051            return false;
4052        }
4053        Intent intent = getHomeIntent();
4054        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4055        if (aInfo != null) {
4056            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4057            // Don't do this if the home app is currently being
4058            // instrumented.
4059            aInfo = new ActivityInfo(aInfo);
4060            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4061            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4062                    aInfo.applicationInfo.uid, true);
4063            if (app == null || app.instr == null) {
4064                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4065                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
4066            }
4067        } else {
4068            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4069        }
4070
4071        return true;
4072    }
4073
4074    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4075        ActivityInfo ai = null;
4076        ComponentName comp = intent.getComponent();
4077        try {
4078            if (comp != null) {
4079                // Factory test.
4080                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4081            } else {
4082                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4083                        intent,
4084                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4085                        flags, userId);
4086
4087                if (info != null) {
4088                    ai = info.activityInfo;
4089                }
4090            }
4091        } catch (RemoteException e) {
4092            // ignore
4093        }
4094
4095        return ai;
4096    }
4097
4098    /**
4099     * Starts the "new version setup screen" if appropriate.
4100     */
4101    void startSetupActivityLocked() {
4102        // Only do this once per boot.
4103        if (mCheckedForSetup) {
4104            return;
4105        }
4106
4107        // We will show this screen if the current one is a different
4108        // version than the last one shown, and we are not running in
4109        // low-level factory test mode.
4110        final ContentResolver resolver = mContext.getContentResolver();
4111        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4112                Settings.Global.getInt(resolver,
4113                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4114            mCheckedForSetup = true;
4115
4116            // See if we should be showing the platform update setup UI.
4117            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4118            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4119                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4120            if (!ris.isEmpty()) {
4121                final ResolveInfo ri = ris.get(0);
4122                String vers = ri.activityInfo.metaData != null
4123                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4124                        : null;
4125                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4126                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4127                            Intent.METADATA_SETUP_VERSION);
4128                }
4129                String lastVers = Settings.Secure.getString(
4130                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4131                if (vers != null && !vers.equals(lastVers)) {
4132                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4133                    intent.setComponent(new ComponentName(
4134                            ri.activityInfo.packageName, ri.activityInfo.name));
4135                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4136                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4137                            null, 0, 0, 0, null, false, false, null, null, null);
4138                }
4139            }
4140        }
4141    }
4142
4143    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4144        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4145    }
4146
4147    void enforceNotIsolatedCaller(String caller) {
4148        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4149            throw new SecurityException("Isolated process not allowed to call " + caller);
4150        }
4151    }
4152
4153    void enforceShellRestriction(String restriction, int userHandle) {
4154        if (Binder.getCallingUid() == SHELL_UID) {
4155            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4156                throw new SecurityException("Shell does not have permission to access user "
4157                        + userHandle);
4158            }
4159        }
4160    }
4161
4162    @Override
4163    public int getFrontActivityScreenCompatMode() {
4164        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4165        synchronized (this) {
4166            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4167        }
4168    }
4169
4170    @Override
4171    public void setFrontActivityScreenCompatMode(int mode) {
4172        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4173                "setFrontActivityScreenCompatMode");
4174        synchronized (this) {
4175            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4176        }
4177    }
4178
4179    @Override
4180    public int getPackageScreenCompatMode(String packageName) {
4181        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4182        synchronized (this) {
4183            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4184        }
4185    }
4186
4187    @Override
4188    public void setPackageScreenCompatMode(String packageName, int mode) {
4189        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4190                "setPackageScreenCompatMode");
4191        synchronized (this) {
4192            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4193        }
4194    }
4195
4196    @Override
4197    public boolean getPackageAskScreenCompat(String packageName) {
4198        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4199        synchronized (this) {
4200            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4201        }
4202    }
4203
4204    @Override
4205    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4206        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4207                "setPackageAskScreenCompat");
4208        synchronized (this) {
4209            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4210        }
4211    }
4212
4213    private boolean hasUsageStatsPermission(String callingPackage) {
4214        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4215                Binder.getCallingUid(), callingPackage);
4216        if (mode == AppOpsManager.MODE_DEFAULT) {
4217            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4218                    == PackageManager.PERMISSION_GRANTED;
4219        }
4220        return mode == AppOpsManager.MODE_ALLOWED;
4221    }
4222
4223    @Override
4224    public int getPackageProcessState(String packageName, String callingPackage) {
4225        if (!hasUsageStatsPermission(callingPackage)) {
4226            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4227                    "getPackageProcessState");
4228        }
4229
4230        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4231        synchronized (this) {
4232            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4233                final ProcessRecord proc = mLruProcesses.get(i);
4234                if (procState > proc.setProcState) {
4235                    if (proc.pkgList.containsKey(packageName) ||
4236                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4237                        procState = proc.setProcState;
4238                    }
4239                }
4240            }
4241        }
4242        return procState;
4243    }
4244
4245    @Override
4246    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4247            throws RemoteException {
4248        synchronized (this) {
4249            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4250            if (app == null) {
4251                throw new IllegalArgumentException("Unknown process: " + process);
4252            }
4253            if (app.thread == null) {
4254                throw new IllegalArgumentException("Process has no app thread");
4255            }
4256            if (app.trimMemoryLevel >= level) {
4257                throw new IllegalArgumentException(
4258                        "Unable to set a higher trim level than current level");
4259            }
4260            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4261                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4262                throw new IllegalArgumentException("Unable to set a background trim level "
4263                    + "on a foreground process");
4264            }
4265            app.thread.scheduleTrimMemory(level);
4266            app.trimMemoryLevel = level;
4267            return true;
4268        }
4269    }
4270
4271    private void dispatchProcessesChanged() {
4272        int N;
4273        synchronized (this) {
4274            N = mPendingProcessChanges.size();
4275            if (mActiveProcessChanges.length < N) {
4276                mActiveProcessChanges = new ProcessChangeItem[N];
4277            }
4278            mPendingProcessChanges.toArray(mActiveProcessChanges);
4279            mPendingProcessChanges.clear();
4280            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4281                    "*** Delivering " + N + " process changes");
4282        }
4283
4284        int i = mProcessObservers.beginBroadcast();
4285        while (i > 0) {
4286            i--;
4287            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4288            if (observer != null) {
4289                try {
4290                    for (int j=0; j<N; j++) {
4291                        ProcessChangeItem item = mActiveProcessChanges[j];
4292                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4293                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4294                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4295                                    + item.uid + ": " + item.foregroundActivities);
4296                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4297                                    item.foregroundActivities);
4298                        }
4299                    }
4300                } catch (RemoteException e) {
4301                }
4302            }
4303        }
4304        mProcessObservers.finishBroadcast();
4305
4306        synchronized (this) {
4307            for (int j=0; j<N; j++) {
4308                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4309            }
4310        }
4311    }
4312
4313    private void dispatchProcessDied(int pid, int uid) {
4314        int i = mProcessObservers.beginBroadcast();
4315        while (i > 0) {
4316            i--;
4317            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4318            if (observer != null) {
4319                try {
4320                    observer.onProcessDied(pid, uid);
4321                } catch (RemoteException e) {
4322                }
4323            }
4324        }
4325        mProcessObservers.finishBroadcast();
4326    }
4327
4328    @VisibleForTesting
4329    void dispatchUidsChanged() {
4330        int N;
4331        synchronized (this) {
4332            N = mPendingUidChanges.size();
4333            if (mActiveUidChanges.length < N) {
4334                mActiveUidChanges = new UidRecord.ChangeItem[N];
4335            }
4336            for (int i=0; i<N; i++) {
4337                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4338                mActiveUidChanges[i] = change;
4339                if (change.uidRecord != null) {
4340                    change.uidRecord.pendingChange = null;
4341                    change.uidRecord = null;
4342                }
4343            }
4344            mPendingUidChanges.clear();
4345            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4346                    "*** Delivering " + N + " uid changes");
4347        }
4348
4349        int i = mUidObservers.beginBroadcast();
4350        while (i > 0) {
4351            i--;
4352            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4353                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4354        }
4355        mUidObservers.finishBroadcast();
4356
4357        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4358            for (int j = 0; j < N; ++j) {
4359                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4360                if (item.change == UidRecord.CHANGE_GONE
4361                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4362                    mValidateUids.remove(item.uid);
4363                } else {
4364                    UidRecord validateUid = mValidateUids.get(item.uid);
4365                    if (validateUid == null) {
4366                        validateUid = new UidRecord(item.uid);
4367                        mValidateUids.put(item.uid, validateUid);
4368                    }
4369                    if (item.change == UidRecord.CHANGE_IDLE) {
4370                        validateUid.idle = true;
4371                    } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4372                        validateUid.idle = false;
4373                    }
4374                    validateUid.curProcState = validateUid.setProcState = item.processState;
4375                }
4376            }
4377        }
4378
4379        synchronized (this) {
4380            for (int j = 0; j < N; j++) {
4381                mAvailUidChanges.add(mActiveUidChanges[j]);
4382            }
4383        }
4384    }
4385
4386    private void dispatchUidsChangedForObserver(IUidObserver observer,
4387            UidObserverRegistration reg, int changesSize) {
4388        if (observer == null) {
4389            return;
4390        }
4391        try {
4392            for (int j = 0; j < changesSize; j++) {
4393                UidRecord.ChangeItem item = mActiveUidChanges[j];
4394                final int change = item.change;
4395                if (change == UidRecord.CHANGE_IDLE
4396                        || change == UidRecord.CHANGE_GONE_IDLE) {
4397                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4398                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4399                                "UID idle uid=" + item.uid);
4400                        observer.onUidIdle(item.uid, item.ephemeral);
4401                    }
4402                } else if (change == UidRecord.CHANGE_ACTIVE) {
4403                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4404                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4405                                "UID active uid=" + item.uid);
4406                        observer.onUidActive(item.uid);
4407                    }
4408                }
4409                if (change == UidRecord.CHANGE_GONE
4410                        || change == UidRecord.CHANGE_GONE_IDLE) {
4411                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4412                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4413                                "UID gone uid=" + item.uid);
4414                        observer.onUidGone(item.uid, item.ephemeral);
4415                    }
4416                    if (reg.lastProcStates != null) {
4417                        reg.lastProcStates.delete(item.uid);
4418                    }
4419                } else {
4420                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4421                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4422                                "UID CHANGED uid=" + item.uid
4423                                        + ": " + item.processState);
4424                        boolean doReport = true;
4425                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4426                            final int lastState = reg.lastProcStates.get(item.uid,
4427                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4428                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4429                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4430                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4431                                doReport = lastAboveCut != newAboveCut;
4432                            } else {
4433                                doReport = item.processState
4434                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4435                            }
4436                        }
4437                        if (doReport) {
4438                            if (reg.lastProcStates != null) {
4439                                reg.lastProcStates.put(item.uid, item.processState);
4440                            }
4441                            observer.onUidStateChanged(item.uid, item.processState,
4442                                    item.procStateSeq);
4443                        }
4444                    }
4445                }
4446            }
4447        } catch (RemoteException e) {
4448        }
4449    }
4450
4451    @Override
4452    public final int startActivity(IApplicationThread caller, String callingPackage,
4453            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4454            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4455        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4456                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4457                UserHandle.getCallingUserId());
4458    }
4459
4460    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4461        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4462        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4463                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4464                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4465
4466        // TODO: Switch to user app stacks here.
4467        String mimeType = intent.getType();
4468        final Uri data = intent.getData();
4469        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4470            mimeType = getProviderMimeType(data, userId);
4471        }
4472        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4473
4474        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4475        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4476                null, 0, 0, null, null, null, null, false, userId, container, null);
4477    }
4478
4479    @Override
4480    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4481            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4482            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4483        enforceNotIsolatedCaller("startActivity");
4484        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4485                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4486        // TODO: Switch to user app stacks here.
4487        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4488                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4489                profilerInfo, null, null, bOptions, false, userId, null, null);
4490    }
4491
4492    @Override
4493    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4494            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4495            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4496            int userId) {
4497
4498        // This is very dangerous -- it allows you to perform a start activity (including
4499        // permission grants) as any app that may launch one of your own activities.  So
4500        // we will only allow this to be done from activities that are part of the core framework,
4501        // and then only when they are running as the system.
4502        final ActivityRecord sourceRecord;
4503        final int targetUid;
4504        final String targetPackage;
4505        synchronized (this) {
4506            if (resultTo == null) {
4507                throw new SecurityException("Must be called from an activity");
4508            }
4509            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4510            if (sourceRecord == null) {
4511                throw new SecurityException("Called with bad activity token: " + resultTo);
4512            }
4513            if (!sourceRecord.info.packageName.equals("android")) {
4514                throw new SecurityException(
4515                        "Must be called from an activity that is declared in the android package");
4516            }
4517            if (sourceRecord.app == null) {
4518                throw new SecurityException("Called without a process attached to activity");
4519            }
4520            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4521                // This is still okay, as long as this activity is running under the
4522                // uid of the original calling activity.
4523                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4524                    throw new SecurityException(
4525                            "Calling activity in uid " + sourceRecord.app.uid
4526                                    + " must be system uid or original calling uid "
4527                                    + sourceRecord.launchedFromUid);
4528                }
4529            }
4530            if (ignoreTargetSecurity) {
4531                if (intent.getComponent() == null) {
4532                    throw new SecurityException(
4533                            "Component must be specified with ignoreTargetSecurity");
4534                }
4535                if (intent.getSelector() != null) {
4536                    throw new SecurityException(
4537                            "Selector not allowed with ignoreTargetSecurity");
4538                }
4539            }
4540            targetUid = sourceRecord.launchedFromUid;
4541            targetPackage = sourceRecord.launchedFromPackage;
4542        }
4543
4544        if (userId == UserHandle.USER_NULL) {
4545            userId = UserHandle.getUserId(sourceRecord.app.uid);
4546        }
4547
4548        // TODO: Switch to user app stacks here.
4549        try {
4550            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4551                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4552                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4553            return ret;
4554        } catch (SecurityException e) {
4555            // XXX need to figure out how to propagate to original app.
4556            // A SecurityException here is generally actually a fault of the original
4557            // calling activity (such as a fairly granting permissions), so propagate it
4558            // back to them.
4559            /*
4560            StringBuilder msg = new StringBuilder();
4561            msg.append("While launching");
4562            msg.append(intent.toString());
4563            msg.append(": ");
4564            msg.append(e.getMessage());
4565            */
4566            throw e;
4567        }
4568    }
4569
4570    @Override
4571    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4572            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4573            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4574        enforceNotIsolatedCaller("startActivityAndWait");
4575        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4576                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4577        WaitResult res = new WaitResult();
4578        // TODO: Switch to user app stacks here.
4579        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4580                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4581                bOptions, false, userId, null, null);
4582        return res;
4583    }
4584
4585    @Override
4586    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4587            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4588            int startFlags, Configuration config, Bundle bOptions, int userId) {
4589        enforceNotIsolatedCaller("startActivityWithConfig");
4590        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4591                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4592        // TODO: Switch to user app stacks here.
4593        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4594                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4595                null, null, config, bOptions, false, userId, null, null);
4596        return ret;
4597    }
4598
4599    @Override
4600    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4601            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4602            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4603            throws TransactionTooLargeException {
4604        enforceNotIsolatedCaller("startActivityIntentSender");
4605        // Refuse possible leaked file descriptors
4606        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4607            throw new IllegalArgumentException("File descriptors passed in Intent");
4608        }
4609
4610        IIntentSender sender = intent.getTarget();
4611        if (!(sender instanceof PendingIntentRecord)) {
4612            throw new IllegalArgumentException("Bad PendingIntent object");
4613        }
4614
4615        PendingIntentRecord pir = (PendingIntentRecord)sender;
4616
4617        synchronized (this) {
4618            // If this is coming from the currently resumed activity, it is
4619            // effectively saying that app switches are allowed at this point.
4620            final ActivityStack stack = getFocusedStack();
4621            if (stack.mResumedActivity != null &&
4622                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4623                mAppSwitchesAllowedTime = 0;
4624            }
4625        }
4626        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4627                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4628        return ret;
4629    }
4630
4631    @Override
4632    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4633            Intent intent, String resolvedType, IVoiceInteractionSession session,
4634            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4635            Bundle bOptions, int userId) {
4636        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4637                != PackageManager.PERMISSION_GRANTED) {
4638            String msg = "Permission Denial: startVoiceActivity() from pid="
4639                    + Binder.getCallingPid()
4640                    + ", uid=" + Binder.getCallingUid()
4641                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4642            Slog.w(TAG, msg);
4643            throw new SecurityException(msg);
4644        }
4645        if (session == null || interactor == null) {
4646            throw new NullPointerException("null session or interactor");
4647        }
4648        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4649                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4650        // TODO: Switch to user app stacks here.
4651        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4652                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4653                null, bOptions, false, userId, null, null);
4654    }
4655
4656    @Override
4657    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4658            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4659        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4660                != PackageManager.PERMISSION_GRANTED) {
4661            final String msg = "Permission Denial: startAssistantActivity() from pid="
4662                    + Binder.getCallingPid()
4663                    + ", uid=" + Binder.getCallingUid()
4664                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4665            Slog.w(TAG, msg);
4666            throw new SecurityException(msg);
4667        }
4668        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4669                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4670        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4671                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4672                userId, null, null);
4673    }
4674
4675    @Override
4676    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4677            throws RemoteException {
4678        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4679        synchronized (this) {
4680            ActivityRecord activity = getFocusedStack().topActivity();
4681            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4682                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4683            }
4684            if (mRunningVoice != null || activity.getTask().voiceSession != null
4685                    || activity.voiceSession != null) {
4686                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4687                return;
4688            }
4689            if (activity.pendingVoiceInteractionStart) {
4690                Slog.w(TAG, "Pending start of voice interaction already.");
4691                return;
4692            }
4693            activity.pendingVoiceInteractionStart = true;
4694        }
4695        LocalServices.getService(VoiceInteractionManagerInternal.class)
4696                .startLocalVoiceInteraction(callingActivity, options);
4697    }
4698
4699    @Override
4700    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4701        LocalServices.getService(VoiceInteractionManagerInternal.class)
4702                .stopLocalVoiceInteraction(callingActivity);
4703    }
4704
4705    @Override
4706    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4707        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4708                .supportsLocalVoiceInteraction();
4709    }
4710
4711    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4712            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4713        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4714        if (activityToCallback == null) return;
4715        activityToCallback.setVoiceSessionLocked(voiceSession);
4716
4717        // Inform the activity
4718        try {
4719            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4720                    voiceInteractor);
4721            long token = Binder.clearCallingIdentity();
4722            try {
4723                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4724            } finally {
4725                Binder.restoreCallingIdentity(token);
4726            }
4727            // TODO: VI Should we cache the activity so that it's easier to find later
4728            // rather than scan through all the stacks and activities?
4729        } catch (RemoteException re) {
4730            activityToCallback.clearVoiceSessionLocked();
4731            // TODO: VI Should this terminate the voice session?
4732        }
4733    }
4734
4735    @Override
4736    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4737        synchronized (this) {
4738            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4739                if (keepAwake) {
4740                    mVoiceWakeLock.acquire();
4741                } else {
4742                    mVoiceWakeLock.release();
4743                }
4744            }
4745        }
4746    }
4747
4748    @Override
4749    public boolean startNextMatchingActivity(IBinder callingActivity,
4750            Intent intent, Bundle bOptions) {
4751        // Refuse possible leaked file descriptors
4752        if (intent != null && intent.hasFileDescriptors() == true) {
4753            throw new IllegalArgumentException("File descriptors passed in Intent");
4754        }
4755        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4756
4757        synchronized (this) {
4758            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4759            if (r == null) {
4760                ActivityOptions.abort(options);
4761                return false;
4762            }
4763            if (r.app == null || r.app.thread == null) {
4764                // The caller is not running...  d'oh!
4765                ActivityOptions.abort(options);
4766                return false;
4767            }
4768            intent = new Intent(intent);
4769            // The caller is not allowed to change the data.
4770            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4771            // And we are resetting to find the next component...
4772            intent.setComponent(null);
4773
4774            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4775
4776            ActivityInfo aInfo = null;
4777            try {
4778                List<ResolveInfo> resolves =
4779                    AppGlobals.getPackageManager().queryIntentActivities(
4780                            intent, r.resolvedType,
4781                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4782                            UserHandle.getCallingUserId()).getList();
4783
4784                // Look for the original activity in the list...
4785                final int N = resolves != null ? resolves.size() : 0;
4786                for (int i=0; i<N; i++) {
4787                    ResolveInfo rInfo = resolves.get(i);
4788                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4789                            && rInfo.activityInfo.name.equals(r.info.name)) {
4790                        // We found the current one...  the next matching is
4791                        // after it.
4792                        i++;
4793                        if (i<N) {
4794                            aInfo = resolves.get(i).activityInfo;
4795                        }
4796                        if (debug) {
4797                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4798                                    + "/" + r.info.name);
4799                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4800                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4801                        }
4802                        break;
4803                    }
4804                }
4805            } catch (RemoteException e) {
4806            }
4807
4808            if (aInfo == null) {
4809                // Nobody who is next!
4810                ActivityOptions.abort(options);
4811                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4812                return false;
4813            }
4814
4815            intent.setComponent(new ComponentName(
4816                    aInfo.applicationInfo.packageName, aInfo.name));
4817            intent.setFlags(intent.getFlags()&~(
4818                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4819                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4820                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4821                    Intent.FLAG_ACTIVITY_NEW_TASK));
4822
4823            // Okay now we need to start the new activity, replacing the
4824            // currently running activity.  This is a little tricky because
4825            // we want to start the new one as if the current one is finished,
4826            // but not finish the current one first so that there is no flicker.
4827            // And thus...
4828            final boolean wasFinishing = r.finishing;
4829            r.finishing = true;
4830
4831            // Propagate reply information over to the new activity.
4832            final ActivityRecord resultTo = r.resultTo;
4833            final String resultWho = r.resultWho;
4834            final int requestCode = r.requestCode;
4835            r.resultTo = null;
4836            if (resultTo != null) {
4837                resultTo.removeResultsLocked(r, resultWho, requestCode);
4838            }
4839
4840            final long origId = Binder.clearCallingIdentity();
4841            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4842                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4843                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4844                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4845                    false, false, null, null, null);
4846            Binder.restoreCallingIdentity(origId);
4847
4848            r.finishing = wasFinishing;
4849            if (res != ActivityManager.START_SUCCESS) {
4850                return false;
4851            }
4852            return true;
4853        }
4854    }
4855
4856    @Override
4857    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4858        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4859            String msg = "Permission Denial: startActivityFromRecents called without " +
4860                    START_TASKS_FROM_RECENTS;
4861            Slog.w(TAG, msg);
4862            throw new SecurityException(msg);
4863        }
4864        final long origId = Binder.clearCallingIdentity();
4865        try {
4866            synchronized (this) {
4867                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4868            }
4869        } finally {
4870            Binder.restoreCallingIdentity(origId);
4871        }
4872    }
4873
4874    final int startActivityInPackage(int uid, String callingPackage,
4875            Intent intent, String resolvedType, IBinder resultTo,
4876            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4877            IActivityContainer container, TaskRecord inTask) {
4878
4879        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4880                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4881
4882        // TODO: Switch to user app stacks here.
4883        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4884                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4885                null, null, null, bOptions, false, userId, container, inTask);
4886        return ret;
4887    }
4888
4889    @Override
4890    public final int startActivities(IApplicationThread caller, String callingPackage,
4891            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4892            int userId) {
4893        enforceNotIsolatedCaller("startActivities");
4894        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4895                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4896        // TODO: Switch to user app stacks here.
4897        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4898                resolvedTypes, resultTo, bOptions, userId);
4899        return ret;
4900    }
4901
4902    final int startActivitiesInPackage(int uid, String callingPackage,
4903            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4904            Bundle bOptions, int userId) {
4905
4906        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4907                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4908        // TODO: Switch to user app stacks here.
4909        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4910                resultTo, bOptions, userId);
4911        return ret;
4912    }
4913
4914    @Override
4915    public void reportActivityFullyDrawn(IBinder token) {
4916        synchronized (this) {
4917            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4918            if (r == null) {
4919                return;
4920            }
4921            r.reportFullyDrawnLocked();
4922        }
4923    }
4924
4925    @Override
4926    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4927        synchronized (this) {
4928            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4929            if (r == null) {
4930                return;
4931            }
4932            final long origId = Binder.clearCallingIdentity();
4933            try {
4934                r.setRequestedOrientation(requestedOrientation);
4935            } finally {
4936                Binder.restoreCallingIdentity(origId);
4937            }
4938        }
4939    }
4940
4941    @Override
4942    public int getRequestedOrientation(IBinder token) {
4943        synchronized (this) {
4944            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4945            if (r == null) {
4946                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4947            }
4948            return r.getRequestedOrientation();
4949        }
4950    }
4951
4952    @Override
4953    public final void requestActivityRelaunch(IBinder token) {
4954        synchronized(this) {
4955            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4956            if (r == null) {
4957                return;
4958            }
4959            final long origId = Binder.clearCallingIdentity();
4960            try {
4961                r.forceNewConfig = true;
4962                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4963                        true /* preserveWindow */);
4964            } finally {
4965                Binder.restoreCallingIdentity(origId);
4966            }
4967        }
4968    }
4969
4970    /**
4971     * This is the internal entry point for handling Activity.finish().
4972     *
4973     * @param token The Binder token referencing the Activity we want to finish.
4974     * @param resultCode Result code, if any, from this Activity.
4975     * @param resultData Result data (Intent), if any, from this Activity.
4976     * @param finishTask Whether to finish the task associated with this Activity.
4977     *
4978     * @return Returns true if the activity successfully finished, or false if it is still running.
4979     */
4980    @Override
4981    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4982            int finishTask) {
4983        // Refuse possible leaked file descriptors
4984        if (resultData != null && resultData.hasFileDescriptors() == true) {
4985            throw new IllegalArgumentException("File descriptors passed in Intent");
4986        }
4987
4988        synchronized(this) {
4989            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4990            if (r == null) {
4991                return true;
4992            }
4993            // Keep track of the root activity of the task before we finish it
4994            TaskRecord tr = r.getTask();
4995            ActivityRecord rootR = tr.getRootActivity();
4996            if (rootR == null) {
4997                Slog.w(TAG, "Finishing task with all activities already finished");
4998            }
4999            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5000            // finish.
5001            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5002                    mStackSupervisor.isLastLockedTask(tr)) {
5003                Slog.i(TAG, "Not finishing task in lock task mode");
5004                mStackSupervisor.showLockTaskToast();
5005                return false;
5006            }
5007            if (mController != null) {
5008                // Find the first activity that is not finishing.
5009                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5010                if (next != null) {
5011                    // ask watcher if this is allowed
5012                    boolean resumeOK = true;
5013                    try {
5014                        resumeOK = mController.activityResuming(next.packageName);
5015                    } catch (RemoteException e) {
5016                        mController = null;
5017                        Watchdog.getInstance().setActivityController(null);
5018                    }
5019
5020                    if (!resumeOK) {
5021                        Slog.i(TAG, "Not finishing activity because controller resumed");
5022                        return false;
5023                    }
5024                }
5025            }
5026            final long origId = Binder.clearCallingIdentity();
5027            try {
5028                boolean res;
5029                final boolean finishWithRootActivity =
5030                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5031                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5032                        || (finishWithRootActivity && r == rootR)) {
5033                    // If requested, remove the task that is associated to this activity only if it
5034                    // was the root activity in the task. The result code and data is ignored
5035                    // because we don't support returning them across task boundaries. Also, to
5036                    // keep backwards compatibility we remove the task from recents when finishing
5037                    // task with root activity.
5038                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5039                    if (!res) {
5040                        Slog.i(TAG, "Removing task failed to finish activity");
5041                    }
5042                } else {
5043                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5044                            resultData, "app-request", true);
5045                    if (!res) {
5046                        Slog.i(TAG, "Failed to finish by app-request");
5047                    }
5048                }
5049                return res;
5050            } finally {
5051                Binder.restoreCallingIdentity(origId);
5052            }
5053        }
5054    }
5055
5056    @Override
5057    public final void finishHeavyWeightApp() {
5058        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5059                != PackageManager.PERMISSION_GRANTED) {
5060            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5061                    + Binder.getCallingPid()
5062                    + ", uid=" + Binder.getCallingUid()
5063                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5064            Slog.w(TAG, msg);
5065            throw new SecurityException(msg);
5066        }
5067
5068        synchronized(this) {
5069            if (mHeavyWeightProcess == null) {
5070                return;
5071            }
5072
5073            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5074            for (int i = 0; i < activities.size(); i++) {
5075                ActivityRecord r = activities.get(i);
5076                if (!r.finishing && r.isInStackLocked()) {
5077                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5078                            null, "finish-heavy", true);
5079                }
5080            }
5081
5082            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5083                    mHeavyWeightProcess.userId, 0));
5084            mHeavyWeightProcess = null;
5085        }
5086    }
5087
5088    @Override
5089    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5090            String message) {
5091        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5092                != PackageManager.PERMISSION_GRANTED) {
5093            String msg = "Permission Denial: crashApplication() from pid="
5094                    + Binder.getCallingPid()
5095                    + ", uid=" + Binder.getCallingUid()
5096                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5097            Slog.w(TAG, msg);
5098            throw new SecurityException(msg);
5099        }
5100
5101        synchronized(this) {
5102            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5103        }
5104    }
5105
5106    @Override
5107    public final void finishSubActivity(IBinder token, String resultWho,
5108            int requestCode) {
5109        synchronized(this) {
5110            final long origId = Binder.clearCallingIdentity();
5111            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5112            if (r != null) {
5113                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5114            }
5115            Binder.restoreCallingIdentity(origId);
5116        }
5117    }
5118
5119    @Override
5120    public boolean finishActivityAffinity(IBinder token) {
5121        synchronized(this) {
5122            final long origId = Binder.clearCallingIdentity();
5123            try {
5124                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5125                if (r == null) {
5126                    return false;
5127                }
5128
5129                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5130                // can finish.
5131                final TaskRecord task = r.getTask();
5132                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5133                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5134                    mStackSupervisor.showLockTaskToast();
5135                    return false;
5136                }
5137                return task.getStack().finishActivityAffinityLocked(r);
5138            } finally {
5139                Binder.restoreCallingIdentity(origId);
5140            }
5141        }
5142    }
5143
5144    @Override
5145    public void finishVoiceTask(IVoiceInteractionSession session) {
5146        synchronized (this) {
5147            final long origId = Binder.clearCallingIdentity();
5148            try {
5149                // TODO: VI Consider treating local voice interactions and voice tasks
5150                // differently here
5151                mStackSupervisor.finishVoiceTask(session);
5152            } finally {
5153                Binder.restoreCallingIdentity(origId);
5154            }
5155        }
5156
5157    }
5158
5159    @Override
5160    public boolean releaseActivityInstance(IBinder token) {
5161        synchronized(this) {
5162            final long origId = Binder.clearCallingIdentity();
5163            try {
5164                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5165                if (r == null) {
5166                    return false;
5167                }
5168                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5169            } finally {
5170                Binder.restoreCallingIdentity(origId);
5171            }
5172        }
5173    }
5174
5175    @Override
5176    public void releaseSomeActivities(IApplicationThread appInt) {
5177        synchronized(this) {
5178            final long origId = Binder.clearCallingIdentity();
5179            try {
5180                ProcessRecord app = getRecordForAppLocked(appInt);
5181                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5182            } finally {
5183                Binder.restoreCallingIdentity(origId);
5184            }
5185        }
5186    }
5187
5188    @Override
5189    public boolean willActivityBeVisible(IBinder token) {
5190        synchronized(this) {
5191            ActivityStack stack = ActivityRecord.getStackLocked(token);
5192            if (stack != null) {
5193                return stack.willActivityBeVisibleLocked(token);
5194            }
5195            return false;
5196        }
5197    }
5198
5199    @Override
5200    public void overridePendingTransition(IBinder token, String packageName,
5201            int enterAnim, int exitAnim) {
5202        synchronized(this) {
5203            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5204            if (self == null) {
5205                return;
5206            }
5207
5208            final long origId = Binder.clearCallingIdentity();
5209
5210            if (self.state == ActivityState.RESUMED
5211                    || self.state == ActivityState.PAUSING) {
5212                mWindowManager.overridePendingAppTransition(packageName,
5213                        enterAnim, exitAnim, null);
5214            }
5215
5216            Binder.restoreCallingIdentity(origId);
5217        }
5218    }
5219
5220    /**
5221     * Main function for removing an existing process from the activity manager
5222     * as a result of that process going away.  Clears out all connections
5223     * to the process.
5224     */
5225    private final void handleAppDiedLocked(ProcessRecord app,
5226            boolean restarting, boolean allowRestart) {
5227        int pid = app.pid;
5228        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5229                false /*replacingPid*/);
5230        if (!kept && !restarting) {
5231            removeLruProcessLocked(app);
5232            if (pid > 0) {
5233                ProcessList.remove(pid);
5234            }
5235        }
5236
5237        if (mProfileProc == app) {
5238            clearProfilerLocked();
5239        }
5240
5241        // Remove this application's activities from active lists.
5242        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5243
5244        app.activities.clear();
5245
5246        if (app.instr != null) {
5247            Slog.w(TAG, "Crash of app " + app.processName
5248                  + " running instrumentation " + app.instr.mClass);
5249            Bundle info = new Bundle();
5250            info.putString("shortMsg", "Process crashed.");
5251            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5252        }
5253
5254        mWindowManager.deferSurfaceLayout();
5255        try {
5256            if (!restarting && hasVisibleActivities
5257                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5258                // If there was nothing to resume, and we are not already restarting this process, but
5259                // there is a visible activity that is hosted by the process...  then make sure all
5260                // visible activities are running, taking care of restarting this process.
5261                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5262            }
5263        } finally {
5264            mWindowManager.continueSurfaceLayout();
5265        }
5266    }
5267
5268    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5269        final IBinder threadBinder = thread.asBinder();
5270        // Find the application record.
5271        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5272            final ProcessRecord rec = mLruProcesses.get(i);
5273            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5274                return i;
5275            }
5276        }
5277        return -1;
5278    }
5279
5280    final ProcessRecord getRecordForAppLocked(
5281            IApplicationThread thread) {
5282        if (thread == null) {
5283            return null;
5284        }
5285
5286        int appIndex = getLRURecordIndexForAppLocked(thread);
5287        if (appIndex >= 0) {
5288            return mLruProcesses.get(appIndex);
5289        }
5290
5291        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5292        // double-check that.
5293        final IBinder threadBinder = thread.asBinder();
5294        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5295        for (int i = pmap.size()-1; i >= 0; i--) {
5296            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5297            for (int j = procs.size()-1; j >= 0; j--) {
5298                final ProcessRecord proc = procs.valueAt(j);
5299                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5300                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5301                            + proc);
5302                    return proc;
5303                }
5304            }
5305        }
5306
5307        return null;
5308    }
5309
5310    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5311        // If there are no longer any background processes running,
5312        // and the app that died was not running instrumentation,
5313        // then tell everyone we are now low on memory.
5314        boolean haveBg = false;
5315        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5316            ProcessRecord rec = mLruProcesses.get(i);
5317            if (rec.thread != null
5318                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5319                haveBg = true;
5320                break;
5321            }
5322        }
5323
5324        if (!haveBg) {
5325            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5326            if (doReport) {
5327                long now = SystemClock.uptimeMillis();
5328                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5329                    doReport = false;
5330                } else {
5331                    mLastMemUsageReportTime = now;
5332                }
5333            }
5334            final ArrayList<ProcessMemInfo> memInfos
5335                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5336            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5337            long now = SystemClock.uptimeMillis();
5338            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5339                ProcessRecord rec = mLruProcesses.get(i);
5340                if (rec == dyingProc || rec.thread == null) {
5341                    continue;
5342                }
5343                if (doReport) {
5344                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5345                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5346                }
5347                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5348                    // The low memory report is overriding any current
5349                    // state for a GC request.  Make sure to do
5350                    // heavy/important/visible/foreground processes first.
5351                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5352                        rec.lastRequestedGc = 0;
5353                    } else {
5354                        rec.lastRequestedGc = rec.lastLowMemory;
5355                    }
5356                    rec.reportLowMemory = true;
5357                    rec.lastLowMemory = now;
5358                    mProcessesToGc.remove(rec);
5359                    addProcessToGcListLocked(rec);
5360                }
5361            }
5362            if (doReport) {
5363                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5364                mHandler.sendMessage(msg);
5365            }
5366            scheduleAppGcsLocked();
5367        }
5368    }
5369
5370    final void appDiedLocked(ProcessRecord app) {
5371       appDiedLocked(app, app.pid, app.thread, false);
5372    }
5373
5374    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5375            boolean fromBinderDied) {
5376        // First check if this ProcessRecord is actually active for the pid.
5377        synchronized (mPidsSelfLocked) {
5378            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5379            if (curProc != app) {
5380                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5381                return;
5382            }
5383        }
5384
5385        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5386        synchronized (stats) {
5387            stats.noteProcessDiedLocked(app.info.uid, pid);
5388        }
5389
5390        if (!app.killed) {
5391            if (!fromBinderDied) {
5392                killProcessQuiet(pid);
5393            }
5394            killProcessGroup(app.uid, pid);
5395            app.killed = true;
5396        }
5397
5398        // Clean up already done if the process has been re-started.
5399        if (app.pid == pid && app.thread != null &&
5400                app.thread.asBinder() == thread.asBinder()) {
5401            boolean doLowMem = app.instr == null;
5402            boolean doOomAdj = doLowMem;
5403            if (!app.killedByAm) {
5404                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5405                        + ") has died");
5406                mAllowLowerMemLevel = true;
5407            } else {
5408                // Note that we always want to do oom adj to update our state with the
5409                // new number of procs.
5410                mAllowLowerMemLevel = false;
5411                doLowMem = false;
5412            }
5413            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5414            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5415                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5416            handleAppDiedLocked(app, false, true);
5417
5418            if (doOomAdj) {
5419                updateOomAdjLocked();
5420            }
5421            if (doLowMem) {
5422                doLowMemReportIfNeededLocked(app);
5423            }
5424        } else if (app.pid != pid) {
5425            // A new process has already been started.
5426            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5427                    + ") has died and restarted (pid " + app.pid + ").");
5428            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5429        } else if (DEBUG_PROCESSES) {
5430            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5431                    + thread.asBinder());
5432        }
5433    }
5434
5435    /**
5436     * If a stack trace dump file is configured, dump process stack traces.
5437     * @param clearTraces causes the dump file to be erased prior to the new
5438     *    traces being written, if true; when false, the new traces will be
5439     *    appended to any existing file content.
5440     * @param firstPids of dalvik VM processes to dump stack traces for first
5441     * @param lastPids of dalvik VM processes to dump stack traces for last
5442     * @param nativePids optional list of native pids to dump stack crawls
5443     * @return file containing stack traces, or null if no dump file is configured
5444     */
5445    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5446            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5447            ArrayList<Integer> nativePids) {
5448        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5449        if (tracesPath == null || tracesPath.length() == 0) {
5450            return null;
5451        }
5452
5453        File tracesFile = new File(tracesPath);
5454        try {
5455            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5456            tracesFile.createNewFile();
5457            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5458        } catch (IOException e) {
5459            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5460            return null;
5461        }
5462
5463        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativePids);
5464        return tracesFile;
5465    }
5466
5467    public static class DumpStackFileObserver extends FileObserver {
5468        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5469        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5470        static final int TRACE_DUMP_TIMEOUT_SECONDS = TRACE_DUMP_TIMEOUT_MS / 1000;
5471
5472        private final String mTracesPath;
5473        private boolean mClosed;
5474
5475        public DumpStackFileObserver(String tracesPath) {
5476            super(tracesPath, FileObserver.CLOSE_WRITE);
5477            mTracesPath = tracesPath;
5478        }
5479
5480        @Override
5481        public synchronized void onEvent(int event, String path) {
5482            mClosed = true;
5483            notify();
5484        }
5485
5486        public void dumpWithTimeout(int pid) {
5487            sendSignal(pid, SIGNAL_QUIT);
5488            synchronized (this) {
5489                try {
5490                    wait(TRACE_DUMP_TIMEOUT_MS); // Wait for traces file to be closed.
5491                } catch (InterruptedException e) {
5492                    Slog.wtf(TAG, e);
5493                }
5494            }
5495            if (!mClosed) {
5496                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5497                       ". Attempting native stack collection.");
5498                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath, TRACE_DUMP_TIMEOUT_SECONDS);
5499            }
5500            mClosed = false;
5501        }
5502    }
5503
5504    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5505            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5506            ArrayList<Integer> nativePids) {
5507        // Use a FileObserver to detect when traces finish writing.
5508        // The order of traces is considered important to maintain for legibility.
5509        DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
5510        try {
5511            observer.startWatching();
5512
5513            // First collect all of the stacks of the most important pids.
5514            if (firstPids != null) {
5515                int num = firstPids.size();
5516                for (int i = 0; i < num; i++) {
5517                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5518                            + firstPids.get(i));
5519                    final long sime = SystemClock.elapsedRealtime();
5520                    observer.dumpWithTimeout(firstPids.get(i));
5521                    if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5522                            + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5523                }
5524            }
5525
5526            // Next collect the stacks of the native pids
5527            if (nativePids != null) {
5528                for (int pid : nativePids) {
5529                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5530                    final long sime = SystemClock.elapsedRealtime();
5531
5532                    Debug.dumpNativeBacktraceToFileTimeout(
5533                            pid, tracesPath, DumpStackFileObserver.TRACE_DUMP_TIMEOUT_SECONDS);
5534                    if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5535                            + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5536                }
5537            }
5538
5539            // Lastly, measure CPU usage.
5540            if (processCpuTracker != null) {
5541                processCpuTracker.init();
5542                System.gc();
5543                processCpuTracker.update();
5544                try {
5545                    synchronized (processCpuTracker) {
5546                        processCpuTracker.wait(500); // measure over 1/2 second.
5547                    }
5548                } catch (InterruptedException e) {
5549                }
5550                processCpuTracker.update();
5551
5552                // We'll take the stack crawls of just the top apps using CPU.
5553                final int N = processCpuTracker.countWorkingStats();
5554                int numProcs = 0;
5555                for (int i=0; i<N && numProcs<5; i++) {
5556                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5557                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5558                        numProcs++;
5559                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5560                                + stats.pid);
5561                        final long stime = SystemClock.elapsedRealtime();
5562                        observer.dumpWithTimeout(stats.pid);
5563                        if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5564                                + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5565                    } else if (DEBUG_ANR) {
5566                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5567                                + stats.pid);
5568                    }
5569                }
5570            }
5571        } finally {
5572            observer.stopWatching();
5573        }
5574    }
5575
5576    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5577        if (true || IS_USER_BUILD) {
5578            return;
5579        }
5580        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5581        if (tracesPath == null || tracesPath.length() == 0) {
5582            return;
5583        }
5584
5585        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5586        StrictMode.allowThreadDiskWrites();
5587        try {
5588            final File tracesFile = new File(tracesPath);
5589            final File tracesDir = tracesFile.getParentFile();
5590            final File tracesTmp = new File(tracesDir, "__tmp__");
5591            try {
5592                if (tracesFile.exists()) {
5593                    tracesTmp.delete();
5594                    tracesFile.renameTo(tracesTmp);
5595                }
5596                StringBuilder sb = new StringBuilder();
5597                Time tobj = new Time();
5598                tobj.set(System.currentTimeMillis());
5599                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5600                sb.append(": ");
5601                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5602                sb.append(" since ");
5603                sb.append(msg);
5604                FileOutputStream fos = new FileOutputStream(tracesFile);
5605                fos.write(sb.toString().getBytes());
5606                if (app == null) {
5607                    fos.write("\n*** No application process!".getBytes());
5608                }
5609                fos.close();
5610                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5611            } catch (IOException e) {
5612                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5613                return;
5614            }
5615
5616            if (app != null) {
5617                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5618                firstPids.add(app.pid);
5619                dumpStackTraces(tracesPath, firstPids, null, null, null);
5620            }
5621
5622            File lastTracesFile = null;
5623            File curTracesFile = null;
5624            for (int i=9; i>=0; i--) {
5625                String name = String.format(Locale.US, "slow%02d.txt", i);
5626                curTracesFile = new File(tracesDir, name);
5627                if (curTracesFile.exists()) {
5628                    if (lastTracesFile != null) {
5629                        curTracesFile.renameTo(lastTracesFile);
5630                    } else {
5631                        curTracesFile.delete();
5632                    }
5633                }
5634                lastTracesFile = curTracesFile;
5635            }
5636            tracesFile.renameTo(curTracesFile);
5637            if (tracesTmp.exists()) {
5638                tracesTmp.renameTo(tracesFile);
5639            }
5640        } finally {
5641            StrictMode.setThreadPolicy(oldPolicy);
5642        }
5643    }
5644
5645    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5646        if (!mLaunchWarningShown) {
5647            mLaunchWarningShown = true;
5648            mUiHandler.post(new Runnable() {
5649                @Override
5650                public void run() {
5651                    synchronized (ActivityManagerService.this) {
5652                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5653                        d.show();
5654                        mUiHandler.postDelayed(new Runnable() {
5655                            @Override
5656                            public void run() {
5657                                synchronized (ActivityManagerService.this) {
5658                                    d.dismiss();
5659                                    mLaunchWarningShown = false;
5660                                }
5661                            }
5662                        }, 4000);
5663                    }
5664                }
5665            });
5666        }
5667    }
5668
5669    @Override
5670    public boolean clearApplicationUserData(final String packageName,
5671            final IPackageDataObserver observer, int userId) {
5672        enforceNotIsolatedCaller("clearApplicationUserData");
5673        int uid = Binder.getCallingUid();
5674        int pid = Binder.getCallingPid();
5675        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5676                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5677
5678
5679        long callingId = Binder.clearCallingIdentity();
5680        try {
5681            IPackageManager pm = AppGlobals.getPackageManager();
5682            int pkgUid = -1;
5683            synchronized(this) {
5684                if (getPackageManagerInternalLocked().isPackageDataProtected(
5685                        userId, packageName)) {
5686                    throw new SecurityException(
5687                            "Cannot clear data for a protected package: " + packageName);
5688                }
5689
5690                try {
5691                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5692                } catch (RemoteException e) {
5693                }
5694                if (pkgUid == -1) {
5695                    Slog.w(TAG, "Invalid packageName: " + packageName);
5696                    if (observer != null) {
5697                        try {
5698                            observer.onRemoveCompleted(packageName, false);
5699                        } catch (RemoteException e) {
5700                            Slog.i(TAG, "Observer no longer exists.");
5701                        }
5702                    }
5703                    return false;
5704                }
5705                if (uid == pkgUid || checkComponentPermission(
5706                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5707                        pid, uid, -1, true)
5708                        == PackageManager.PERMISSION_GRANTED) {
5709                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5710                } else {
5711                    throw new SecurityException("PID " + pid + " does not have permission "
5712                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5713                                    + " of package " + packageName);
5714                }
5715
5716                // Remove all tasks match the cleared application package and user
5717                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5718                    final TaskRecord tr = mRecentTasks.get(i);
5719                    final String taskPackageName =
5720                            tr.getBaseIntent().getComponent().getPackageName();
5721                    if (tr.userId != userId) continue;
5722                    if (!taskPackageName.equals(packageName)) continue;
5723                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5724                }
5725            }
5726
5727            final int pkgUidF = pkgUid;
5728            final int userIdF = userId;
5729            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5730                @Override
5731                public void onRemoveCompleted(String packageName, boolean succeeded)
5732                        throws RemoteException {
5733                    synchronized (ActivityManagerService.this) {
5734                        finishForceStopPackageLocked(packageName, pkgUidF);
5735                    }
5736
5737                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5738                            Uri.fromParts("package", packageName, null));
5739                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5740                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5741                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5742                    broadcastIntentInPackage("android", SYSTEM_UID, intent,
5743                            null, null, 0, null, null, null, null, false, false, userIdF);
5744
5745                    if (observer != null) {
5746                        observer.onRemoveCompleted(packageName, succeeded);
5747                    }
5748                }
5749            };
5750
5751            try {
5752                // Clear application user data
5753                pm.clearApplicationUserData(packageName, localObserver, userId);
5754
5755                synchronized(this) {
5756                    // Remove all permissions granted from/to this package
5757                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5758                }
5759
5760                // Reset notification settings.
5761                INotificationManager inm = NotificationManager.getService();
5762                inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5763            } catch (RemoteException e) {
5764            }
5765        } finally {
5766            Binder.restoreCallingIdentity(callingId);
5767        }
5768        return true;
5769    }
5770
5771    @Override
5772    public void killBackgroundProcesses(final String packageName, int userId) {
5773        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5774                != PackageManager.PERMISSION_GRANTED &&
5775                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5776                        != PackageManager.PERMISSION_GRANTED) {
5777            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5778                    + Binder.getCallingPid()
5779                    + ", uid=" + Binder.getCallingUid()
5780                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5781            Slog.w(TAG, msg);
5782            throw new SecurityException(msg);
5783        }
5784
5785        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5786                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5787        long callingId = Binder.clearCallingIdentity();
5788        try {
5789            IPackageManager pm = AppGlobals.getPackageManager();
5790            synchronized(this) {
5791                int appId = -1;
5792                try {
5793                    appId = UserHandle.getAppId(
5794                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5795                } catch (RemoteException e) {
5796                }
5797                if (appId == -1) {
5798                    Slog.w(TAG, "Invalid packageName: " + packageName);
5799                    return;
5800                }
5801                killPackageProcessesLocked(packageName, appId, userId,
5802                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5803            }
5804        } finally {
5805            Binder.restoreCallingIdentity(callingId);
5806        }
5807    }
5808
5809    @Override
5810    public void killAllBackgroundProcesses() {
5811        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5812                != PackageManager.PERMISSION_GRANTED) {
5813            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5814                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5815                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5816            Slog.w(TAG, msg);
5817            throw new SecurityException(msg);
5818        }
5819
5820        final long callingId = Binder.clearCallingIdentity();
5821        try {
5822            synchronized (this) {
5823                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5824                final int NP = mProcessNames.getMap().size();
5825                for (int ip = 0; ip < NP; ip++) {
5826                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5827                    final int NA = apps.size();
5828                    for (int ia = 0; ia < NA; ia++) {
5829                        final ProcessRecord app = apps.valueAt(ia);
5830                        if (app.persistent) {
5831                            // We don't kill persistent processes.
5832                            continue;
5833                        }
5834                        if (app.removed) {
5835                            procs.add(app);
5836                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5837                            app.removed = true;
5838                            procs.add(app);
5839                        }
5840                    }
5841                }
5842
5843                final int N = procs.size();
5844                for (int i = 0; i < N; i++) {
5845                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5846                }
5847
5848                mAllowLowerMemLevel = true;
5849
5850                updateOomAdjLocked();
5851                doLowMemReportIfNeededLocked(null);
5852            }
5853        } finally {
5854            Binder.restoreCallingIdentity(callingId);
5855        }
5856    }
5857
5858    /**
5859     * Kills all background processes, except those matching any of the
5860     * specified properties.
5861     *
5862     * @param minTargetSdk the target SDK version at or above which to preserve
5863     *                     processes, or {@code -1} to ignore the target SDK
5864     * @param maxProcState the process state at or below which to preserve
5865     *                     processes, or {@code -1} to ignore the process state
5866     */
5867    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5868        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5869                != PackageManager.PERMISSION_GRANTED) {
5870            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5871                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5872                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5873            Slog.w(TAG, msg);
5874            throw new SecurityException(msg);
5875        }
5876
5877        final long callingId = Binder.clearCallingIdentity();
5878        try {
5879            synchronized (this) {
5880                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5881                final int NP = mProcessNames.getMap().size();
5882                for (int ip = 0; ip < NP; ip++) {
5883                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5884                    final int NA = apps.size();
5885                    for (int ia = 0; ia < NA; ia++) {
5886                        final ProcessRecord app = apps.valueAt(ia);
5887                        if (app.removed) {
5888                            procs.add(app);
5889                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5890                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5891                            app.removed = true;
5892                            procs.add(app);
5893                        }
5894                    }
5895                }
5896
5897                final int N = procs.size();
5898                for (int i = 0; i < N; i++) {
5899                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5900                }
5901            }
5902        } finally {
5903            Binder.restoreCallingIdentity(callingId);
5904        }
5905    }
5906
5907    @Override
5908    public void forceStopPackage(final String packageName, int userId) {
5909        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5910                != PackageManager.PERMISSION_GRANTED) {
5911            String msg = "Permission Denial: forceStopPackage() from pid="
5912                    + Binder.getCallingPid()
5913                    + ", uid=" + Binder.getCallingUid()
5914                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5915            Slog.w(TAG, msg);
5916            throw new SecurityException(msg);
5917        }
5918        final int callingPid = Binder.getCallingPid();
5919        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5920                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5921        long callingId = Binder.clearCallingIdentity();
5922        try {
5923            IPackageManager pm = AppGlobals.getPackageManager();
5924            synchronized(this) {
5925                int[] users = userId == UserHandle.USER_ALL
5926                        ? mUserController.getUsers() : new int[] { userId };
5927                for (int user : users) {
5928                    int pkgUid = -1;
5929                    try {
5930                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5931                                user);
5932                    } catch (RemoteException e) {
5933                    }
5934                    if (pkgUid == -1) {
5935                        Slog.w(TAG, "Invalid packageName: " + packageName);
5936                        continue;
5937                    }
5938                    try {
5939                        pm.setPackageStoppedState(packageName, true, user);
5940                    } catch (RemoteException e) {
5941                    } catch (IllegalArgumentException e) {
5942                        Slog.w(TAG, "Failed trying to unstop package "
5943                                + packageName + ": " + e);
5944                    }
5945                    if (mUserController.isUserRunningLocked(user, 0)) {
5946                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5947                        finishForceStopPackageLocked(packageName, pkgUid);
5948                    }
5949                }
5950            }
5951        } finally {
5952            Binder.restoreCallingIdentity(callingId);
5953        }
5954    }
5955
5956    @Override
5957    public void addPackageDependency(String packageName) {
5958        synchronized (this) {
5959            int callingPid = Binder.getCallingPid();
5960            if (callingPid == myPid()) {
5961                //  Yeah, um, no.
5962                return;
5963            }
5964            ProcessRecord proc;
5965            synchronized (mPidsSelfLocked) {
5966                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5967            }
5968            if (proc != null) {
5969                if (proc.pkgDeps == null) {
5970                    proc.pkgDeps = new ArraySet<String>(1);
5971                }
5972                proc.pkgDeps.add(packageName);
5973            }
5974        }
5975    }
5976
5977    /*
5978     * The pkg name and app id have to be specified.
5979     */
5980    @Override
5981    public void killApplication(String pkg, int appId, int userId, String reason) {
5982        if (pkg == null) {
5983            return;
5984        }
5985        // Make sure the uid is valid.
5986        if (appId < 0) {
5987            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5988            return;
5989        }
5990        int callerUid = Binder.getCallingUid();
5991        // Only the system server can kill an application
5992        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
5993            // Post an aysnc message to kill the application
5994            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5995            msg.arg1 = appId;
5996            msg.arg2 = userId;
5997            Bundle bundle = new Bundle();
5998            bundle.putString("pkg", pkg);
5999            bundle.putString("reason", reason);
6000            msg.obj = bundle;
6001            mHandler.sendMessage(msg);
6002        } else {
6003            throw new SecurityException(callerUid + " cannot kill pkg: " +
6004                    pkg);
6005        }
6006    }
6007
6008    @Override
6009    public void closeSystemDialogs(String reason) {
6010        enforceNotIsolatedCaller("closeSystemDialogs");
6011
6012        final int pid = Binder.getCallingPid();
6013        final int uid = Binder.getCallingUid();
6014        final long origId = Binder.clearCallingIdentity();
6015        try {
6016            synchronized (this) {
6017                // Only allow this from foreground processes, so that background
6018                // applications can't abuse it to prevent system UI from being shown.
6019                if (uid >= FIRST_APPLICATION_UID) {
6020                    ProcessRecord proc;
6021                    synchronized (mPidsSelfLocked) {
6022                        proc = mPidsSelfLocked.get(pid);
6023                    }
6024                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6025                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6026                                + " from background process " + proc);
6027                        return;
6028                    }
6029                }
6030                closeSystemDialogsLocked(reason);
6031            }
6032        } finally {
6033            Binder.restoreCallingIdentity(origId);
6034        }
6035    }
6036
6037    void closeSystemDialogsLocked(String reason) {
6038        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6039        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6040                | Intent.FLAG_RECEIVER_FOREGROUND);
6041        if (reason != null) {
6042            intent.putExtra("reason", reason);
6043        }
6044        mWindowManager.closeSystemDialogs(reason);
6045
6046        mStackSupervisor.closeSystemDialogsLocked();
6047
6048        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6049                AppOpsManager.OP_NONE, null, false, false,
6050                -1, SYSTEM_UID, UserHandle.USER_ALL);
6051    }
6052
6053    @Override
6054    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6055        enforceNotIsolatedCaller("getProcessMemoryInfo");
6056        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6057        for (int i=pids.length-1; i>=0; i--) {
6058            ProcessRecord proc;
6059            int oomAdj;
6060            synchronized (this) {
6061                synchronized (mPidsSelfLocked) {
6062                    proc = mPidsSelfLocked.get(pids[i]);
6063                    oomAdj = proc != null ? proc.setAdj : 0;
6064                }
6065            }
6066            infos[i] = new Debug.MemoryInfo();
6067            Debug.getMemoryInfo(pids[i], infos[i]);
6068            if (proc != null) {
6069                synchronized (this) {
6070                    if (proc.thread != null && proc.setAdj == oomAdj) {
6071                        // Record this for posterity if the process has been stable.
6072                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6073                                infos[i].getTotalUss(), false, proc.pkgList);
6074                    }
6075                }
6076            }
6077        }
6078        return infos;
6079    }
6080
6081    @Override
6082    public long[] getProcessPss(int[] pids) {
6083        enforceNotIsolatedCaller("getProcessPss");
6084        long[] pss = new long[pids.length];
6085        for (int i=pids.length-1; i>=0; i--) {
6086            ProcessRecord proc;
6087            int oomAdj;
6088            synchronized (this) {
6089                synchronized (mPidsSelfLocked) {
6090                    proc = mPidsSelfLocked.get(pids[i]);
6091                    oomAdj = proc != null ? proc.setAdj : 0;
6092                }
6093            }
6094            long[] tmpUss = new long[1];
6095            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6096            if (proc != null) {
6097                synchronized (this) {
6098                    if (proc.thread != null && proc.setAdj == oomAdj) {
6099                        // Record this for posterity if the process has been stable.
6100                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6101                    }
6102                }
6103            }
6104        }
6105        return pss;
6106    }
6107
6108    @Override
6109    public void killApplicationProcess(String processName, int uid) {
6110        if (processName == null) {
6111            return;
6112        }
6113
6114        int callerUid = Binder.getCallingUid();
6115        // Only the system server can kill an application
6116        if (callerUid == SYSTEM_UID) {
6117            synchronized (this) {
6118                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6119                if (app != null && app.thread != null) {
6120                    try {
6121                        app.thread.scheduleSuicide();
6122                    } catch (RemoteException e) {
6123                        // If the other end already died, then our work here is done.
6124                    }
6125                } else {
6126                    Slog.w(TAG, "Process/uid not found attempting kill of "
6127                            + processName + " / " + uid);
6128                }
6129            }
6130        } else {
6131            throw new SecurityException(callerUid + " cannot kill app process: " +
6132                    processName);
6133        }
6134    }
6135
6136    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6137        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6138                false, true, false, false, UserHandle.getUserId(uid), reason);
6139    }
6140
6141    private void finishForceStopPackageLocked(final String packageName, int uid) {
6142        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6143                Uri.fromParts("package", packageName, null));
6144        if (!mProcessesReady) {
6145            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6146                    | Intent.FLAG_RECEIVER_FOREGROUND);
6147        }
6148        intent.putExtra(Intent.EXTRA_UID, uid);
6149        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6150        broadcastIntentLocked(null, null, intent,
6151                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6152                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6153    }
6154
6155
6156    private final boolean killPackageProcessesLocked(String packageName, int appId,
6157            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6158            boolean doit, boolean evenPersistent, String reason) {
6159        ArrayList<ProcessRecord> procs = new ArrayList<>();
6160
6161        // Remove all processes this package may have touched: all with the
6162        // same UID (except for the system or root user), and all whose name
6163        // matches the package name.
6164        final int NP = mProcessNames.getMap().size();
6165        for (int ip=0; ip<NP; ip++) {
6166            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6167            final int NA = apps.size();
6168            for (int ia=0; ia<NA; ia++) {
6169                ProcessRecord app = apps.valueAt(ia);
6170                if (app.persistent && !evenPersistent) {
6171                    // we don't kill persistent processes
6172                    continue;
6173                }
6174                if (app.removed) {
6175                    if (doit) {
6176                        procs.add(app);
6177                    }
6178                    continue;
6179                }
6180
6181                // Skip process if it doesn't meet our oom adj requirement.
6182                if (app.setAdj < minOomAdj) {
6183                    continue;
6184                }
6185
6186                // If no package is specified, we call all processes under the
6187                // give user id.
6188                if (packageName == null) {
6189                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6190                        continue;
6191                    }
6192                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6193                        continue;
6194                    }
6195                // Package has been specified, we want to hit all processes
6196                // that match it.  We need to qualify this by the processes
6197                // that are running under the specified app and user ID.
6198                } else {
6199                    final boolean isDep = app.pkgDeps != null
6200                            && app.pkgDeps.contains(packageName);
6201                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6202                        continue;
6203                    }
6204                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6205                        continue;
6206                    }
6207                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6208                        continue;
6209                    }
6210                }
6211
6212                // Process has passed all conditions, kill it!
6213                if (!doit) {
6214                    return true;
6215                }
6216                app.removed = true;
6217                procs.add(app);
6218            }
6219        }
6220
6221        int N = procs.size();
6222        for (int i=0; i<N; i++) {
6223            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6224        }
6225        updateOomAdjLocked();
6226        return N > 0;
6227    }
6228
6229    private void cleanupDisabledPackageComponentsLocked(
6230            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6231
6232        Set<String> disabledClasses = null;
6233        boolean packageDisabled = false;
6234        IPackageManager pm = AppGlobals.getPackageManager();
6235
6236        if (changedClasses == null) {
6237            // Nothing changed...
6238            return;
6239        }
6240
6241        // Determine enable/disable state of the package and its components.
6242        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6243        for (int i = changedClasses.length - 1; i >= 0; i--) {
6244            final String changedClass = changedClasses[i];
6245
6246            if (changedClass.equals(packageName)) {
6247                try {
6248                    // Entire package setting changed
6249                    enabled = pm.getApplicationEnabledSetting(packageName,
6250                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6251                } catch (Exception e) {
6252                    // No such package/component; probably racing with uninstall.  In any
6253                    // event it means we have nothing further to do here.
6254                    return;
6255                }
6256                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6257                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6258                if (packageDisabled) {
6259                    // Entire package is disabled.
6260                    // No need to continue to check component states.
6261                    disabledClasses = null;
6262                    break;
6263                }
6264            } else {
6265                try {
6266                    enabled = pm.getComponentEnabledSetting(
6267                            new ComponentName(packageName, changedClass),
6268                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6269                } catch (Exception e) {
6270                    // As above, probably racing with uninstall.
6271                    return;
6272                }
6273                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6274                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6275                    if (disabledClasses == null) {
6276                        disabledClasses = new ArraySet<>(changedClasses.length);
6277                    }
6278                    disabledClasses.add(changedClass);
6279                }
6280            }
6281        }
6282
6283        if (!packageDisabled && disabledClasses == null) {
6284            // Nothing to do here...
6285            return;
6286        }
6287
6288        // Clean-up disabled activities.
6289        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6290                packageName, disabledClasses, true, false, userId) && mBooted) {
6291            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6292            mStackSupervisor.scheduleIdleLocked();
6293        }
6294
6295        // Clean-up disabled tasks
6296        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6297
6298        // Clean-up disabled services.
6299        mServices.bringDownDisabledPackageServicesLocked(
6300                packageName, disabledClasses, userId, false, killProcess, true);
6301
6302        // Clean-up disabled providers.
6303        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6304        mProviderMap.collectPackageProvidersLocked(
6305                packageName, disabledClasses, true, false, userId, providers);
6306        for (int i = providers.size() - 1; i >= 0; i--) {
6307            removeDyingProviderLocked(null, providers.get(i), true);
6308        }
6309
6310        // Clean-up disabled broadcast receivers.
6311        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6312            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6313                    packageName, disabledClasses, userId, true);
6314        }
6315
6316    }
6317
6318    final boolean clearBroadcastQueueForUserLocked(int userId) {
6319        boolean didSomething = false;
6320        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6321            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6322                    null, null, userId, true);
6323        }
6324        return didSomething;
6325    }
6326
6327    final boolean forceStopPackageLocked(String packageName, int appId,
6328            boolean callerWillRestart, boolean purgeCache, boolean doit,
6329            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6330        int i;
6331
6332        if (userId == UserHandle.USER_ALL && packageName == null) {
6333            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6334        }
6335
6336        if (appId < 0 && packageName != null) {
6337            try {
6338                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6339                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6340            } catch (RemoteException e) {
6341            }
6342        }
6343
6344        if (doit) {
6345            if (packageName != null) {
6346                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6347                        + " user=" + userId + ": " + reason);
6348            } else {
6349                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6350            }
6351
6352            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6353        }
6354
6355        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6356                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6357                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6358
6359        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6360
6361        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6362                packageName, null, doit, evenPersistent, userId)) {
6363            if (!doit) {
6364                return true;
6365            }
6366            didSomething = true;
6367        }
6368
6369        if (mServices.bringDownDisabledPackageServicesLocked(
6370                packageName, null, userId, evenPersistent, true, doit)) {
6371            if (!doit) {
6372                return true;
6373            }
6374            didSomething = true;
6375        }
6376
6377        if (packageName == null) {
6378            // Remove all sticky broadcasts from this user.
6379            mStickyBroadcasts.remove(userId);
6380        }
6381
6382        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6383        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6384                userId, providers)) {
6385            if (!doit) {
6386                return true;
6387            }
6388            didSomething = true;
6389        }
6390        for (i = providers.size() - 1; i >= 0; i--) {
6391            removeDyingProviderLocked(null, providers.get(i), true);
6392        }
6393
6394        // Remove transient permissions granted from/to this package/user
6395        removeUriPermissionsForPackageLocked(packageName, userId, false);
6396
6397        if (doit) {
6398            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6399                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6400                        packageName, null, userId, doit);
6401            }
6402        }
6403
6404        if (packageName == null || uninstalling) {
6405            // Remove pending intents.  For now we only do this when force
6406            // stopping users, because we have some problems when doing this
6407            // for packages -- app widgets are not currently cleaned up for
6408            // such packages, so they can be left with bad pending intents.
6409            if (mIntentSenderRecords.size() > 0) {
6410                Iterator<WeakReference<PendingIntentRecord>> it
6411                        = mIntentSenderRecords.values().iterator();
6412                while (it.hasNext()) {
6413                    WeakReference<PendingIntentRecord> wpir = it.next();
6414                    if (wpir == null) {
6415                        it.remove();
6416                        continue;
6417                    }
6418                    PendingIntentRecord pir = wpir.get();
6419                    if (pir == null) {
6420                        it.remove();
6421                        continue;
6422                    }
6423                    if (packageName == null) {
6424                        // Stopping user, remove all objects for the user.
6425                        if (pir.key.userId != userId) {
6426                            // Not the same user, skip it.
6427                            continue;
6428                        }
6429                    } else {
6430                        if (UserHandle.getAppId(pir.uid) != appId) {
6431                            // Different app id, skip it.
6432                            continue;
6433                        }
6434                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6435                            // Different user, skip it.
6436                            continue;
6437                        }
6438                        if (!pir.key.packageName.equals(packageName)) {
6439                            // Different package, skip it.
6440                            continue;
6441                        }
6442                    }
6443                    if (!doit) {
6444                        return true;
6445                    }
6446                    didSomething = true;
6447                    it.remove();
6448                    makeIntentSenderCanceledLocked(pir);
6449                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6450                        pir.key.activity.pendingResults.remove(pir.ref);
6451                    }
6452                }
6453            }
6454        }
6455
6456        if (doit) {
6457            if (purgeCache && packageName != null) {
6458                AttributeCache ac = AttributeCache.instance();
6459                if (ac != null) {
6460                    ac.removePackage(packageName);
6461                }
6462            }
6463            if (mBooted) {
6464                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6465                mStackSupervisor.scheduleIdleLocked();
6466            }
6467        }
6468
6469        return didSomething;
6470    }
6471
6472    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6473        return removeProcessNameLocked(name, uid, null);
6474    }
6475
6476    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6477            final ProcessRecord expecting) {
6478        ProcessRecord old = mProcessNames.get(name, uid);
6479        // Only actually remove when the currently recorded value matches the
6480        // record that we expected; if it doesn't match then we raced with a
6481        // newly created process and we don't want to destroy the new one.
6482        if ((expecting == null) || (old == expecting)) {
6483            mProcessNames.remove(name, uid);
6484        }
6485        if (old != null && old.uidRecord != null) {
6486            old.uidRecord.numProcs--;
6487            if (old.uidRecord.numProcs == 0) {
6488                // No more processes using this uid, tell clients it is gone.
6489                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6490                        "No more processes in " + old.uidRecord);
6491                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6492                mActiveUids.remove(uid);
6493                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6494            }
6495            old.uidRecord = null;
6496        }
6497        mIsolatedProcesses.remove(uid);
6498        return old;
6499    }
6500
6501    private final void addProcessNameLocked(ProcessRecord proc) {
6502        // We shouldn't already have a process under this name, but just in case we
6503        // need to clean up whatever may be there now.
6504        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6505        if (old == proc && proc.persistent) {
6506            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6507            Slog.w(TAG, "Re-adding persistent process " + proc);
6508        } else if (old != null) {
6509            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6510        }
6511        UidRecord uidRec = mActiveUids.get(proc.uid);
6512        if (uidRec == null) {
6513            uidRec = new UidRecord(proc.uid);
6514            // This is the first appearance of the uid, report it now!
6515            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6516                    "Creating new process uid: " + uidRec);
6517            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6518                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6519                uidRec.setWhitelist = uidRec.curWhitelist = true;
6520            }
6521            uidRec.updateHasInternetPermission();
6522            mActiveUids.put(proc.uid, uidRec);
6523            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6524            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6525        }
6526        proc.uidRecord = uidRec;
6527
6528        // Reset render thread tid if it was already set, so new process can set it again.
6529        proc.renderThreadTid = 0;
6530        uidRec.numProcs++;
6531        mProcessNames.put(proc.processName, proc.uid, proc);
6532        if (proc.isolated) {
6533            mIsolatedProcesses.put(proc.uid, proc);
6534        }
6535    }
6536
6537    boolean removeProcessLocked(ProcessRecord app,
6538            boolean callerWillRestart, boolean allowRestart, String reason) {
6539        final String name = app.processName;
6540        final int uid = app.uid;
6541        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6542            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6543
6544        ProcessRecord old = mProcessNames.get(name, uid);
6545        if (old != app) {
6546            // This process is no longer active, so nothing to do.
6547            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6548            return false;
6549        }
6550        removeProcessNameLocked(name, uid);
6551        if (mHeavyWeightProcess == app) {
6552            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6553                    mHeavyWeightProcess.userId, 0));
6554            mHeavyWeightProcess = null;
6555        }
6556        boolean needRestart = false;
6557        if (app.pid > 0 && app.pid != MY_PID) {
6558            int pid = app.pid;
6559            synchronized (mPidsSelfLocked) {
6560                mPidsSelfLocked.remove(pid);
6561                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6562            }
6563            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6564            if (app.isolated) {
6565                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6566                getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6567            }
6568            boolean willRestart = false;
6569            if (app.persistent && !app.isolated) {
6570                if (!callerWillRestart) {
6571                    willRestart = true;
6572                } else {
6573                    needRestart = true;
6574                }
6575            }
6576            app.kill(reason, true);
6577            handleAppDiedLocked(app, willRestart, allowRestart);
6578            if (willRestart) {
6579                removeLruProcessLocked(app);
6580                addAppLocked(app.info, null, false, null /* ABI override */);
6581            }
6582        } else {
6583            mRemovedProcesses.add(app);
6584        }
6585
6586        return needRestart;
6587    }
6588
6589    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6590        cleanupAppInLaunchingProvidersLocked(app, true);
6591        removeProcessLocked(app, false, true, "timeout publishing content providers");
6592    }
6593
6594    private final void processStartTimedOutLocked(ProcessRecord app) {
6595        final int pid = app.pid;
6596        boolean gone = false;
6597        synchronized (mPidsSelfLocked) {
6598            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6599            if (knownApp != null && knownApp.thread == null) {
6600                mPidsSelfLocked.remove(pid);
6601                gone = true;
6602            }
6603        }
6604
6605        if (gone) {
6606            Slog.w(TAG, "Process " + app + " failed to attach");
6607            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6608                    pid, app.uid, app.processName);
6609            removeProcessNameLocked(app.processName, app.uid);
6610            if (mHeavyWeightProcess == app) {
6611                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6612                        mHeavyWeightProcess.userId, 0));
6613                mHeavyWeightProcess = null;
6614            }
6615            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6616            if (app.isolated) {
6617                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6618            }
6619            // Take care of any launching providers waiting for this process.
6620            cleanupAppInLaunchingProvidersLocked(app, true);
6621            // Take care of any services that are waiting for the process.
6622            mServices.processStartTimedOutLocked(app);
6623            app.kill("start timeout", true);
6624            removeLruProcessLocked(app);
6625            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6626                Slog.w(TAG, "Unattached app died before backup, skipping");
6627                mHandler.post(new Runnable() {
6628                @Override
6629                    public void run(){
6630                        try {
6631                            IBackupManager bm = IBackupManager.Stub.asInterface(
6632                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6633                            bm.agentDisconnected(app.info.packageName);
6634                        } catch (RemoteException e) {
6635                            // Can't happen; the backup manager is local
6636                        }
6637                    }
6638                });
6639            }
6640            if (isPendingBroadcastProcessLocked(pid)) {
6641                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6642                skipPendingBroadcastLocked(pid);
6643            }
6644        } else {
6645            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6646        }
6647    }
6648
6649    private final boolean attachApplicationLocked(IApplicationThread thread,
6650            int pid) {
6651
6652        // Find the application record that is being attached...  either via
6653        // the pid if we are running in multiple processes, or just pull the
6654        // next app record if we are emulating process with anonymous threads.
6655        ProcessRecord app;
6656        long startTime = SystemClock.uptimeMillis();
6657        if (pid != MY_PID && pid >= 0) {
6658            synchronized (mPidsSelfLocked) {
6659                app = mPidsSelfLocked.get(pid);
6660            }
6661        } else {
6662            app = null;
6663        }
6664
6665        if (app == null) {
6666            Slog.w(TAG, "No pending application record for pid " + pid
6667                    + " (IApplicationThread " + thread + "); dropping process");
6668            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6669            if (pid > 0 && pid != MY_PID) {
6670                killProcessQuiet(pid);
6671                //TODO: killProcessGroup(app.info.uid, pid);
6672            } else {
6673                try {
6674                    thread.scheduleExit();
6675                } catch (Exception e) {
6676                    // Ignore exceptions.
6677                }
6678            }
6679            return false;
6680        }
6681
6682        // If this application record is still attached to a previous
6683        // process, clean it up now.
6684        if (app.thread != null) {
6685            handleAppDiedLocked(app, true, true);
6686        }
6687
6688        // Tell the process all about itself.
6689
6690        if (DEBUG_ALL) Slog.v(
6691                TAG, "Binding process pid " + pid + " to record " + app);
6692
6693        final String processName = app.processName;
6694        try {
6695            AppDeathRecipient adr = new AppDeathRecipient(
6696                    app, pid, thread);
6697            thread.asBinder().linkToDeath(adr, 0);
6698            app.deathRecipient = adr;
6699        } catch (RemoteException e) {
6700            app.resetPackageList(mProcessStats);
6701            startProcessLocked(app, "link fail", processName);
6702            return false;
6703        }
6704
6705        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6706
6707        app.makeActive(thread, mProcessStats);
6708        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6709        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6710        app.forcingToForeground = null;
6711        updateProcessForegroundLocked(app, false, false);
6712        app.hasShownUi = false;
6713        app.debugging = false;
6714        app.cached = false;
6715        app.killedByAm = false;
6716        app.killed = false;
6717
6718
6719        // We carefully use the same state that PackageManager uses for
6720        // filtering, since we use this flag to decide if we need to install
6721        // providers when user is unlocked later
6722        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6723
6724        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6725
6726        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6727        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6728
6729        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6730            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6731            msg.obj = app;
6732            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6733        }
6734
6735        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6736
6737        if (!normalMode) {
6738            Slog.i(TAG, "Launching preboot mode app: " + app);
6739        }
6740
6741        if (DEBUG_ALL) Slog.v(
6742            TAG, "New app record " + app
6743            + " thread=" + thread.asBinder() + " pid=" + pid);
6744        try {
6745            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6746            if (mDebugApp != null && mDebugApp.equals(processName)) {
6747                testMode = mWaitForDebugger
6748                    ? ApplicationThreadConstants.DEBUG_WAIT
6749                    : ApplicationThreadConstants.DEBUG_ON;
6750                app.debugging = true;
6751                if (mDebugTransient) {
6752                    mDebugApp = mOrigDebugApp;
6753                    mWaitForDebugger = mOrigWaitForDebugger;
6754                }
6755            }
6756            String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6757            ParcelFileDescriptor profileFd = null;
6758            int samplingInterval = 0;
6759            boolean profileAutoStop = false;
6760            boolean profileStreamingOutput = false;
6761            if (mProfileApp != null && mProfileApp.equals(processName)) {
6762                mProfileProc = app;
6763                profileFile = mProfileFile;
6764                profileFd = mProfileFd;
6765                samplingInterval = mSamplingInterval;
6766                profileAutoStop = mAutoStopProfiler;
6767                profileStreamingOutput = mStreamingOutput;
6768            }
6769            boolean enableTrackAllocation = false;
6770            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6771                enableTrackAllocation = true;
6772                mTrackAllocationApp = null;
6773            }
6774
6775            // If the app is being launched for restore or full backup, set it up specially
6776            boolean isRestrictedBackupMode = false;
6777            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6778                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6779                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6780                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6781                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6782            }
6783
6784            if (app.instr != null) {
6785                notifyPackageUse(app.instr.mClass.getPackageName(),
6786                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6787            }
6788            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6789                    + processName + " with config " + getGlobalConfiguration());
6790            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6791            app.compat = compatibilityInfoForPackageLocked(appInfo);
6792            if (profileFd != null) {
6793                profileFd = profileFd.dup();
6794            }
6795            ProfilerInfo profilerInfo = profileFile == null ? null
6796                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6797                                       profileStreamingOutput);
6798
6799            // We deprecated Build.SERIAL and it is not accessible to
6800            // apps that target the v2 security sandbox. Since access to
6801            // the serial is now behind a permission we push down the value.
6802            String buildSerial = Build.UNKNOWN;
6803            if (appInfo.targetSandboxVersion != 2) {
6804                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6805                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6806                        .getSerial();
6807            }
6808
6809            // Check if this is a secondary process that should be incorporated into some
6810            // currently active instrumentation.  (Note we do this AFTER all of the profiling
6811            // stuff above because profiling can currently happen only in the primary
6812            // instrumentation process.)
6813            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6814                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6815                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6816                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6817                        if (aInstr.mTargetProcesses.length == 0) {
6818                            // This is the wildcard mode, where every process brought up for
6819                            // the target instrumentation should be included.
6820                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6821                                app.instr = aInstr;
6822                                aInstr.mRunningProcesses.add(app);
6823                            }
6824                        } else {
6825                            for (String proc : aInstr.mTargetProcesses) {
6826                                if (proc.equals(app.processName)) {
6827                                    app.instr = aInstr;
6828                                    aInstr.mRunningProcesses.add(app);
6829                                    break;
6830                                }
6831                            }
6832                        }
6833                    }
6834                }
6835            }
6836
6837            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6838            if (app.instr != null) {
6839                thread.bindApplication(processName, appInfo, providers,
6840                        app.instr.mClass,
6841                        profilerInfo, app.instr.mArguments,
6842                        app.instr.mWatcher,
6843                        app.instr.mUiAutomationConnection, testMode,
6844                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6845                        isRestrictedBackupMode || !normalMode, app.persistent,
6846                        new Configuration(getGlobalConfiguration()), app.compat,
6847                        getCommonServicesLocked(app.isolated),
6848                        mCoreSettingsObserver.getCoreSettingsLocked(),
6849                        buildSerial);
6850            } else {
6851                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6852                        null, null, null, testMode,
6853                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6854                        isRestrictedBackupMode || !normalMode, app.persistent,
6855                        new Configuration(getGlobalConfiguration()), app.compat,
6856                        getCommonServicesLocked(app.isolated),
6857                        mCoreSettingsObserver.getCoreSettingsLocked(),
6858                        buildSerial);
6859            }
6860
6861            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6862            updateLruProcessLocked(app, false, null);
6863            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6864            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6865        } catch (Exception e) {
6866            // todo: Yikes!  What should we do?  For now we will try to
6867            // start another process, but that could easily get us in
6868            // an infinite loop of restarting processes...
6869            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6870
6871            app.resetPackageList(mProcessStats);
6872            app.unlinkDeathRecipient();
6873            startProcessLocked(app, "bind fail", processName);
6874            return false;
6875        }
6876
6877        // Remove this record from the list of starting applications.
6878        mPersistentStartingProcesses.remove(app);
6879        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6880                "Attach application locked removing on hold: " + app);
6881        mProcessesOnHold.remove(app);
6882
6883        boolean badApp = false;
6884        boolean didSomething = false;
6885
6886        // See if the top visible activity is waiting to run in this process...
6887        if (normalMode) {
6888            try {
6889                if (mStackSupervisor.attachApplicationLocked(app)) {
6890                    didSomething = true;
6891                }
6892            } catch (Exception e) {
6893                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6894                badApp = true;
6895            }
6896        }
6897
6898        // Find any services that should be running in this process...
6899        if (!badApp) {
6900            try {
6901                didSomething |= mServices.attachApplicationLocked(app, processName);
6902                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6903            } catch (Exception e) {
6904                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6905                badApp = true;
6906            }
6907        }
6908
6909        // Check if a next-broadcast receiver is in this process...
6910        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6911            try {
6912                didSomething |= sendPendingBroadcastsLocked(app);
6913                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6914            } catch (Exception e) {
6915                // If the app died trying to launch the receiver we declare it 'bad'
6916                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6917                badApp = true;
6918            }
6919        }
6920
6921        // Check whether the next backup agent is in this process...
6922        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6923            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6924                    "New app is backup target, launching agent for " + app);
6925            notifyPackageUse(mBackupTarget.appInfo.packageName,
6926                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6927            try {
6928                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6929                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6930                        mBackupTarget.backupMode);
6931            } catch (Exception e) {
6932                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6933                badApp = true;
6934            }
6935        }
6936
6937        if (badApp) {
6938            app.kill("error during init", true);
6939            handleAppDiedLocked(app, false, true);
6940            return false;
6941        }
6942
6943        if (!didSomething) {
6944            updateOomAdjLocked();
6945            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6946        }
6947
6948        return true;
6949    }
6950
6951    @Override
6952    public final void attachApplication(IApplicationThread thread) {
6953        synchronized (this) {
6954            int callingPid = Binder.getCallingPid();
6955            final long origId = Binder.clearCallingIdentity();
6956            attachApplicationLocked(thread, callingPid);
6957            Binder.restoreCallingIdentity(origId);
6958        }
6959    }
6960
6961    @Override
6962    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6963        final long origId = Binder.clearCallingIdentity();
6964        synchronized (this) {
6965            ActivityStack stack = ActivityRecord.getStackLocked(token);
6966            if (stack != null) {
6967                ActivityRecord r =
6968                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
6969                                false /* processPausingActivities */, config);
6970                if (stopProfiling) {
6971                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6972                        try {
6973                            mProfileFd.close();
6974                        } catch (IOException e) {
6975                        }
6976                        clearProfilerLocked();
6977                    }
6978                }
6979            }
6980        }
6981        Binder.restoreCallingIdentity(origId);
6982    }
6983
6984    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6985        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6986                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6987    }
6988
6989    void enableScreenAfterBoot() {
6990        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6991                SystemClock.uptimeMillis());
6992        mWindowManager.enableScreenAfterBoot();
6993
6994        synchronized (this) {
6995            updateEventDispatchingLocked();
6996        }
6997    }
6998
6999    @Override
7000    public void showBootMessage(final CharSequence msg, final boolean always) {
7001        if (Binder.getCallingUid() != myUid()) {
7002            throw new SecurityException();
7003        }
7004        mWindowManager.showBootMessage(msg, always);
7005    }
7006
7007    @Override
7008    public void keyguardGoingAway(int flags) {
7009        enforceNotIsolatedCaller("keyguardGoingAway");
7010        final long token = Binder.clearCallingIdentity();
7011        try {
7012            synchronized (this) {
7013                mKeyguardController.keyguardGoingAway(flags);
7014            }
7015        } finally {
7016            Binder.restoreCallingIdentity(token);
7017        }
7018    }
7019
7020    /**
7021     * @return whther the keyguard is currently locked.
7022     */
7023    boolean isKeyguardLocked() {
7024        return mKeyguardController.isKeyguardLocked();
7025    }
7026
7027    final void finishBooting() {
7028        synchronized (this) {
7029            if (!mBootAnimationComplete) {
7030                mCallFinishBooting = true;
7031                return;
7032            }
7033            mCallFinishBooting = false;
7034        }
7035
7036        ArraySet<String> completedIsas = new ArraySet<String>();
7037        for (String abi : Build.SUPPORTED_ABIS) {
7038            zygoteProcess.establishZygoteConnectionForAbi(abi);
7039            final String instructionSet = VMRuntime.getInstructionSet(abi);
7040            if (!completedIsas.contains(instructionSet)) {
7041                try {
7042                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7043                } catch (InstallerException e) {
7044                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7045                            e.getMessage() +")");
7046                }
7047                completedIsas.add(instructionSet);
7048            }
7049        }
7050
7051        IntentFilter pkgFilter = new IntentFilter();
7052        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7053        pkgFilter.addDataScheme("package");
7054        mContext.registerReceiver(new BroadcastReceiver() {
7055            @Override
7056            public void onReceive(Context context, Intent intent) {
7057                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7058                if (pkgs != null) {
7059                    for (String pkg : pkgs) {
7060                        synchronized (ActivityManagerService.this) {
7061                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7062                                    0, "query restart")) {
7063                                setResultCode(Activity.RESULT_OK);
7064                                return;
7065                            }
7066                        }
7067                    }
7068                }
7069            }
7070        }, pkgFilter);
7071
7072        IntentFilter dumpheapFilter = new IntentFilter();
7073        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7074        mContext.registerReceiver(new BroadcastReceiver() {
7075            @Override
7076            public void onReceive(Context context, Intent intent) {
7077                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7078                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7079                } else {
7080                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7081                }
7082            }
7083        }, dumpheapFilter);
7084
7085        // Let system services know.
7086        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7087
7088        synchronized (this) {
7089            // Ensure that any processes we had put on hold are now started
7090            // up.
7091            final int NP = mProcessesOnHold.size();
7092            if (NP > 0) {
7093                ArrayList<ProcessRecord> procs =
7094                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7095                for (int ip=0; ip<NP; ip++) {
7096                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7097                            + procs.get(ip));
7098                    startProcessLocked(procs.get(ip), "on-hold", null);
7099                }
7100            }
7101
7102            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7103                // Start looking for apps that are abusing wake locks.
7104                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7105                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7106                // Tell anyone interested that we are done booting!
7107                SystemProperties.set("sys.boot_completed", "1");
7108
7109                // And trigger dev.bootcomplete if we are not showing encryption progress
7110                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7111                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7112                    SystemProperties.set("dev.bootcomplete", "1");
7113                }
7114                mUserController.sendBootCompletedLocked(
7115                        new IIntentReceiver.Stub() {
7116                            @Override
7117                            public void performReceive(Intent intent, int resultCode,
7118                                    String data, Bundle extras, boolean ordered,
7119                                    boolean sticky, int sendingUser) {
7120                                synchronized (ActivityManagerService.this) {
7121                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7122                                            true, false);
7123                                }
7124                            }
7125                        });
7126                scheduleStartProfilesLocked();
7127            }
7128        }
7129    }
7130
7131    @Override
7132    public void bootAnimationComplete() {
7133        final boolean callFinishBooting;
7134        synchronized (this) {
7135            callFinishBooting = mCallFinishBooting;
7136            mBootAnimationComplete = true;
7137        }
7138        if (callFinishBooting) {
7139            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7140            finishBooting();
7141            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7142        }
7143    }
7144
7145    final void ensureBootCompleted() {
7146        boolean booting;
7147        boolean enableScreen;
7148        synchronized (this) {
7149            booting = mBooting;
7150            mBooting = false;
7151            enableScreen = !mBooted;
7152            mBooted = true;
7153        }
7154
7155        if (booting) {
7156            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7157            finishBooting();
7158            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7159        }
7160
7161        if (enableScreen) {
7162            enableScreenAfterBoot();
7163        }
7164    }
7165
7166    @Override
7167    public final void activityResumed(IBinder token) {
7168        final long origId = Binder.clearCallingIdentity();
7169        synchronized(this) {
7170            ActivityRecord.activityResumedLocked(token);
7171            mWindowManager.notifyAppResumedFinished(token);
7172        }
7173        Binder.restoreCallingIdentity(origId);
7174    }
7175
7176    @Override
7177    public final void activityPaused(IBinder token) {
7178        final long origId = Binder.clearCallingIdentity();
7179        synchronized(this) {
7180            ActivityStack stack = ActivityRecord.getStackLocked(token);
7181            if (stack != null) {
7182                stack.activityPausedLocked(token, false);
7183            }
7184        }
7185        Binder.restoreCallingIdentity(origId);
7186    }
7187
7188    @Override
7189    public final void activityStopped(IBinder token, Bundle icicle,
7190            PersistableBundle persistentState, CharSequence description) {
7191        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7192
7193        // Refuse possible leaked file descriptors
7194        if (icicle != null && icicle.hasFileDescriptors()) {
7195            throw new IllegalArgumentException("File descriptors passed in Bundle");
7196        }
7197
7198        final long origId = Binder.clearCallingIdentity();
7199
7200        synchronized (this) {
7201            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7202            if (r != null) {
7203                r.activityStoppedLocked(icicle, persistentState, description);
7204            }
7205        }
7206
7207        trimApplications();
7208
7209        Binder.restoreCallingIdentity(origId);
7210    }
7211
7212    @Override
7213    public final void activityDestroyed(IBinder token) {
7214        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7215        synchronized (this) {
7216            ActivityStack stack = ActivityRecord.getStackLocked(token);
7217            if (stack != null) {
7218                stack.activityDestroyedLocked(token, "activityDestroyed");
7219            }
7220        }
7221    }
7222
7223    @Override
7224    public final void activityRelaunched(IBinder token) {
7225        final long origId = Binder.clearCallingIdentity();
7226        synchronized (this) {
7227            mStackSupervisor.activityRelaunchedLocked(token);
7228        }
7229        Binder.restoreCallingIdentity(origId);
7230    }
7231
7232    @Override
7233    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7234            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7235        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7236                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7237        synchronized (this) {
7238            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7239            if (record == null) {
7240                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7241                        + "found for: " + token);
7242            }
7243            record.setSizeConfigurations(horizontalSizeConfiguration,
7244                    verticalSizeConfigurations, smallestSizeConfigurations);
7245        }
7246    }
7247
7248    @Override
7249    public final void backgroundResourcesReleased(IBinder token) {
7250        final long origId = Binder.clearCallingIdentity();
7251        try {
7252            synchronized (this) {
7253                ActivityStack stack = ActivityRecord.getStackLocked(token);
7254                if (stack != null) {
7255                    stack.backgroundResourcesReleased();
7256                }
7257            }
7258        } finally {
7259            Binder.restoreCallingIdentity(origId);
7260        }
7261    }
7262
7263    @Override
7264    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7265        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7266    }
7267
7268    @Override
7269    public final void notifyEnterAnimationComplete(IBinder token) {
7270        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7271    }
7272
7273    @Override
7274    public String getCallingPackage(IBinder token) {
7275        synchronized (this) {
7276            ActivityRecord r = getCallingRecordLocked(token);
7277            return r != null ? r.info.packageName : null;
7278        }
7279    }
7280
7281    @Override
7282    public ComponentName getCallingActivity(IBinder token) {
7283        synchronized (this) {
7284            ActivityRecord r = getCallingRecordLocked(token);
7285            return r != null ? r.intent.getComponent() : null;
7286        }
7287    }
7288
7289    private ActivityRecord getCallingRecordLocked(IBinder token) {
7290        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7291        if (r == null) {
7292            return null;
7293        }
7294        return r.resultTo;
7295    }
7296
7297    @Override
7298    public ComponentName getActivityClassForToken(IBinder token) {
7299        synchronized(this) {
7300            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7301            if (r == null) {
7302                return null;
7303            }
7304            return r.intent.getComponent();
7305        }
7306    }
7307
7308    @Override
7309    public String getPackageForToken(IBinder token) {
7310        synchronized(this) {
7311            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7312            if (r == null) {
7313                return null;
7314            }
7315            return r.packageName;
7316        }
7317    }
7318
7319    @Override
7320    public boolean isRootVoiceInteraction(IBinder token) {
7321        synchronized(this) {
7322            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7323            if (r == null) {
7324                return false;
7325            }
7326            return r.rootVoiceInteraction;
7327        }
7328    }
7329
7330    @Override
7331    public IIntentSender getIntentSender(int type,
7332            String packageName, IBinder token, String resultWho,
7333            int requestCode, Intent[] intents, String[] resolvedTypes,
7334            int flags, Bundle bOptions, int userId) {
7335        enforceNotIsolatedCaller("getIntentSender");
7336        // Refuse possible leaked file descriptors
7337        if (intents != null) {
7338            if (intents.length < 1) {
7339                throw new IllegalArgumentException("Intents array length must be >= 1");
7340            }
7341            for (int i=0; i<intents.length; i++) {
7342                Intent intent = intents[i];
7343                if (intent != null) {
7344                    if (intent.hasFileDescriptors()) {
7345                        throw new IllegalArgumentException("File descriptors passed in Intent");
7346                    }
7347                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7348                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7349                        throw new IllegalArgumentException(
7350                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7351                    }
7352                    intents[i] = new Intent(intent);
7353                }
7354            }
7355            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7356                throw new IllegalArgumentException(
7357                        "Intent array length does not match resolvedTypes length");
7358            }
7359        }
7360        if (bOptions != null) {
7361            if (bOptions.hasFileDescriptors()) {
7362                throw new IllegalArgumentException("File descriptors passed in options");
7363            }
7364        }
7365
7366        synchronized(this) {
7367            int callingUid = Binder.getCallingUid();
7368            int origUserId = userId;
7369            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7370                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7371                    ALLOW_NON_FULL, "getIntentSender", null);
7372            if (origUserId == UserHandle.USER_CURRENT) {
7373                // We don't want to evaluate this until the pending intent is
7374                // actually executed.  However, we do want to always do the
7375                // security checking for it above.
7376                userId = UserHandle.USER_CURRENT;
7377            }
7378            try {
7379                if (callingUid != 0 && callingUid != SYSTEM_UID) {
7380                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7381                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7382                    if (!UserHandle.isSameApp(callingUid, uid)) {
7383                        String msg = "Permission Denial: getIntentSender() from pid="
7384                            + Binder.getCallingPid()
7385                            + ", uid=" + Binder.getCallingUid()
7386                            + ", (need uid=" + uid + ")"
7387                            + " is not allowed to send as package " + packageName;
7388                        Slog.w(TAG, msg);
7389                        throw new SecurityException(msg);
7390                    }
7391                }
7392
7393                return getIntentSenderLocked(type, packageName, callingUid, userId,
7394                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7395
7396            } catch (RemoteException e) {
7397                throw new SecurityException(e);
7398            }
7399        }
7400    }
7401
7402    IIntentSender getIntentSenderLocked(int type, String packageName,
7403            int callingUid, int userId, IBinder token, String resultWho,
7404            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7405            Bundle bOptions) {
7406        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7407        ActivityRecord activity = null;
7408        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7409            activity = ActivityRecord.isInStackLocked(token);
7410            if (activity == null) {
7411                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7412                return null;
7413            }
7414            if (activity.finishing) {
7415                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7416                return null;
7417            }
7418        }
7419
7420        // We're going to be splicing together extras before sending, so we're
7421        // okay poking into any contained extras.
7422        if (intents != null) {
7423            for (int i = 0; i < intents.length; i++) {
7424                intents[i].setDefusable(true);
7425            }
7426        }
7427        Bundle.setDefusable(bOptions, true);
7428
7429        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7430        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7431        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7432        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7433                |PendingIntent.FLAG_UPDATE_CURRENT);
7434
7435        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7436                type, packageName, activity, resultWho,
7437                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7438        WeakReference<PendingIntentRecord> ref;
7439        ref = mIntentSenderRecords.get(key);
7440        PendingIntentRecord rec = ref != null ? ref.get() : null;
7441        if (rec != null) {
7442            if (!cancelCurrent) {
7443                if (updateCurrent) {
7444                    if (rec.key.requestIntent != null) {
7445                        rec.key.requestIntent.replaceExtras(intents != null ?
7446                                intents[intents.length - 1] : null);
7447                    }
7448                    if (intents != null) {
7449                        intents[intents.length-1] = rec.key.requestIntent;
7450                        rec.key.allIntents = intents;
7451                        rec.key.allResolvedTypes = resolvedTypes;
7452                    } else {
7453                        rec.key.allIntents = null;
7454                        rec.key.allResolvedTypes = null;
7455                    }
7456                }
7457                return rec;
7458            }
7459            makeIntentSenderCanceledLocked(rec);
7460            mIntentSenderRecords.remove(key);
7461        }
7462        if (noCreate) {
7463            return rec;
7464        }
7465        rec = new PendingIntentRecord(this, key, callingUid);
7466        mIntentSenderRecords.put(key, rec.ref);
7467        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7468            if (activity.pendingResults == null) {
7469                activity.pendingResults
7470                        = new HashSet<WeakReference<PendingIntentRecord>>();
7471            }
7472            activity.pendingResults.add(rec.ref);
7473        }
7474        return rec;
7475    }
7476
7477    @Override
7478    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7479            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7480        if (target instanceof PendingIntentRecord) {
7481            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7482                    finishedReceiver, requiredPermission, options);
7483        } else {
7484            if (intent == null) {
7485                // Weird case: someone has given us their own custom IIntentSender, and now
7486                // they have someone else trying to send to it but of course this isn't
7487                // really a PendingIntent, so there is no base Intent, and the caller isn't
7488                // supplying an Intent... but we never want to dispatch a null Intent to
7489                // a receiver, so um...  let's make something up.
7490                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7491                intent = new Intent(Intent.ACTION_MAIN);
7492            }
7493            try {
7494                target.send(code, intent, resolvedType, null, requiredPermission, options);
7495            } catch (RemoteException e) {
7496            }
7497            // Platform code can rely on getting a result back when the send is done, but if
7498            // this intent sender is from outside of the system we can't rely on it doing that.
7499            // So instead we don't give it the result receiver, and instead just directly
7500            // report the finish immediately.
7501            if (finishedReceiver != null) {
7502                try {
7503                    finishedReceiver.performReceive(intent, 0,
7504                            null, null, false, false, UserHandle.getCallingUserId());
7505                } catch (RemoteException e) {
7506                }
7507            }
7508            return 0;
7509        }
7510    }
7511
7512    @Override
7513    public void cancelIntentSender(IIntentSender sender) {
7514        if (!(sender instanceof PendingIntentRecord)) {
7515            return;
7516        }
7517        synchronized(this) {
7518            PendingIntentRecord rec = (PendingIntentRecord)sender;
7519            try {
7520                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7521                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7522                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7523                    String msg = "Permission Denial: cancelIntentSender() from pid="
7524                        + Binder.getCallingPid()
7525                        + ", uid=" + Binder.getCallingUid()
7526                        + " is not allowed to cancel package "
7527                        + rec.key.packageName;
7528                    Slog.w(TAG, msg);
7529                    throw new SecurityException(msg);
7530                }
7531            } catch (RemoteException e) {
7532                throw new SecurityException(e);
7533            }
7534            cancelIntentSenderLocked(rec, true);
7535        }
7536    }
7537
7538    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7539        makeIntentSenderCanceledLocked(rec);
7540        mIntentSenderRecords.remove(rec.key);
7541        if (cleanActivity && rec.key.activity != null) {
7542            rec.key.activity.pendingResults.remove(rec.ref);
7543        }
7544    }
7545
7546    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7547        rec.canceled = true;
7548        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7549        if (callbacks != null) {
7550            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7551        }
7552    }
7553
7554    @Override
7555    public String getPackageForIntentSender(IIntentSender pendingResult) {
7556        if (!(pendingResult instanceof PendingIntentRecord)) {
7557            return null;
7558        }
7559        try {
7560            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7561            return res.key.packageName;
7562        } catch (ClassCastException e) {
7563        }
7564        return null;
7565    }
7566
7567    @Override
7568    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7569        if (!(sender instanceof PendingIntentRecord)) {
7570            return;
7571        }
7572        synchronized(this) {
7573            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7574        }
7575    }
7576
7577    @Override
7578    public void unregisterIntentSenderCancelListener(IIntentSender sender,
7579            IResultReceiver receiver) {
7580        if (!(sender instanceof PendingIntentRecord)) {
7581            return;
7582        }
7583        synchronized(this) {
7584            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7585        }
7586    }
7587
7588    @Override
7589    public int getUidForIntentSender(IIntentSender sender) {
7590        if (sender instanceof PendingIntentRecord) {
7591            try {
7592                PendingIntentRecord res = (PendingIntentRecord)sender;
7593                return res.uid;
7594            } catch (ClassCastException e) {
7595            }
7596        }
7597        return -1;
7598    }
7599
7600    @Override
7601    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7602        if (!(pendingResult instanceof PendingIntentRecord)) {
7603            return false;
7604        }
7605        try {
7606            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7607            if (res.key.allIntents == null) {
7608                return false;
7609            }
7610            for (int i=0; i<res.key.allIntents.length; i++) {
7611                Intent intent = res.key.allIntents[i];
7612                if (intent.getPackage() != null && intent.getComponent() != null) {
7613                    return false;
7614                }
7615            }
7616            return true;
7617        } catch (ClassCastException e) {
7618        }
7619        return false;
7620    }
7621
7622    @Override
7623    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7624        if (!(pendingResult instanceof PendingIntentRecord)) {
7625            return false;
7626        }
7627        try {
7628            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7629            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7630                return true;
7631            }
7632            return false;
7633        } catch (ClassCastException e) {
7634        }
7635        return false;
7636    }
7637
7638    @Override
7639    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7640        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7641                "getIntentForIntentSender()");
7642        if (!(pendingResult instanceof PendingIntentRecord)) {
7643            return null;
7644        }
7645        try {
7646            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7647            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7648        } catch (ClassCastException e) {
7649        }
7650        return null;
7651    }
7652
7653    @Override
7654    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7655        if (!(pendingResult instanceof PendingIntentRecord)) {
7656            return null;
7657        }
7658        try {
7659            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7660            synchronized (this) {
7661                return getTagForIntentSenderLocked(res, prefix);
7662            }
7663        } catch (ClassCastException e) {
7664        }
7665        return null;
7666    }
7667
7668    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7669        final Intent intent = res.key.requestIntent;
7670        if (intent != null) {
7671            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7672                    || res.lastTagPrefix.equals(prefix))) {
7673                return res.lastTag;
7674            }
7675            res.lastTagPrefix = prefix;
7676            final StringBuilder sb = new StringBuilder(128);
7677            if (prefix != null) {
7678                sb.append(prefix);
7679            }
7680            if (intent.getAction() != null) {
7681                sb.append(intent.getAction());
7682            } else if (intent.getComponent() != null) {
7683                intent.getComponent().appendShortString(sb);
7684            } else {
7685                sb.append("?");
7686            }
7687            return res.lastTag = sb.toString();
7688        }
7689        return null;
7690    }
7691
7692    @Override
7693    public void setProcessLimit(int max) {
7694        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7695                "setProcessLimit()");
7696        synchronized (this) {
7697            mConstants.setOverrideMaxCachedProcesses(max);
7698        }
7699        trimApplications();
7700    }
7701
7702    @Override
7703    public int getProcessLimit() {
7704        synchronized (this) {
7705            return mConstants.getOverrideMaxCachedProcesses();
7706        }
7707    }
7708
7709    void foregroundTokenDied(ForegroundToken token) {
7710        synchronized (ActivityManagerService.this) {
7711            synchronized (mPidsSelfLocked) {
7712                ForegroundToken cur
7713                    = mForegroundProcesses.get(token.pid);
7714                if (cur != token) {
7715                    return;
7716                }
7717                mForegroundProcesses.remove(token.pid);
7718                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7719                if (pr == null) {
7720                    return;
7721                }
7722                pr.forcingToForeground = null;
7723                updateProcessForegroundLocked(pr, false, false);
7724            }
7725            updateOomAdjLocked();
7726        }
7727    }
7728
7729    @Override
7730    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7731        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7732                "setProcessForeground()");
7733        synchronized(this) {
7734            boolean changed = false;
7735
7736            synchronized (mPidsSelfLocked) {
7737                ProcessRecord pr = mPidsSelfLocked.get(pid);
7738                if (pr == null && isForeground) {
7739                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7740                    return;
7741                }
7742                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7743                if (oldToken != null) {
7744                    oldToken.token.unlinkToDeath(oldToken, 0);
7745                    mForegroundProcesses.remove(pid);
7746                    if (pr != null) {
7747                        pr.forcingToForeground = null;
7748                    }
7749                    changed = true;
7750                }
7751                if (isForeground && token != null) {
7752                    ForegroundToken newToken = new ForegroundToken() {
7753                        @Override
7754                        public void binderDied() {
7755                            foregroundTokenDied(this);
7756                        }
7757                    };
7758                    newToken.pid = pid;
7759                    newToken.token = token;
7760                    try {
7761                        token.linkToDeath(newToken, 0);
7762                        mForegroundProcesses.put(pid, newToken);
7763                        pr.forcingToForeground = token;
7764                        changed = true;
7765                    } catch (RemoteException e) {
7766                        // If the process died while doing this, we will later
7767                        // do the cleanup with the process death link.
7768                    }
7769                }
7770            }
7771
7772            if (changed) {
7773                updateOomAdjLocked();
7774            }
7775        }
7776    }
7777
7778    @Override
7779    public boolean isAppForeground(int uid) throws RemoteException {
7780        synchronized (this) {
7781            UidRecord uidRec = mActiveUids.get(uid);
7782            if (uidRec == null || uidRec.idle) {
7783                return false;
7784            }
7785            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7786        }
7787    }
7788
7789    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7790    // be guarded by permission checking.
7791    int getUidState(int uid) {
7792        synchronized (this) {
7793            UidRecord uidRec = mActiveUids.get(uid);
7794            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7795        }
7796    }
7797
7798    @Override
7799    public boolean isInMultiWindowMode(IBinder token) {
7800        final long origId = Binder.clearCallingIdentity();
7801        try {
7802            synchronized(this) {
7803                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7804                if (r == null) {
7805                    return false;
7806                }
7807                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7808                return !r.getTask().mFullscreen;
7809            }
7810        } finally {
7811            Binder.restoreCallingIdentity(origId);
7812        }
7813    }
7814
7815    @Override
7816    public boolean isInPictureInPictureMode(IBinder token) {
7817        final long origId = Binder.clearCallingIdentity();
7818        try {
7819            synchronized(this) {
7820                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7821                if (stack == null) {
7822                    return false;
7823                }
7824                return stack.mStackId == PINNED_STACK_ID;
7825            }
7826        } finally {
7827            Binder.restoreCallingIdentity(origId);
7828        }
7829    }
7830
7831    @Override
7832    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureArgs args) {
7833        final long origId = Binder.clearCallingIdentity();
7834        try {
7835            synchronized(this) {
7836                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7837                        "enterPictureInPictureMode", token, args);
7838
7839                // Activity supports picture-in-picture, now check that we can enter PiP at this
7840                // point, if it is
7841                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7842                        false /* noThrow */, false /* beforeStopping */)) {
7843                    return false;
7844                }
7845
7846                final Runnable enterPipRunnable = () -> {
7847                    // Only update the saved args from the args that are set
7848                    r.pictureInPictureArgs.copyOnlySet(args);
7849                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
7850                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
7851                    // Adjust the source bounds by the insets for the transition down
7852                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
7853                    final Rect insets = r.pictureInPictureArgs.getSourceRectHintInsets();
7854                    if (insets != null) {
7855                        sourceBounds.offsetTo(Math.max(0, sourceBounds.left - insets.left),
7856                                Math.max(0, sourceBounds.top - insets.top));
7857                    }
7858
7859                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
7860                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
7861                    final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
7862                    stack.setPictureInPictureAspectRatio(aspectRatio);
7863                    stack.setPictureInPictureActions(actions);
7864
7865                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
7866                            r.supportsPictureInPictureWhilePausing);
7867                    logPictureInPictureArgs(args);
7868                };
7869
7870                if (isKeyguardLocked()) {
7871                    // If the keyguard is showing or occluded, then try and dismiss it before
7872                    // entering picture-in-picture (this will prompt the user to authenticate if the
7873                    // device is currently locked).
7874                    try {
7875                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7876                            @Override
7877                            public void onDismissError() throws RemoteException {
7878                                // Do nothing
7879                            }
7880
7881                            @Override
7882                            public void onDismissSucceeded() throws RemoteException {
7883                                mHandler.post(enterPipRunnable);
7884                            }
7885
7886                            @Override
7887                            public void onDismissCancelled() throws RemoteException {
7888                                // Do nothing
7889                            }
7890                        });
7891                    } catch (RemoteException e) {
7892                        // Local call
7893                    }
7894                } else {
7895                    // Enter picture in picture immediately otherwise
7896                    enterPipRunnable.run();
7897                }
7898                return true;
7899            }
7900        } finally {
7901            Binder.restoreCallingIdentity(origId);
7902        }
7903    }
7904
7905    @Override
7906    public void setPictureInPictureArgs(IBinder token, final PictureInPictureArgs args) {
7907        final long origId = Binder.clearCallingIdentity();
7908        try {
7909            synchronized(this) {
7910                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7911                        "setPictureInPictureArgs", token, args);
7912
7913                // Only update the saved args from the args that are set
7914                r.pictureInPictureArgs.copyOnlySet(args);
7915                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7916                    // If the activity is already in picture-in-picture, update the pinned stack now
7917                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
7918                    // be used the next time the activity enters PiP
7919                    final PinnedActivityStack stack = r.getStack();
7920                    if (!stack.isAnimatingBoundsToFullscreen()) {
7921                        stack.setPictureInPictureAspectRatio(
7922                                r.pictureInPictureArgs.getAspectRatio());
7923                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
7924                    }
7925                }
7926                logPictureInPictureArgs(args);
7927            }
7928        } finally {
7929            Binder.restoreCallingIdentity(origId);
7930        }
7931    }
7932
7933    private void logPictureInPictureArgs(PictureInPictureArgs args) {
7934        if (args.hasSetActions()) {
7935            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
7936                    args.getActions().size());
7937        }
7938        if (args.hasSetAspectRatio()) {
7939            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
7940            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, args.getAspectRatio());
7941            MetricsLogger.action(lm);
7942        }
7943    }
7944
7945    /**
7946     * Checks the state of the system and the activity associated with the given {@param token} to
7947     * verify that picture-in-picture is supported for that activity.
7948     *
7949     * @return the activity record for the given {@param token} if all the checks pass.
7950     */
7951    private ActivityRecord ensureValidPictureInPictureActivityArgsLocked(String caller,
7952            IBinder token, PictureInPictureArgs args) {
7953        if (!mSupportsPictureInPicture) {
7954            throw new IllegalStateException(caller
7955                    + ": Device doesn't support picture-in-picture mode.");
7956        }
7957
7958        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7959        if (r == null) {
7960            throw new IllegalStateException(caller
7961                    + ": Can't find activity for token=" + token);
7962        }
7963
7964        if (!r.supportsPictureInPicture()) {
7965            throw new IllegalStateException(caller
7966                    + ": Current activity does not support picture-in-picture.");
7967        }
7968
7969        if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
7970            throw new IllegalStateException(caller
7971                    + ": Activities on the home, assistant, or recents stack not supported");
7972        }
7973
7974        if (args.hasSetAspectRatio()
7975                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
7976                        args.getAspectRatio())) {
7977            final float minAspectRatio = mContext.getResources().getFloat(
7978                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
7979            final float maxAspectRatio = mContext.getResources().getFloat(
7980                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
7981            throw new IllegalArgumentException(String.format(caller
7982                    + ": Aspect ratio is too extreme (must be between %f and %f).",
7983                            minAspectRatio, maxAspectRatio));
7984        }
7985
7986        if (args.hasSetActions()
7987                && args.getActions().size() > ActivityManager.getMaxNumPictureInPictureActions()) {
7988            throw new IllegalArgumentException(String.format(caller + ": Invalid number of"
7989                    + "picture-in-picture actions.  Only a maximum of %d actions allowed",
7990                            ActivityManager.getMaxNumPictureInPictureActions()));
7991        }
7992
7993        return r;
7994    }
7995
7996    // =========================================================
7997    // PROCESS INFO
7998    // =========================================================
7999
8000    static class ProcessInfoService extends IProcessInfoService.Stub {
8001        final ActivityManagerService mActivityManagerService;
8002        ProcessInfoService(ActivityManagerService activityManagerService) {
8003            mActivityManagerService = activityManagerService;
8004        }
8005
8006        @Override
8007        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8008            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8009                    /*in*/ pids, /*out*/ states, null);
8010        }
8011
8012        @Override
8013        public void getProcessStatesAndOomScoresFromPids(
8014                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8015            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8016                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8017        }
8018    }
8019
8020    /**
8021     * For each PID in the given input array, write the current process state
8022     * for that process into the states array, or -1 to indicate that no
8023     * process with the given PID exists. If scores array is provided, write
8024     * the oom score for the process into the scores array, with INVALID_ADJ
8025     * indicating the PID doesn't exist.
8026     */
8027    public void getProcessStatesAndOomScoresForPIDs(
8028            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8029        if (scores != null) {
8030            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8031                    "getProcessStatesAndOomScoresForPIDs()");
8032        }
8033
8034        if (pids == null) {
8035            throw new NullPointerException("pids");
8036        } else if (states == null) {
8037            throw new NullPointerException("states");
8038        } else if (pids.length != states.length) {
8039            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8040        } else if (scores != null && pids.length != scores.length) {
8041            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8042        }
8043
8044        synchronized (mPidsSelfLocked) {
8045            for (int i = 0; i < pids.length; i++) {
8046                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8047                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8048                        pr.curProcState;
8049                if (scores != null) {
8050                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8051                }
8052            }
8053        }
8054    }
8055
8056    // =========================================================
8057    // PERMISSIONS
8058    // =========================================================
8059
8060    static class PermissionController extends IPermissionController.Stub {
8061        ActivityManagerService mActivityManagerService;
8062        PermissionController(ActivityManagerService activityManagerService) {
8063            mActivityManagerService = activityManagerService;
8064        }
8065
8066        @Override
8067        public boolean checkPermission(String permission, int pid, int uid) {
8068            return mActivityManagerService.checkPermission(permission, pid,
8069                    uid) == PackageManager.PERMISSION_GRANTED;
8070        }
8071
8072        @Override
8073        public String[] getPackagesForUid(int uid) {
8074            return mActivityManagerService.mContext.getPackageManager()
8075                    .getPackagesForUid(uid);
8076        }
8077
8078        @Override
8079        public boolean isRuntimePermission(String permission) {
8080            try {
8081                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8082                        .getPermissionInfo(permission, 0);
8083                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8084                        == PermissionInfo.PROTECTION_DANGEROUS;
8085            } catch (NameNotFoundException nnfe) {
8086                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8087            }
8088            return false;
8089        }
8090    }
8091
8092    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8093        @Override
8094        public int checkComponentPermission(String permission, int pid, int uid,
8095                int owningUid, boolean exported) {
8096            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8097                    owningUid, exported);
8098        }
8099
8100        @Override
8101        public Object getAMSLock() {
8102            return ActivityManagerService.this;
8103        }
8104    }
8105
8106    /**
8107     * This can be called with or without the global lock held.
8108     */
8109    int checkComponentPermission(String permission, int pid, int uid,
8110            int owningUid, boolean exported) {
8111        if (pid == MY_PID) {
8112            return PackageManager.PERMISSION_GRANTED;
8113        }
8114        return ActivityManager.checkComponentPermission(permission, uid,
8115                owningUid, exported);
8116    }
8117
8118    /**
8119     * As the only public entry point for permissions checking, this method
8120     * can enforce the semantic that requesting a check on a null global
8121     * permission is automatically denied.  (Internally a null permission
8122     * string is used when calling {@link #checkComponentPermission} in cases
8123     * when only uid-based security is needed.)
8124     *
8125     * This can be called with or without the global lock held.
8126     */
8127    @Override
8128    public int checkPermission(String permission, int pid, int uid) {
8129        if (permission == null) {
8130            return PackageManager.PERMISSION_DENIED;
8131        }
8132        return checkComponentPermission(permission, pid, uid, -1, true);
8133    }
8134
8135    @Override
8136    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8137        if (permission == null) {
8138            return PackageManager.PERMISSION_DENIED;
8139        }
8140
8141        // We might be performing an operation on behalf of an indirect binder
8142        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8143        // client identity accordingly before proceeding.
8144        Identity tlsIdentity = sCallerIdentity.get();
8145        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8146            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8147                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8148            uid = tlsIdentity.uid;
8149            pid = tlsIdentity.pid;
8150        }
8151
8152        return checkComponentPermission(permission, pid, uid, -1, true);
8153    }
8154
8155    /**
8156     * Binder IPC calls go through the public entry point.
8157     * This can be called with or without the global lock held.
8158     */
8159    int checkCallingPermission(String permission) {
8160        return checkPermission(permission,
8161                Binder.getCallingPid(),
8162                UserHandle.getAppId(Binder.getCallingUid()));
8163    }
8164
8165    /**
8166     * This can be called with or without the global lock held.
8167     */
8168    void enforceCallingPermission(String permission, String func) {
8169        if (checkCallingPermission(permission)
8170                == PackageManager.PERMISSION_GRANTED) {
8171            return;
8172        }
8173
8174        String msg = "Permission Denial: " + func + " from pid="
8175                + Binder.getCallingPid()
8176                + ", uid=" + Binder.getCallingUid()
8177                + " requires " + permission;
8178        Slog.w(TAG, msg);
8179        throw new SecurityException(msg);
8180    }
8181
8182    /**
8183     * Determine if UID is holding permissions required to access {@link Uri} in
8184     * the given {@link ProviderInfo}. Final permission checking is always done
8185     * in {@link ContentProvider}.
8186     */
8187    private final boolean checkHoldingPermissionsLocked(
8188            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8189        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8190                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8191        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8192            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8193                    != PERMISSION_GRANTED) {
8194                return false;
8195            }
8196        }
8197        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8198    }
8199
8200    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8201            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8202        if (pi.applicationInfo.uid == uid) {
8203            return true;
8204        } else if (!pi.exported) {
8205            return false;
8206        }
8207
8208        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8209        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8210        try {
8211            // check if target holds top-level <provider> permissions
8212            if (!readMet && pi.readPermission != null && considerUidPermissions
8213                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8214                readMet = true;
8215            }
8216            if (!writeMet && pi.writePermission != null && considerUidPermissions
8217                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8218                writeMet = true;
8219            }
8220
8221            // track if unprotected read/write is allowed; any denied
8222            // <path-permission> below removes this ability
8223            boolean allowDefaultRead = pi.readPermission == null;
8224            boolean allowDefaultWrite = pi.writePermission == null;
8225
8226            // check if target holds any <path-permission> that match uri
8227            final PathPermission[] pps = pi.pathPermissions;
8228            if (pps != null) {
8229                final String path = grantUri.uri.getPath();
8230                int i = pps.length;
8231                while (i > 0 && (!readMet || !writeMet)) {
8232                    i--;
8233                    PathPermission pp = pps[i];
8234                    if (pp.match(path)) {
8235                        if (!readMet) {
8236                            final String pprperm = pp.getReadPermission();
8237                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8238                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8239                                    + ": match=" + pp.match(path)
8240                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8241                            if (pprperm != null) {
8242                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8243                                        == PERMISSION_GRANTED) {
8244                                    readMet = true;
8245                                } else {
8246                                    allowDefaultRead = false;
8247                                }
8248                            }
8249                        }
8250                        if (!writeMet) {
8251                            final String ppwperm = pp.getWritePermission();
8252                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8253                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8254                                    + ": match=" + pp.match(path)
8255                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8256                            if (ppwperm != null) {
8257                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8258                                        == PERMISSION_GRANTED) {
8259                                    writeMet = true;
8260                                } else {
8261                                    allowDefaultWrite = false;
8262                                }
8263                            }
8264                        }
8265                    }
8266                }
8267            }
8268
8269            // grant unprotected <provider> read/write, if not blocked by
8270            // <path-permission> above
8271            if (allowDefaultRead) readMet = true;
8272            if (allowDefaultWrite) writeMet = true;
8273
8274        } catch (RemoteException e) {
8275            return false;
8276        }
8277
8278        return readMet && writeMet;
8279    }
8280
8281    public boolean isAppStartModeDisabled(int uid, String packageName) {
8282        synchronized (this) {
8283            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8284                    == ActivityManager.APP_START_MODE_DISABLED;
8285        }
8286    }
8287
8288    // Unified app-op and target sdk check
8289    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8290        // Apps that target O+ are always subject to background check
8291        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8292            if (DEBUG_BACKGROUND_CHECK) {
8293                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8294            }
8295            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8296        }
8297        // ...and legacy apps get an AppOp check
8298        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8299                uid, packageName);
8300        if (DEBUG_BACKGROUND_CHECK) {
8301            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8302        }
8303        switch (appop) {
8304            case AppOpsManager.MODE_ALLOWED:
8305                return ActivityManager.APP_START_MODE_NORMAL;
8306            case AppOpsManager.MODE_IGNORED:
8307                return ActivityManager.APP_START_MODE_DELAYED;
8308            default:
8309                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8310        }
8311    }
8312
8313    // Service launch is available to apps with run-in-background exemptions but
8314    // some other background operations are not.  If we're doing a check
8315    // of service-launch policy, allow those callers to proceed unrestricted.
8316    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8317        // Persistent app?
8318        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8319            if (DEBUG_BACKGROUND_CHECK) {
8320                Slog.i(TAG, "App " + uid + "/" + packageName
8321                        + " is persistent; not restricted in background");
8322            }
8323            return ActivityManager.APP_START_MODE_NORMAL;
8324        }
8325
8326        // Non-persistent but background whitelisted?
8327        if (uidOnBackgroundWhitelist(uid)) {
8328            if (DEBUG_BACKGROUND_CHECK) {
8329                Slog.i(TAG, "App " + uid + "/" + packageName
8330                        + " on background whitelist; not restricted in background");
8331            }
8332            return ActivityManager.APP_START_MODE_NORMAL;
8333        }
8334
8335        // Is this app on the battery whitelist?
8336        if (isOnDeviceIdleWhitelistLocked(uid)) {
8337            if (DEBUG_BACKGROUND_CHECK) {
8338                Slog.i(TAG, "App " + uid + "/" + packageName
8339                        + " on idle whitelist; not restricted in background");
8340            }
8341            return ActivityManager.APP_START_MODE_NORMAL;
8342        }
8343
8344        // None of the service-policy criteria apply, so we apply the common criteria
8345        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8346    }
8347
8348    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8349            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8350        UidRecord uidRec = mActiveUids.get(uid);
8351        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8352                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8353                + (uidRec != null ? uidRec.idle : false));
8354        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8355            boolean ephemeral;
8356            if (uidRec == null) {
8357                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8358                        UserHandle.getUserId(uid), packageName);
8359            } else {
8360                ephemeral = uidRec.ephemeral;
8361            }
8362
8363            if (ephemeral) {
8364                // We are hard-core about ephemeral apps not running in the background.
8365                return ActivityManager.APP_START_MODE_DISABLED;
8366            } else {
8367                if (disabledOnly) {
8368                    // The caller is only interested in whether app starts are completely
8369                    // disabled for the given package (that is, it is an instant app).  So
8370                    // we don't need to go further, which is all just seeing if we should
8371                    // apply a "delayed" mode for a regular app.
8372                    return ActivityManager.APP_START_MODE_NORMAL;
8373                }
8374                final int startMode = (alwaysRestrict)
8375                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8376                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8377                                packageTargetSdk);
8378                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8379                        + " pkg=" + packageName + " startMode=" + startMode
8380                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8381                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8382                    // This is an old app that has been forced into a "compatible as possible"
8383                    // mode of background check.  To increase compatibility, we will allow other
8384                    // foreground apps to cause its services to start.
8385                    if (callingPid >= 0) {
8386                        ProcessRecord proc;
8387                        synchronized (mPidsSelfLocked) {
8388                            proc = mPidsSelfLocked.get(callingPid);
8389                        }
8390                        if (proc != null && proc.curProcState
8391                                < ActivityManager.PROCESS_STATE_RECEIVER) {
8392                            // Whoever is instigating this is in the foreground, so we will allow it
8393                            // to go through.
8394                            return ActivityManager.APP_START_MODE_NORMAL;
8395                        }
8396                    }
8397                }
8398                return startMode;
8399            }
8400        }
8401        return ActivityManager.APP_START_MODE_NORMAL;
8402    }
8403
8404    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8405        final int appId = UserHandle.getAppId(uid);
8406        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8407                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8408                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8409    }
8410
8411    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8412        ProviderInfo pi = null;
8413        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8414        if (cpr != null) {
8415            pi = cpr.info;
8416        } else {
8417            try {
8418                pi = AppGlobals.getPackageManager().resolveContentProvider(
8419                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8420                        userHandle);
8421            } catch (RemoteException ex) {
8422            }
8423        }
8424        return pi;
8425    }
8426
8427    void grantEphemeralAccessLocked(int userId, Intent intent,
8428            int targetAppId, int ephemeralAppId) {
8429        getPackageManagerInternalLocked().
8430                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8431    }
8432
8433    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8434        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8435        if (targetUris != null) {
8436            return targetUris.get(grantUri);
8437        }
8438        return null;
8439    }
8440
8441    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8442            String targetPkg, int targetUid, GrantUri grantUri) {
8443        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8444        if (targetUris == null) {
8445            targetUris = Maps.newArrayMap();
8446            mGrantedUriPermissions.put(targetUid, targetUris);
8447        }
8448
8449        UriPermission perm = targetUris.get(grantUri);
8450        if (perm == null) {
8451            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8452            targetUris.put(grantUri, perm);
8453        }
8454
8455        return perm;
8456    }
8457
8458    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8459            final int modeFlags) {
8460        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8461        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8462                : UriPermission.STRENGTH_OWNED;
8463
8464        // Root gets to do everything.
8465        if (uid == 0) {
8466            return true;
8467        }
8468
8469        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8470        if (perms == null) return false;
8471
8472        // First look for exact match
8473        final UriPermission exactPerm = perms.get(grantUri);
8474        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8475            return true;
8476        }
8477
8478        // No exact match, look for prefixes
8479        final int N = perms.size();
8480        for (int i = 0; i < N; i++) {
8481            final UriPermission perm = perms.valueAt(i);
8482            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8483                    && perm.getStrength(modeFlags) >= minStrength) {
8484                return true;
8485            }
8486        }
8487
8488        return false;
8489    }
8490
8491    /**
8492     * @param uri This uri must NOT contain an embedded userId.
8493     * @param userId The userId in which the uri is to be resolved.
8494     */
8495    @Override
8496    public int checkUriPermission(Uri uri, int pid, int uid,
8497            final int modeFlags, int userId, IBinder callerToken) {
8498        enforceNotIsolatedCaller("checkUriPermission");
8499
8500        // Another redirected-binder-call permissions check as in
8501        // {@link checkPermissionWithToken}.
8502        Identity tlsIdentity = sCallerIdentity.get();
8503        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8504            uid = tlsIdentity.uid;
8505            pid = tlsIdentity.pid;
8506        }
8507
8508        // Our own process gets to do everything.
8509        if (pid == MY_PID) {
8510            return PackageManager.PERMISSION_GRANTED;
8511        }
8512        synchronized (this) {
8513            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8514                    ? PackageManager.PERMISSION_GRANTED
8515                    : PackageManager.PERMISSION_DENIED;
8516        }
8517    }
8518
8519    /**
8520     * Check if the targetPkg can be granted permission to access uri by
8521     * the callingUid using the given modeFlags.  Throws a security exception
8522     * if callingUid is not allowed to do this.  Returns the uid of the target
8523     * if the URI permission grant should be performed; returns -1 if it is not
8524     * needed (for example targetPkg already has permission to access the URI).
8525     * If you already know the uid of the target, you can supply it in
8526     * lastTargetUid else set that to -1.
8527     */
8528    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8529            final int modeFlags, int lastTargetUid) {
8530        if (!Intent.isAccessUriMode(modeFlags)) {
8531            return -1;
8532        }
8533
8534        if (targetPkg != null) {
8535            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8536                    "Checking grant " + targetPkg + " permission to " + grantUri);
8537        }
8538
8539        final IPackageManager pm = AppGlobals.getPackageManager();
8540
8541        // If this is not a content: uri, we can't do anything with it.
8542        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8543            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8544                    "Can't grant URI permission for non-content URI: " + grantUri);
8545            return -1;
8546        }
8547
8548        final String authority = grantUri.uri.getAuthority();
8549        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8550                MATCH_DEBUG_TRIAGED_MISSING);
8551        if (pi == null) {
8552            Slog.w(TAG, "No content provider found for permission check: " +
8553                    grantUri.uri.toSafeString());
8554            return -1;
8555        }
8556
8557        int targetUid = lastTargetUid;
8558        if (targetUid < 0 && targetPkg != null) {
8559            try {
8560                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8561                        UserHandle.getUserId(callingUid));
8562                if (targetUid < 0) {
8563                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8564                            "Can't grant URI permission no uid for: " + targetPkg);
8565                    return -1;
8566                }
8567            } catch (RemoteException ex) {
8568                return -1;
8569            }
8570        }
8571
8572        // If we're extending a persistable grant, then we always need to create
8573        // the grant data structure so that take/release APIs work
8574        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8575            return targetUid;
8576        }
8577
8578        if (targetUid >= 0) {
8579            // First...  does the target actually need this permission?
8580            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8581                // No need to grant the target this permission.
8582                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8583                        "Target " + targetPkg + " already has full permission to " + grantUri);
8584                return -1;
8585            }
8586        } else {
8587            // First...  there is no target package, so can anyone access it?
8588            boolean allowed = pi.exported;
8589            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8590                if (pi.readPermission != null) {
8591                    allowed = false;
8592                }
8593            }
8594            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8595                if (pi.writePermission != null) {
8596                    allowed = false;
8597                }
8598            }
8599            if (allowed) {
8600                return -1;
8601            }
8602        }
8603
8604        /* There is a special cross user grant if:
8605         * - The target is on another user.
8606         * - Apps on the current user can access the uri without any uid permissions.
8607         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8608         * grant uri permissions.
8609         */
8610        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8611                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8612                modeFlags, false /*without considering the uid permissions*/);
8613
8614        // Second...  is the provider allowing granting of URI permissions?
8615        if (!specialCrossUserGrant) {
8616            if (!pi.grantUriPermissions) {
8617                throw new SecurityException("Provider " + pi.packageName
8618                        + "/" + pi.name
8619                        + " does not allow granting of Uri permissions (uri "
8620                        + grantUri + ")");
8621            }
8622            if (pi.uriPermissionPatterns != null) {
8623                final int N = pi.uriPermissionPatterns.length;
8624                boolean allowed = false;
8625                for (int i=0; i<N; i++) {
8626                    if (pi.uriPermissionPatterns[i] != null
8627                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8628                        allowed = true;
8629                        break;
8630                    }
8631                }
8632                if (!allowed) {
8633                    throw new SecurityException("Provider " + pi.packageName
8634                            + "/" + pi.name
8635                            + " does not allow granting of permission to path of Uri "
8636                            + grantUri);
8637                }
8638            }
8639        }
8640
8641        // Third...  does the caller itself have permission to access
8642        // this uri?
8643        final int callingAppId = UserHandle.getAppId(callingUid);
8644        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8645            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8646                // Exempted authority for cropping user photos in Settings app
8647            } else {
8648                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8649                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8650                return -1;
8651            }
8652        }
8653        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8654            // Require they hold a strong enough Uri permission
8655            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8656                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8657                    throw new SecurityException(
8658                            "UID " + callingUid + " does not have permission to " + grantUri
8659                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8660                                    + "or related APIs");
8661                } else {
8662                    throw new SecurityException(
8663                            "UID " + callingUid + " does not have permission to " + grantUri);
8664                }
8665            }
8666        }
8667        return targetUid;
8668    }
8669
8670    /**
8671     * @param uri This uri must NOT contain an embedded userId.
8672     * @param userId The userId in which the uri is to be resolved.
8673     */
8674    @Override
8675    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8676            final int modeFlags, int userId) {
8677        enforceNotIsolatedCaller("checkGrantUriPermission");
8678        synchronized(this) {
8679            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8680                    new GrantUri(userId, uri, false), modeFlags, -1);
8681        }
8682    }
8683
8684    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8685            final int modeFlags, UriPermissionOwner owner) {
8686        if (!Intent.isAccessUriMode(modeFlags)) {
8687            return;
8688        }
8689
8690        // So here we are: the caller has the assumed permission
8691        // to the uri, and the target doesn't.  Let's now give this to
8692        // the target.
8693
8694        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8695                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8696
8697        final String authority = grantUri.uri.getAuthority();
8698        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8699                MATCH_DEBUG_TRIAGED_MISSING);
8700        if (pi == null) {
8701            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8702            return;
8703        }
8704
8705        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8706            grantUri.prefix = true;
8707        }
8708        final UriPermission perm = findOrCreateUriPermissionLocked(
8709                pi.packageName, targetPkg, targetUid, grantUri);
8710        perm.grantModes(modeFlags, owner);
8711    }
8712
8713    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8714            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8715        if (targetPkg == null) {
8716            throw new NullPointerException("targetPkg");
8717        }
8718        int targetUid;
8719        final IPackageManager pm = AppGlobals.getPackageManager();
8720        try {
8721            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8722        } catch (RemoteException ex) {
8723            return;
8724        }
8725
8726        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8727                targetUid);
8728        if (targetUid < 0) {
8729            return;
8730        }
8731
8732        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8733                owner);
8734    }
8735
8736    static class NeededUriGrants extends ArrayList<GrantUri> {
8737        final String targetPkg;
8738        final int targetUid;
8739        final int flags;
8740
8741        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8742            this.targetPkg = targetPkg;
8743            this.targetUid = targetUid;
8744            this.flags = flags;
8745        }
8746    }
8747
8748    /**
8749     * Like checkGrantUriPermissionLocked, but takes an Intent.
8750     */
8751    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8752            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8753        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8754                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8755                + " clip=" + (intent != null ? intent.getClipData() : null)
8756                + " from " + intent + "; flags=0x"
8757                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8758
8759        if (targetPkg == null) {
8760            throw new NullPointerException("targetPkg");
8761        }
8762
8763        if (intent == null) {
8764            return null;
8765        }
8766        Uri data = intent.getData();
8767        ClipData clip = intent.getClipData();
8768        if (data == null && clip == null) {
8769            return null;
8770        }
8771        // Default userId for uris in the intent (if they don't specify it themselves)
8772        int contentUserHint = intent.getContentUserHint();
8773        if (contentUserHint == UserHandle.USER_CURRENT) {
8774            contentUserHint = UserHandle.getUserId(callingUid);
8775        }
8776        final IPackageManager pm = AppGlobals.getPackageManager();
8777        int targetUid;
8778        if (needed != null) {
8779            targetUid = needed.targetUid;
8780        } else {
8781            try {
8782                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8783                        targetUserId);
8784            } catch (RemoteException ex) {
8785                return null;
8786            }
8787            if (targetUid < 0) {
8788                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8789                        "Can't grant URI permission no uid for: " + targetPkg
8790                        + " on user " + targetUserId);
8791                return null;
8792            }
8793        }
8794        if (data != null) {
8795            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8796            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8797                    targetUid);
8798            if (targetUid > 0) {
8799                if (needed == null) {
8800                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8801                }
8802                needed.add(grantUri);
8803            }
8804        }
8805        if (clip != null) {
8806            for (int i=0; i<clip.getItemCount(); i++) {
8807                Uri uri = clip.getItemAt(i).getUri();
8808                if (uri != null) {
8809                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8810                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8811                            targetUid);
8812                    if (targetUid > 0) {
8813                        if (needed == null) {
8814                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8815                        }
8816                        needed.add(grantUri);
8817                    }
8818                } else {
8819                    Intent clipIntent = clip.getItemAt(i).getIntent();
8820                    if (clipIntent != null) {
8821                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8822                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8823                        if (newNeeded != null) {
8824                            needed = newNeeded;
8825                        }
8826                    }
8827                }
8828            }
8829        }
8830
8831        return needed;
8832    }
8833
8834    /**
8835     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8836     */
8837    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8838            UriPermissionOwner owner) {
8839        if (needed != null) {
8840            for (int i=0; i<needed.size(); i++) {
8841                GrantUri grantUri = needed.get(i);
8842                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8843                        grantUri, needed.flags, owner);
8844            }
8845        }
8846    }
8847
8848    void grantUriPermissionFromIntentLocked(int callingUid,
8849            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8850        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8851                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8852        if (needed == null) {
8853            return;
8854        }
8855
8856        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8857    }
8858
8859    /**
8860     * @param uri This uri must NOT contain an embedded userId.
8861     * @param userId The userId in which the uri is to be resolved.
8862     */
8863    @Override
8864    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8865            final int modeFlags, int userId) {
8866        enforceNotIsolatedCaller("grantUriPermission");
8867        GrantUri grantUri = new GrantUri(userId, uri, false);
8868        synchronized(this) {
8869            final ProcessRecord r = getRecordForAppLocked(caller);
8870            if (r == null) {
8871                throw new SecurityException("Unable to find app for caller "
8872                        + caller
8873                        + " when granting permission to uri " + grantUri);
8874            }
8875            if (targetPkg == null) {
8876                throw new IllegalArgumentException("null target");
8877            }
8878            if (grantUri == null) {
8879                throw new IllegalArgumentException("null uri");
8880            }
8881
8882            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8883                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8884                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8885                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8886
8887            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8888                    UserHandle.getUserId(r.uid));
8889        }
8890    }
8891
8892    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8893        if (perm.modeFlags == 0) {
8894            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8895                    perm.targetUid);
8896            if (perms != null) {
8897                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8898                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8899
8900                perms.remove(perm.uri);
8901                if (perms.isEmpty()) {
8902                    mGrantedUriPermissions.remove(perm.targetUid);
8903                }
8904            }
8905        }
8906    }
8907
8908    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
8909            final int modeFlags) {
8910        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8911                "Revoking all granted permissions to " + grantUri);
8912
8913        final IPackageManager pm = AppGlobals.getPackageManager();
8914        final String authority = grantUri.uri.getAuthority();
8915        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8916                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8917        if (pi == null) {
8918            Slog.w(TAG, "No content provider found for permission revoke: "
8919                    + grantUri.toSafeString());
8920            return;
8921        }
8922
8923        // Does the caller have this permission on the URI?
8924        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8925            // If they don't have direct access to the URI, then revoke any
8926            // ownerless URI permissions that have been granted to them.
8927            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8928            if (perms != null) {
8929                boolean persistChanged = false;
8930                for (int i = perms.size()-1; i >= 0; i--) {
8931                    final UriPermission perm = perms.valueAt(i);
8932                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
8933                        continue;
8934                    }
8935                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8936                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8937                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8938                                "Revoking non-owned " + perm.targetUid
8939                                + " permission to " + perm.uri);
8940                        persistChanged |= perm.revokeModes(
8941                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8942                        if (perm.modeFlags == 0) {
8943                            perms.removeAt(i);
8944                        }
8945                    }
8946                }
8947                if (perms.isEmpty()) {
8948                    mGrantedUriPermissions.remove(callingUid);
8949                }
8950                if (persistChanged) {
8951                    schedulePersistUriGrants();
8952                }
8953            }
8954            return;
8955        }
8956
8957        boolean persistChanged = false;
8958
8959        // Go through all of the permissions and remove any that match.
8960        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
8961            final int targetUid = mGrantedUriPermissions.keyAt(i);
8962            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8963
8964            for (int j = perms.size()-1; j >= 0; j--) {
8965                final UriPermission perm = perms.valueAt(j);
8966                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
8967                    continue;
8968                }
8969                if (perm.uri.sourceUserId == grantUri.sourceUserId
8970                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8971                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8972                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8973                    persistChanged |= perm.revokeModes(
8974                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
8975                            targetPackage == null);
8976                    if (perm.modeFlags == 0) {
8977                        perms.removeAt(j);
8978                    }
8979                }
8980            }
8981
8982            if (perms.isEmpty()) {
8983                mGrantedUriPermissions.removeAt(i);
8984            }
8985        }
8986
8987        if (persistChanged) {
8988            schedulePersistUriGrants();
8989        }
8990    }
8991
8992    /**
8993     * @param uri This uri must NOT contain an embedded userId.
8994     * @param userId The userId in which the uri is to be resolved.
8995     */
8996    @Override
8997    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
8998            final int modeFlags, int userId) {
8999        enforceNotIsolatedCaller("revokeUriPermission");
9000        synchronized(this) {
9001            final ProcessRecord r = getRecordForAppLocked(caller);
9002            if (r == null) {
9003                throw new SecurityException("Unable to find app for caller "
9004                        + caller
9005                        + " when revoking permission to uri " + uri);
9006            }
9007            if (uri == null) {
9008                Slog.w(TAG, "revokeUriPermission: null uri");
9009                return;
9010            }
9011
9012            if (!Intent.isAccessUriMode(modeFlags)) {
9013                return;
9014            }
9015
9016            final String authority = uri.getAuthority();
9017            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9018                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9019            if (pi == null) {
9020                Slog.w(TAG, "No content provider found for permission revoke: "
9021                        + uri.toSafeString());
9022                return;
9023            }
9024
9025            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9026                    modeFlags);
9027        }
9028    }
9029
9030    /**
9031     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9032     * given package.
9033     *
9034     * @param packageName Package name to match, or {@code null} to apply to all
9035     *            packages.
9036     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9037     *            to all users.
9038     * @param persistable If persistable grants should be removed.
9039     */
9040    private void removeUriPermissionsForPackageLocked(
9041            String packageName, int userHandle, boolean persistable) {
9042        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9043            throw new IllegalArgumentException("Must narrow by either package or user");
9044        }
9045
9046        boolean persistChanged = false;
9047
9048        int N = mGrantedUriPermissions.size();
9049        for (int i = 0; i < N; i++) {
9050            final int targetUid = mGrantedUriPermissions.keyAt(i);
9051            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9052
9053            // Only inspect grants matching user
9054            if (userHandle == UserHandle.USER_ALL
9055                    || userHandle == UserHandle.getUserId(targetUid)) {
9056                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9057                    final UriPermission perm = it.next();
9058
9059                    // Only inspect grants matching package
9060                    if (packageName == null || perm.sourcePkg.equals(packageName)
9061                            || perm.targetPkg.equals(packageName)) {
9062                        // Hacky solution as part of fixing a security bug; ignore
9063                        // grants associated with DownloadManager so we don't have
9064                        // to immediately launch it to regrant the permissions
9065                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9066                                && !persistable) continue;
9067
9068                        persistChanged |= perm.revokeModes(persistable
9069                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9070
9071                        // Only remove when no modes remain; any persisted grants
9072                        // will keep this alive.
9073                        if (perm.modeFlags == 0) {
9074                            it.remove();
9075                        }
9076                    }
9077                }
9078
9079                if (perms.isEmpty()) {
9080                    mGrantedUriPermissions.remove(targetUid);
9081                    N--;
9082                    i--;
9083                }
9084            }
9085        }
9086
9087        if (persistChanged) {
9088            schedulePersistUriGrants();
9089        }
9090    }
9091
9092    @Override
9093    public IBinder newUriPermissionOwner(String name) {
9094        enforceNotIsolatedCaller("newUriPermissionOwner");
9095        synchronized(this) {
9096            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9097            return owner.getExternalTokenLocked();
9098        }
9099    }
9100
9101    @Override
9102    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9103        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9104        synchronized(this) {
9105            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9106            if (r == null) {
9107                throw new IllegalArgumentException("Activity does not exist; token="
9108                        + activityToken);
9109            }
9110            return r.getUriPermissionsLocked().getExternalTokenLocked();
9111        }
9112    }
9113    /**
9114     * @param uri This uri must NOT contain an embedded userId.
9115     * @param sourceUserId The userId in which the uri is to be resolved.
9116     * @param targetUserId The userId of the app that receives the grant.
9117     */
9118    @Override
9119    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9120            final int modeFlags, int sourceUserId, int targetUserId) {
9121        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9122                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9123                "grantUriPermissionFromOwner", null);
9124        synchronized(this) {
9125            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9126            if (owner == null) {
9127                throw new IllegalArgumentException("Unknown owner: " + token);
9128            }
9129            if (fromUid != Binder.getCallingUid()) {
9130                if (Binder.getCallingUid() != myUid()) {
9131                    // Only system code can grant URI permissions on behalf
9132                    // of other users.
9133                    throw new SecurityException("nice try");
9134                }
9135            }
9136            if (targetPkg == null) {
9137                throw new IllegalArgumentException("null target");
9138            }
9139            if (uri == null) {
9140                throw new IllegalArgumentException("null uri");
9141            }
9142
9143            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9144                    modeFlags, owner, targetUserId);
9145        }
9146    }
9147
9148    /**
9149     * @param uri This uri must NOT contain an embedded userId.
9150     * @param userId The userId in which the uri is to be resolved.
9151     */
9152    @Override
9153    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9154        synchronized(this) {
9155            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9156            if (owner == null) {
9157                throw new IllegalArgumentException("Unknown owner: " + token);
9158            }
9159
9160            if (uri == null) {
9161                owner.removeUriPermissionsLocked(mode);
9162            } else {
9163                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9164                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9165            }
9166        }
9167    }
9168
9169    private void schedulePersistUriGrants() {
9170        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9171            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9172                    10 * DateUtils.SECOND_IN_MILLIS);
9173        }
9174    }
9175
9176    private void writeGrantedUriPermissions() {
9177        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9178
9179        // Snapshot permissions so we can persist without lock
9180        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9181        synchronized (this) {
9182            final int size = mGrantedUriPermissions.size();
9183            for (int i = 0; i < size; i++) {
9184                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9185                for (UriPermission perm : perms.values()) {
9186                    if (perm.persistedModeFlags != 0) {
9187                        persist.add(perm.snapshot());
9188                    }
9189                }
9190            }
9191        }
9192
9193        FileOutputStream fos = null;
9194        try {
9195            fos = mGrantFile.startWrite();
9196
9197            XmlSerializer out = new FastXmlSerializer();
9198            out.setOutput(fos, StandardCharsets.UTF_8.name());
9199            out.startDocument(null, true);
9200            out.startTag(null, TAG_URI_GRANTS);
9201            for (UriPermission.Snapshot perm : persist) {
9202                out.startTag(null, TAG_URI_GRANT);
9203                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9204                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9205                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9206                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9207                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9208                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9209                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9210                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9211                out.endTag(null, TAG_URI_GRANT);
9212            }
9213            out.endTag(null, TAG_URI_GRANTS);
9214            out.endDocument();
9215
9216            mGrantFile.finishWrite(fos);
9217        } catch (IOException e) {
9218            if (fos != null) {
9219                mGrantFile.failWrite(fos);
9220            }
9221        }
9222    }
9223
9224    private void readGrantedUriPermissionsLocked() {
9225        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9226
9227        final long now = System.currentTimeMillis();
9228
9229        FileInputStream fis = null;
9230        try {
9231            fis = mGrantFile.openRead();
9232            final XmlPullParser in = Xml.newPullParser();
9233            in.setInput(fis, StandardCharsets.UTF_8.name());
9234
9235            int type;
9236            while ((type = in.next()) != END_DOCUMENT) {
9237                final String tag = in.getName();
9238                if (type == START_TAG) {
9239                    if (TAG_URI_GRANT.equals(tag)) {
9240                        final int sourceUserId;
9241                        final int targetUserId;
9242                        final int userHandle = readIntAttribute(in,
9243                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9244                        if (userHandle != UserHandle.USER_NULL) {
9245                            // For backwards compatibility.
9246                            sourceUserId = userHandle;
9247                            targetUserId = userHandle;
9248                        } else {
9249                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9250                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9251                        }
9252                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9253                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9254                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9255                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9256                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9257                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9258
9259                        // Sanity check that provider still belongs to source package
9260                        // Both direct boot aware and unaware packages are fine as we
9261                        // will do filtering at query time to avoid multiple parsing.
9262                        final ProviderInfo pi = getProviderInfoLocked(
9263                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9264                                        | MATCH_DIRECT_BOOT_UNAWARE);
9265                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9266                            int targetUid = -1;
9267                            try {
9268                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9269                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9270                            } catch (RemoteException e) {
9271                            }
9272                            if (targetUid != -1) {
9273                                final UriPermission perm = findOrCreateUriPermissionLocked(
9274                                        sourcePkg, targetPkg, targetUid,
9275                                        new GrantUri(sourceUserId, uri, prefix));
9276                                perm.initPersistedModes(modeFlags, createdTime);
9277                            }
9278                        } else {
9279                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9280                                    + " but instead found " + pi);
9281                        }
9282                    }
9283                }
9284            }
9285        } catch (FileNotFoundException e) {
9286            // Missing grants is okay
9287        } catch (IOException e) {
9288            Slog.wtf(TAG, "Failed reading Uri grants", e);
9289        } catch (XmlPullParserException e) {
9290            Slog.wtf(TAG, "Failed reading Uri grants", e);
9291        } finally {
9292            IoUtils.closeQuietly(fis);
9293        }
9294    }
9295
9296    /**
9297     * @param uri This uri must NOT contain an embedded userId.
9298     * @param userId The userId in which the uri is to be resolved.
9299     */
9300    @Override
9301    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9302        enforceNotIsolatedCaller("takePersistableUriPermission");
9303
9304        Preconditions.checkFlagsArgument(modeFlags,
9305                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9306
9307        synchronized (this) {
9308            final int callingUid = Binder.getCallingUid();
9309            boolean persistChanged = false;
9310            GrantUri grantUri = new GrantUri(userId, uri, false);
9311
9312            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9313                    new GrantUri(userId, uri, false));
9314            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9315                    new GrantUri(userId, uri, true));
9316
9317            final boolean exactValid = (exactPerm != null)
9318                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9319            final boolean prefixValid = (prefixPerm != null)
9320                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9321
9322            if (!(exactValid || prefixValid)) {
9323                throw new SecurityException("No persistable permission grants found for UID "
9324                        + callingUid + " and Uri " + grantUri.toSafeString());
9325            }
9326
9327            if (exactValid) {
9328                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9329            }
9330            if (prefixValid) {
9331                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9332            }
9333
9334            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9335
9336            if (persistChanged) {
9337                schedulePersistUriGrants();
9338            }
9339        }
9340    }
9341
9342    /**
9343     * @param uri This uri must NOT contain an embedded userId.
9344     * @param userId The userId in which the uri is to be resolved.
9345     */
9346    @Override
9347    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9348        enforceNotIsolatedCaller("releasePersistableUriPermission");
9349
9350        Preconditions.checkFlagsArgument(modeFlags,
9351                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9352
9353        synchronized (this) {
9354            final int callingUid = Binder.getCallingUid();
9355            boolean persistChanged = false;
9356
9357            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9358                    new GrantUri(userId, uri, false));
9359            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9360                    new GrantUri(userId, uri, true));
9361            if (exactPerm == null && prefixPerm == null) {
9362                throw new SecurityException("No permission grants found for UID " + callingUid
9363                        + " and Uri " + uri.toSafeString());
9364            }
9365
9366            if (exactPerm != null) {
9367                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9368                removeUriPermissionIfNeededLocked(exactPerm);
9369            }
9370            if (prefixPerm != null) {
9371                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9372                removeUriPermissionIfNeededLocked(prefixPerm);
9373            }
9374
9375            if (persistChanged) {
9376                schedulePersistUriGrants();
9377            }
9378        }
9379    }
9380
9381    /**
9382     * Prune any older {@link UriPermission} for the given UID until outstanding
9383     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9384     *
9385     * @return if any mutations occured that require persisting.
9386     */
9387    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9388        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9389        if (perms == null) return false;
9390        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9391
9392        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9393        for (UriPermission perm : perms.values()) {
9394            if (perm.persistedModeFlags != 0) {
9395                persisted.add(perm);
9396            }
9397        }
9398
9399        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9400        if (trimCount <= 0) return false;
9401
9402        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9403        for (int i = 0; i < trimCount; i++) {
9404            final UriPermission perm = persisted.get(i);
9405
9406            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9407                    "Trimming grant created at " + perm.persistedCreateTime);
9408
9409            perm.releasePersistableModes(~0);
9410            removeUriPermissionIfNeededLocked(perm);
9411        }
9412
9413        return true;
9414    }
9415
9416    @Override
9417    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9418            String packageName, boolean incoming) {
9419        enforceNotIsolatedCaller("getPersistedUriPermissions");
9420        Preconditions.checkNotNull(packageName, "packageName");
9421
9422        final int callingUid = Binder.getCallingUid();
9423        final int callingUserId = UserHandle.getUserId(callingUid);
9424        final IPackageManager pm = AppGlobals.getPackageManager();
9425        try {
9426            final int packageUid = pm.getPackageUid(packageName,
9427                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9428            if (packageUid != callingUid) {
9429                throw new SecurityException(
9430                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9431            }
9432        } catch (RemoteException e) {
9433            throw new SecurityException("Failed to verify package name ownership");
9434        }
9435
9436        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9437        synchronized (this) {
9438            if (incoming) {
9439                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9440                        callingUid);
9441                if (perms == null) {
9442                    Slog.w(TAG, "No permission grants found for " + packageName);
9443                } else {
9444                    for (UriPermission perm : perms.values()) {
9445                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9446                            result.add(perm.buildPersistedPublicApiObject());
9447                        }
9448                    }
9449                }
9450            } else {
9451                final int size = mGrantedUriPermissions.size();
9452                for (int i = 0; i < size; i++) {
9453                    final ArrayMap<GrantUri, UriPermission> perms =
9454                            mGrantedUriPermissions.valueAt(i);
9455                    for (UriPermission perm : perms.values()) {
9456                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9457                            result.add(perm.buildPersistedPublicApiObject());
9458                        }
9459                    }
9460                }
9461            }
9462        }
9463        return new ParceledListSlice<android.content.UriPermission>(result);
9464    }
9465
9466    @Override
9467    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9468            String packageName, int userId) {
9469        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9470                "getGrantedUriPermissions");
9471
9472        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9473        synchronized (this) {
9474            final int size = mGrantedUriPermissions.size();
9475            for (int i = 0; i < size; i++) {
9476                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9477                for (UriPermission perm : perms.values()) {
9478                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9479                            && perm.persistedModeFlags != 0) {
9480                        result.add(perm.buildPersistedPublicApiObject());
9481                    }
9482                }
9483            }
9484        }
9485        return new ParceledListSlice<android.content.UriPermission>(result);
9486    }
9487
9488    @Override
9489    public void clearGrantedUriPermissions(String packageName, int userId) {
9490        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9491                "clearGrantedUriPermissions");
9492        removeUriPermissionsForPackageLocked(packageName, userId, true);
9493    }
9494
9495    @Override
9496    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9497        synchronized (this) {
9498            ProcessRecord app =
9499                who != null ? getRecordForAppLocked(who) : null;
9500            if (app == null) return;
9501
9502            Message msg = Message.obtain();
9503            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9504            msg.obj = app;
9505            msg.arg1 = waiting ? 1 : 0;
9506            mUiHandler.sendMessage(msg);
9507        }
9508    }
9509
9510    @Override
9511    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9512        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9513        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9514        outInfo.availMem = getFreeMemory();
9515        outInfo.totalMem = getTotalMemory();
9516        outInfo.threshold = homeAppMem;
9517        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9518        outInfo.hiddenAppThreshold = cachedAppMem;
9519        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9520                ProcessList.SERVICE_ADJ);
9521        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9522                ProcessList.VISIBLE_APP_ADJ);
9523        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9524                ProcessList.FOREGROUND_APP_ADJ);
9525    }
9526
9527    // =========================================================
9528    // TASK MANAGEMENT
9529    // =========================================================
9530
9531    @Override
9532    public List<IBinder> getAppTasks(String callingPackage) {
9533        int callingUid = Binder.getCallingUid();
9534        long ident = Binder.clearCallingIdentity();
9535
9536        synchronized(this) {
9537            ArrayList<IBinder> list = new ArrayList<IBinder>();
9538            try {
9539                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9540
9541                final int N = mRecentTasks.size();
9542                for (int i = 0; i < N; i++) {
9543                    TaskRecord tr = mRecentTasks.get(i);
9544                    // Skip tasks that do not match the caller.  We don't need to verify
9545                    // callingPackage, because we are also limiting to callingUid and know
9546                    // that will limit to the correct security sandbox.
9547                    if (tr.effectiveUid != callingUid) {
9548                        continue;
9549                    }
9550                    Intent intent = tr.getBaseIntent();
9551                    if (intent == null ||
9552                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9553                        continue;
9554                    }
9555                    ActivityManager.RecentTaskInfo taskInfo =
9556                            createRecentTaskInfoFromTaskRecord(tr);
9557                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9558                    list.add(taskImpl.asBinder());
9559                }
9560            } finally {
9561                Binder.restoreCallingIdentity(ident);
9562            }
9563            return list;
9564        }
9565    }
9566
9567    @Override
9568    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9569        final int callingUid = Binder.getCallingUid();
9570        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9571
9572        synchronized(this) {
9573            if (DEBUG_ALL) Slog.v(
9574                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9575
9576            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9577                    callingUid);
9578
9579            // TODO: Improve with MRU list from all ActivityStacks.
9580            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9581        }
9582
9583        return list;
9584    }
9585
9586    /**
9587     * Creates a new RecentTaskInfo from a TaskRecord.
9588     */
9589    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9590        // Update the task description to reflect any changes in the task stack
9591        tr.updateTaskDescription();
9592
9593        // Compose the recent task info
9594        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9595        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9596        rti.persistentId = tr.taskId;
9597        rti.baseIntent = new Intent(tr.getBaseIntent());
9598        rti.origActivity = tr.origActivity;
9599        rti.realActivity = tr.realActivity;
9600        rti.description = tr.lastDescription;
9601        rti.stackId = tr.getStackId();
9602        rti.userId = tr.userId;
9603        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9604        rti.firstActiveTime = tr.firstActiveTime;
9605        rti.lastActiveTime = tr.lastActiveTime;
9606        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9607        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9608        rti.numActivities = 0;
9609        if (tr.mBounds != null) {
9610            rti.bounds = new Rect(tr.mBounds);
9611        }
9612        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9613        rti.resizeMode = tr.mResizeMode;
9614
9615        ActivityRecord base = null;
9616        ActivityRecord top = null;
9617        ActivityRecord tmp;
9618
9619        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9620            tmp = tr.mActivities.get(i);
9621            if (tmp.finishing) {
9622                continue;
9623            }
9624            base = tmp;
9625            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9626                top = base;
9627            }
9628            rti.numActivities++;
9629        }
9630
9631        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9632        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9633
9634        return rti;
9635    }
9636
9637    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9638        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9639                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9640        if (!allowed) {
9641            if (checkPermission(android.Manifest.permission.GET_TASKS,
9642                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9643                // Temporary compatibility: some existing apps on the system image may
9644                // still be requesting the old permission and not switched to the new
9645                // one; if so, we'll still allow them full access.  This means we need
9646                // to see if they are holding the old permission and are a system app.
9647                try {
9648                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9649                        allowed = true;
9650                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9651                                + " is using old GET_TASKS but privileged; allowing");
9652                    }
9653                } catch (RemoteException e) {
9654                }
9655            }
9656        }
9657        if (!allowed) {
9658            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9659                    + " does not hold REAL_GET_TASKS; limiting output");
9660        }
9661        return allowed;
9662    }
9663
9664    @Override
9665    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9666            int userId) {
9667        final int callingUid = Binder.getCallingUid();
9668        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9669                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9670
9671        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9672        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9673        synchronized (this) {
9674            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9675                    callingUid);
9676            final boolean detailed = checkCallingPermission(
9677                    android.Manifest.permission.GET_DETAILED_TASKS)
9678                    == PackageManager.PERMISSION_GRANTED;
9679
9680            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9681                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9682                return ParceledListSlice.emptyList();
9683            }
9684            mRecentTasks.loadUserRecentsLocked(userId);
9685
9686            final int recentsCount = mRecentTasks.size();
9687            ArrayList<ActivityManager.RecentTaskInfo> res =
9688                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9689
9690            final Set<Integer> includedUsers;
9691            if (includeProfiles) {
9692                includedUsers = mUserController.getProfileIds(userId);
9693            } else {
9694                includedUsers = new HashSet<>();
9695            }
9696            includedUsers.add(Integer.valueOf(userId));
9697
9698            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9699                TaskRecord tr = mRecentTasks.get(i);
9700                // Only add calling user or related users recent tasks
9701                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9702                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9703                    continue;
9704                }
9705
9706                if (tr.realActivitySuspended) {
9707                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9708                    continue;
9709                }
9710
9711                // Return the entry if desired by the caller.  We always return
9712                // the first entry, because callers always expect this to be the
9713                // foreground app.  We may filter others if the caller has
9714                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9715                // we should exclude the entry.
9716
9717                if (i == 0
9718                        || withExcluded
9719                        || (tr.intent == null)
9720                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9721                                == 0)) {
9722                    if (!allowed) {
9723                        // If the caller doesn't have the GET_TASKS permission, then only
9724                        // allow them to see a small subset of tasks -- their own and home.
9725                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9726                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9727                            continue;
9728                        }
9729                    }
9730                    final ActivityStack stack = tr.getStack();
9731                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9732                        if (stack != null && stack.isHomeOrRecentsStack()) {
9733                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9734                                    "Skipping, home or recents stack task: " + tr);
9735                            continue;
9736                        }
9737                    }
9738                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9739                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9740                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9741                                    "Skipping, top task in docked stack: " + tr);
9742                            continue;
9743                        }
9744                    }
9745                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9746                        if (stack != null && stack.isPinnedStack()) {
9747                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9748                                    "Skipping, pinned stack task: " + tr);
9749                            continue;
9750                        }
9751                    }
9752                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9753                        // Don't include auto remove tasks that are finished or finishing.
9754                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9755                                "Skipping, auto-remove without activity: " + tr);
9756                        continue;
9757                    }
9758                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9759                            && !tr.isAvailable) {
9760                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9761                                "Skipping, unavail real act: " + tr);
9762                        continue;
9763                    }
9764
9765                    if (!tr.mUserSetupComplete) {
9766                        // Don't include task launched while user is not done setting-up.
9767                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9768                                "Skipping, user setup not complete: " + tr);
9769                        continue;
9770                    }
9771
9772                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9773                    if (!detailed) {
9774                        rti.baseIntent.replaceExtras((Bundle)null);
9775                    }
9776
9777                    res.add(rti);
9778                    maxNum--;
9779                }
9780            }
9781            return new ParceledListSlice<>(res);
9782        }
9783    }
9784
9785    @Override
9786    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9787        synchronized (this) {
9788            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9789                    "getTaskThumbnail()");
9790            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9791                    id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9792            if (tr != null) {
9793                return tr.getTaskThumbnailLocked();
9794            }
9795        }
9796        return null;
9797    }
9798
9799    @Override
9800    public ActivityManager.TaskDescription getTaskDescription(int id) {
9801        synchronized (this) {
9802            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9803                    "getTaskDescription()");
9804            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9805                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9806            if (tr != null) {
9807                return tr.lastTaskDescription;
9808            }
9809        }
9810        return null;
9811    }
9812
9813    @Override
9814    public int addAppTask(IBinder activityToken, Intent intent,
9815            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9816        final int callingUid = Binder.getCallingUid();
9817        final long callingIdent = Binder.clearCallingIdentity();
9818
9819        try {
9820            synchronized (this) {
9821                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9822                if (r == null) {
9823                    throw new IllegalArgumentException("Activity does not exist; token="
9824                            + activityToken);
9825                }
9826                ComponentName comp = intent.getComponent();
9827                if (comp == null) {
9828                    throw new IllegalArgumentException("Intent " + intent
9829                            + " must specify explicit component");
9830                }
9831                if (thumbnail.getWidth() != mThumbnailWidth
9832                        || thumbnail.getHeight() != mThumbnailHeight) {
9833                    throw new IllegalArgumentException("Bad thumbnail size: got "
9834                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9835                            + mThumbnailWidth + "x" + mThumbnailHeight);
9836                }
9837                if (intent.getSelector() != null) {
9838                    intent.setSelector(null);
9839                }
9840                if (intent.getSourceBounds() != null) {
9841                    intent.setSourceBounds(null);
9842                }
9843                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9844                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9845                        // The caller has added this as an auto-remove task...  that makes no
9846                        // sense, so turn off auto-remove.
9847                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9848                    }
9849                }
9850                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9851                    mLastAddedTaskActivity = null;
9852                }
9853                ActivityInfo ainfo = mLastAddedTaskActivity;
9854                if (ainfo == null) {
9855                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9856                            comp, 0, UserHandle.getUserId(callingUid));
9857                    if (ainfo.applicationInfo.uid != callingUid) {
9858                        throw new SecurityException(
9859                                "Can't add task for another application: target uid="
9860                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9861                    }
9862                }
9863
9864                TaskRecord task = new TaskRecord(this,
9865                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9866                        ainfo, intent, description, new TaskThumbnailInfo());
9867
9868                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9869                if (trimIdx >= 0) {
9870                    // If this would have caused a trim, then we'll abort because that
9871                    // means it would be added at the end of the list but then just removed.
9872                    return INVALID_TASK_ID;
9873                }
9874
9875                final int N = mRecentTasks.size();
9876                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9877                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9878                    tr.removedFromRecents();
9879                }
9880
9881                task.inRecents = true;
9882                mRecentTasks.add(task);
9883                r.getStack().addTask(task, false, "addAppTask");
9884
9885                task.setLastThumbnailLocked(thumbnail);
9886                task.freeLastThumbnail();
9887                return task.taskId;
9888            }
9889        } finally {
9890            Binder.restoreCallingIdentity(callingIdent);
9891        }
9892    }
9893
9894    @Override
9895    public Point getAppTaskThumbnailSize() {
9896        synchronized (this) {
9897            return new Point(mThumbnailWidth,  mThumbnailHeight);
9898        }
9899    }
9900
9901    @Override
9902    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9903        synchronized (this) {
9904            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9905            if (r != null) {
9906                r.setTaskDescription(td);
9907                final TaskRecord task = r.getTask();
9908                task.updateTaskDescription();
9909                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
9910            }
9911        }
9912    }
9913
9914    @Override
9915    public void setTaskResizeable(int taskId, int resizeableMode) {
9916        synchronized (this) {
9917            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9918                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9919            if (task == null) {
9920                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9921                return;
9922            }
9923            task.setResizeMode(resizeableMode);
9924        }
9925    }
9926
9927    @Override
9928    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9929        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9930        long ident = Binder.clearCallingIdentity();
9931        try {
9932            synchronized (this) {
9933                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9934                if (task == null) {
9935                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9936                    return;
9937                }
9938                // Place the task in the right stack if it isn't there already based on
9939                // the requested bounds.
9940                // The stack transition logic is:
9941                // - a null bounds on a freeform task moves that task to fullscreen
9942                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9943                //   that task to freeform
9944                // - otherwise the task is not moved
9945                int stackId = task.getStackId();
9946                if (!StackId.isTaskResizeAllowed(stackId)) {
9947                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9948                }
9949                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9950                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9951                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9952                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9953                }
9954
9955                // Reparent the task to the right stack if necessary
9956                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9957                if (stackId != task.getStackId()) {
9958                    // Defer resume until the task is resized below
9959                    task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
9960                            DEFER_RESUME, "resizeTask");
9961                    preserveWindow = false;
9962                }
9963
9964                // After reparenting (which only resizes the task to the stack bounds), resize the
9965                // task to the actual bounds provided
9966                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
9967            }
9968        } finally {
9969            Binder.restoreCallingIdentity(ident);
9970        }
9971    }
9972
9973    @Override
9974    public Rect getTaskBounds(int taskId) {
9975        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9976        long ident = Binder.clearCallingIdentity();
9977        Rect rect = new Rect();
9978        try {
9979            synchronized (this) {
9980                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
9981                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9982                if (task == null) {
9983                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9984                    return rect;
9985                }
9986                if (task.getStack() != null) {
9987                    // Return the bounds from window manager since it will be adjusted for various
9988                    // things like the presense of a docked stack for tasks that aren't resizeable.
9989                    task.getWindowContainerBounds(rect);
9990                } else {
9991                    // Task isn't in window manager yet since it isn't associated with a stack.
9992                    // Return the persist value from activity manager
9993                    if (task.mBounds != null) {
9994                        rect.set(task.mBounds);
9995                    } else if (task.mLastNonFullscreenBounds != null) {
9996                        rect.set(task.mLastNonFullscreenBounds);
9997                    }
9998                }
9999            }
10000        } finally {
10001            Binder.restoreCallingIdentity(ident);
10002        }
10003        return rect;
10004    }
10005
10006    @Override
10007    public void cancelTaskWindowTransition(int taskId) {
10008        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10009        final long ident = Binder.clearCallingIdentity();
10010        try {
10011            synchronized (this) {
10012                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10013                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10014                if (task == null) {
10015                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10016                    return;
10017                }
10018                task.cancelWindowTransition();
10019            }
10020        } finally {
10021            Binder.restoreCallingIdentity(ident);
10022        }
10023    }
10024
10025    @Override
10026    public void cancelTaskThumbnailTransition(int taskId) {
10027        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10028        final long ident = Binder.clearCallingIdentity();
10029        try {
10030            synchronized (this) {
10031                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10032                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10033                if (task == null) {
10034                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10035                    return;
10036                }
10037                task.cancelThumbnailTransition();
10038            }
10039        } finally {
10040            Binder.restoreCallingIdentity(ident);
10041        }
10042    }
10043
10044    @Override
10045    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10046        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10047        final long ident = Binder.clearCallingIdentity();
10048        try {
10049            final TaskRecord task;
10050            synchronized (this) {
10051                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10052                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10053                if (task == null) {
10054                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10055                    return null;
10056                }
10057            }
10058            // Don't call this while holding the lock as this operation might hit the disk.
10059            return task.getSnapshot(reducedResolution);
10060        } finally {
10061            Binder.restoreCallingIdentity(ident);
10062        }
10063    }
10064
10065    @Override
10066    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10067        if (userId != UserHandle.getCallingUserId()) {
10068            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10069                    "getTaskDescriptionIcon");
10070        }
10071        final File passedIconFile = new File(filePath);
10072        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10073                passedIconFile.getName());
10074        if (!legitIconFile.getPath().equals(filePath)
10075                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10076            throw new IllegalArgumentException("Bad file path: " + filePath
10077                    + " passed for userId " + userId);
10078        }
10079        return mRecentTasks.getTaskDescriptionIcon(filePath);
10080    }
10081
10082    @Override
10083    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10084            throws RemoteException {
10085        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10086        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10087                activityOptions.getCustomInPlaceResId() == 0) {
10088            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10089                    "with valid animation");
10090        }
10091        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10092        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10093                activityOptions.getCustomInPlaceResId());
10094        mWindowManager.executeAppTransition();
10095    }
10096
10097    private void removeTasksByPackageNameLocked(String packageName, int userId) {
10098        // Remove all tasks with activities in the specified package from the list of recent tasks
10099        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10100            TaskRecord tr = mRecentTasks.get(i);
10101            if (tr.userId != userId) continue;
10102
10103            ComponentName cn = tr.intent.getComponent();
10104            if (cn != null && cn.getPackageName().equals(packageName)) {
10105                // If the package name matches, remove the task.
10106                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10107            }
10108        }
10109    }
10110
10111    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10112            int userId) {
10113
10114        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10115            TaskRecord tr = mRecentTasks.get(i);
10116            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10117                continue;
10118            }
10119
10120            ComponentName cn = tr.intent.getComponent();
10121            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10122                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10123            if (sameComponent) {
10124                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10125            }
10126        }
10127    }
10128
10129    @Override
10130    public void removeStack(int stackId) {
10131        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10132        if (StackId.isHomeOrRecentsStack(stackId)) {
10133            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10134        }
10135
10136        synchronized (this) {
10137            final long ident = Binder.clearCallingIdentity();
10138            try {
10139                mStackSupervisor.removeStackLocked(stackId);
10140            } finally {
10141                Binder.restoreCallingIdentity(ident);
10142            }
10143        }
10144    }
10145
10146    @Override
10147    public void moveStackToDisplay(int stackId, int displayId) {
10148        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
10149
10150        synchronized (this) {
10151            final long ident = Binder.clearCallingIdentity();
10152            try {
10153                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10154                        + " to displayId=" + displayId);
10155                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10156            } finally {
10157                Binder.restoreCallingIdentity(ident);
10158            }
10159        }
10160    }
10161
10162    @Override
10163    public boolean removeTask(int taskId) {
10164        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10165        synchronized (this) {
10166            final long ident = Binder.clearCallingIdentity();
10167            try {
10168                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10169            } finally {
10170                Binder.restoreCallingIdentity(ident);
10171            }
10172        }
10173    }
10174
10175    /**
10176     * TODO: Add mController hook
10177     */
10178    @Override
10179    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10180        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10181
10182        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10183        synchronized(this) {
10184            moveTaskToFrontLocked(taskId, flags, bOptions);
10185        }
10186    }
10187
10188    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
10189        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10190
10191        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10192                Binder.getCallingUid(), -1, -1, "Task to front")) {
10193            ActivityOptions.abort(options);
10194            return;
10195        }
10196        final long origId = Binder.clearCallingIdentity();
10197        try {
10198            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10199            if (task == null) {
10200                Slog.d(TAG, "Could not find task for id: "+ taskId);
10201                return;
10202            }
10203            if (mStackSupervisor.isLockTaskModeViolation(task)) {
10204                mStackSupervisor.showLockTaskToast();
10205                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10206                return;
10207            }
10208            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10209            if (prev != null) {
10210                task.setTaskToReturnTo(prev);
10211            }
10212            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10213                    false /* forceNonResizable */);
10214
10215            final ActivityRecord topActivity = task.getTopActivity();
10216            if (topActivity != null) {
10217
10218                // We are reshowing a task, use a starting window to hide the initial draw delay
10219                // so the transition can start earlier.
10220                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10221                        true /* taskSwitch */);
10222            }
10223        } finally {
10224            Binder.restoreCallingIdentity(origId);
10225        }
10226        ActivityOptions.abort(options);
10227    }
10228
10229    /**
10230     * Attempts to move a task backwards in z-order (the order of activities within the task is
10231     * unchanged).
10232     *
10233     * There are several possible results of this call:
10234     * - if the task is locked, then we will show the lock toast
10235     * - if there is a task behind the provided task, then that task is made visible and resumed as
10236     *   this task is moved to the back
10237     * - otherwise, if there are no other tasks in the stack:
10238     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10239     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10240     *       (depending on whether it is visible)
10241     *     - otherwise, we simply return home and hide this task
10242     *
10243     * @param token A reference to the activity we wish to move
10244     * @param nonRoot If false then this only works if the activity is the root
10245     *                of a task; if true it will work for any activity in a task.
10246     * @return Returns true if the move completed, false if not.
10247     */
10248    @Override
10249    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10250        enforceNotIsolatedCaller("moveActivityTaskToBack");
10251        synchronized(this) {
10252            final long origId = Binder.clearCallingIdentity();
10253            try {
10254                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10255                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10256                if (task != null) {
10257                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10258                }
10259            } finally {
10260                Binder.restoreCallingIdentity(origId);
10261            }
10262        }
10263        return false;
10264    }
10265
10266    @Override
10267    public void moveTaskBackwards(int task) {
10268        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10269                "moveTaskBackwards()");
10270
10271        synchronized(this) {
10272            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10273                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10274                return;
10275            }
10276            final long origId = Binder.clearCallingIdentity();
10277            moveTaskBackwardsLocked(task);
10278            Binder.restoreCallingIdentity(origId);
10279        }
10280    }
10281
10282    private final void moveTaskBackwardsLocked(int task) {
10283        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10284    }
10285
10286    @Override
10287    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10288            IActivityContainerCallback callback) throws RemoteException {
10289        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10290        synchronized (this) {
10291            if (parentActivityToken == null) {
10292                throw new IllegalArgumentException("parent token must not be null");
10293            }
10294            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10295            if (r == null) {
10296                return null;
10297            }
10298            if (callback == null) {
10299                throw new IllegalArgumentException("callback must not be null");
10300            }
10301            return mStackSupervisor.createVirtualActivityContainer(r, callback);
10302        }
10303    }
10304
10305    @Override
10306    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10307        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10308        synchronized (this) {
10309            final int stackId = mStackSupervisor.getNextStackId();
10310            final ActivityStack stack =
10311                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10312            if (stack == null) {
10313                return null;
10314            }
10315            return stack.mActivityContainer;
10316        }
10317    }
10318
10319    @Override
10320    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10321        synchronized (this) {
10322            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10323            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10324                return stack.mActivityContainer.getDisplayId();
10325            }
10326            return DEFAULT_DISPLAY;
10327        }
10328    }
10329
10330    @Override
10331    public int getActivityStackId(IBinder token) throws RemoteException {
10332        synchronized (this) {
10333            ActivityStack stack = ActivityRecord.getStackLocked(token);
10334            if (stack == null) {
10335                return INVALID_STACK_ID;
10336            }
10337            return stack.mStackId;
10338        }
10339    }
10340
10341    @Override
10342    public void exitFreeformMode(IBinder token) throws RemoteException {
10343        synchronized (this) {
10344            long ident = Binder.clearCallingIdentity();
10345            try {
10346                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10347                if (r == null) {
10348                    throw new IllegalArgumentException(
10349                            "exitFreeformMode: No activity record matching token=" + token);
10350                }
10351
10352                final ActivityStack stack = r.getStack();
10353                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10354                    throw new IllegalStateException(
10355                            "exitFreeformMode: You can only go fullscreen from freeform.");
10356                }
10357
10358                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10359                r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10360                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10361            } finally {
10362                Binder.restoreCallingIdentity(ident);
10363            }
10364        }
10365    }
10366
10367    @Override
10368    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10369        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10370        if (StackId.isHomeOrRecentsStack(stackId)) {
10371            throw new IllegalArgumentException(
10372                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10373        }
10374        synchronized (this) {
10375            long ident = Binder.clearCallingIdentity();
10376            try {
10377                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10378                if (task == null) {
10379                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10380                    return;
10381                }
10382
10383                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10384                        + " to stackId=" + stackId + " toTop=" + toTop);
10385                if (stackId == DOCKED_STACK_ID) {
10386                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10387                            null /* initialBounds */);
10388                }
10389                task.reparent(stackId, toTop,
10390                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10391            } finally {
10392                Binder.restoreCallingIdentity(ident);
10393            }
10394        }
10395    }
10396
10397    @Override
10398    public void swapDockedAndFullscreenStack() throws RemoteException {
10399        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10400        synchronized (this) {
10401            long ident = Binder.clearCallingIdentity();
10402            try {
10403                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10404                        FULLSCREEN_WORKSPACE_STACK_ID);
10405                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10406                        : null;
10407                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10408                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10409                        : null;
10410                if (topTask == null || tasks == null || tasks.size() == 0) {
10411                    Slog.w(TAG,
10412                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10413                    return;
10414                }
10415
10416                // TODO: App transition
10417                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10418
10419                // Defer the resume until we move all the docked tasks to the fullscreen stack below
10420                topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10421                        DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10422                final int size = tasks.size();
10423                for (int i = 0; i < size; i++) {
10424                    final int id = tasks.get(i).taskId;
10425                    if (id == topTask.taskId) {
10426                        continue;
10427                    }
10428
10429                    // Defer the resume until after all the tasks have been moved
10430                    tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10431                            REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10432                            "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10433                }
10434
10435                // Because we deferred the resume to avoid conflicts with stack switches while
10436                // resuming, we need to do it after all the tasks are moved.
10437                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10438                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10439
10440                mWindowManager.executeAppTransition();
10441            } finally {
10442                Binder.restoreCallingIdentity(ident);
10443            }
10444        }
10445    }
10446
10447    /**
10448     * Moves the input task to the docked stack.
10449     *
10450     * @param taskId Id of task to move.
10451     * @param createMode The mode the docked stack should be created in if it doesn't exist
10452     *                   already. See
10453     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10454     *                   and
10455     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10456     * @param toTop If the task and stack should be moved to the top.
10457     * @param animate Whether we should play an animation for the moving the task
10458     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10459     *                      docked stack. Pass {@code null} to use default bounds.
10460     */
10461    @Override
10462    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10463            Rect initialBounds) {
10464        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10465        synchronized (this) {
10466            long ident = Binder.clearCallingIdentity();
10467            try {
10468                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10469                if (task == null) {
10470                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10471                    return false;
10472                }
10473
10474                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10475                        + " to createMode=" + createMode + " toTop=" + toTop);
10476                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10477
10478                // Defer resuming until we move the home stack to the front below
10479                final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10480                        REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10481                        "moveTaskToDockedStack");
10482                if (moved) {
10483                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10484                }
10485                return moved;
10486            } finally {
10487                Binder.restoreCallingIdentity(ident);
10488            }
10489        }
10490    }
10491
10492    /**
10493     * Moves the top activity in the input stackId to the pinned stack.
10494     *
10495     * @param stackId Id of stack to move the top activity to pinned stack.
10496     * @param bounds Bounds to use for pinned stack.
10497     *
10498     * @return True if the top activity of the input stack was successfully moved to the pinned
10499     *          stack.
10500     */
10501    @Override
10502    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10503        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10504        synchronized (this) {
10505            if (!mSupportsPictureInPicture) {
10506                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10507                        + "Device doesn't support picture-in-picture mode");
10508            }
10509
10510            long ident = Binder.clearCallingIdentity();
10511            try {
10512                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10513            } finally {
10514                Binder.restoreCallingIdentity(ident);
10515            }
10516        }
10517    }
10518
10519    @Override
10520    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10521            boolean preserveWindows, boolean animate, int animationDuration) {
10522        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10523        long ident = Binder.clearCallingIdentity();
10524        try {
10525            synchronized (this) {
10526                if (animate) {
10527                    if (stackId == PINNED_STACK_ID) {
10528                        final PinnedActivityStack pinnedStack =
10529                                mStackSupervisor.getStack(PINNED_STACK_ID);
10530                        if (pinnedStack != null) {
10531                            pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10532                                    destBounds, animationDuration,
10533                                    false /* schedulePipModeChangedOnAnimationEnd */);
10534                        }
10535                    } else {
10536                        throw new IllegalArgumentException("Stack: " + stackId
10537                                + " doesn't support animated resize.");
10538                    }
10539                } else {
10540                    mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10541                            null /* tempTaskInsetBounds */, preserveWindows,
10542                            allowResizeInDockedMode, !DEFER_RESUME);
10543                }
10544            }
10545        } finally {
10546            Binder.restoreCallingIdentity(ident);
10547        }
10548    }
10549
10550    @Override
10551    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10552            Rect tempDockedTaskInsetBounds,
10553            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10554        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10555                "resizeDockedStack()");
10556        long ident = Binder.clearCallingIdentity();
10557        try {
10558            synchronized (this) {
10559                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10560                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10561                        PRESERVE_WINDOWS);
10562            }
10563        } finally {
10564            Binder.restoreCallingIdentity(ident);
10565        }
10566    }
10567
10568    @Override
10569    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10570        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10571                "resizePinnedStack()");
10572        final long ident = Binder.clearCallingIdentity();
10573        try {
10574            synchronized (this) {
10575                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10576            }
10577        } finally {
10578            Binder.restoreCallingIdentity(ident);
10579        }
10580    }
10581
10582    /**
10583     * Try to place task to provided position. The final position might be different depending on
10584     * current user and stacks state. The task will be moved to target stack if it's currently in
10585     * different stack.
10586     */
10587    @Override
10588    public void positionTaskInStack(int taskId, int stackId, int position) {
10589        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10590        if (StackId.isHomeOrRecentsStack(stackId)) {
10591            throw new IllegalArgumentException(
10592                    "positionTaskInStack: Attempt to change the position of task "
10593                    + taskId + " in/to home/recents stack");
10594        }
10595        synchronized (this) {
10596            long ident = Binder.clearCallingIdentity();
10597            try {
10598                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10599                        + taskId + " in stackId=" + stackId + " at position=" + position);
10600                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10601                if (task == null) {
10602                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10603                            + taskId);
10604                }
10605
10606                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10607                        !ON_TOP);
10608
10609                // TODO: Have the callers of this API call a separate reparent method if that is
10610                // what they intended to do vs. having this method also do reparenting.
10611                if (task.getStack() == stack) {
10612                    // Change position in current stack.
10613                    stack.positionChildAt(task, position);
10614                } else {
10615                    // Reparent to new stack.
10616                    task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10617                            !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10618                }
10619            } finally {
10620                Binder.restoreCallingIdentity(ident);
10621            }
10622        }
10623    }
10624
10625    @Override
10626    public List<StackInfo> getAllStackInfos() {
10627        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10628        long ident = Binder.clearCallingIdentity();
10629        try {
10630            synchronized (this) {
10631                return mStackSupervisor.getAllStackInfosLocked();
10632            }
10633        } finally {
10634            Binder.restoreCallingIdentity(ident);
10635        }
10636    }
10637
10638    @Override
10639    public StackInfo getStackInfo(int stackId) {
10640        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10641        long ident = Binder.clearCallingIdentity();
10642        try {
10643            synchronized (this) {
10644                return mStackSupervisor.getStackInfoLocked(stackId);
10645            }
10646        } finally {
10647            Binder.restoreCallingIdentity(ident);
10648        }
10649    }
10650
10651    @Override
10652    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10653        synchronized(this) {
10654            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10655        }
10656    }
10657
10658    @Override
10659    public void updateDeviceOwner(String packageName) {
10660        final int callingUid = Binder.getCallingUid();
10661        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10662            throw new SecurityException("updateDeviceOwner called from non-system process");
10663        }
10664        synchronized (this) {
10665            mDeviceOwnerName = packageName;
10666        }
10667    }
10668
10669    @Override
10670    public void updateLockTaskPackages(int userId, String[] packages) {
10671        final int callingUid = Binder.getCallingUid();
10672        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10673            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10674                    "updateLockTaskPackages()");
10675        }
10676        synchronized (this) {
10677            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10678                    Arrays.toString(packages));
10679            mLockTaskPackages.put(userId, packages);
10680            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10681        }
10682    }
10683
10684
10685    void startLockTaskModeLocked(TaskRecord task) {
10686        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10687        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10688            return;
10689        }
10690
10691        // When a task is locked, dismiss the pinned stack if it exists
10692        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10693                PINNED_STACK_ID);
10694        if (pinnedStack != null) {
10695            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10696        }
10697
10698        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10699        // is initiated by system after the pinning request was shown and locked mode is initiated
10700        // by an authorized app directly
10701        final int callingUid = Binder.getCallingUid();
10702        boolean isSystemInitiated = callingUid == SYSTEM_UID;
10703        long ident = Binder.clearCallingIdentity();
10704        try {
10705            if (!isSystemInitiated) {
10706                task.mLockTaskUid = callingUid;
10707                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10708                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10709                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10710                    StatusBarManagerInternal statusBarManager =
10711                            LocalServices.getService(StatusBarManagerInternal.class);
10712                    if (statusBarManager != null) {
10713                        statusBarManager.showScreenPinningRequest(task.taskId);
10714                    }
10715                    return;
10716                }
10717
10718                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10719                if (stack == null || task != stack.topTask()) {
10720                    throw new IllegalArgumentException("Invalid task, not in foreground");
10721                }
10722            }
10723            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10724                    "Locking fully");
10725            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10726                    ActivityManager.LOCK_TASK_MODE_PINNED :
10727                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10728                    "startLockTask", true);
10729        } finally {
10730            Binder.restoreCallingIdentity(ident);
10731        }
10732    }
10733
10734    @Override
10735    public void startLockTaskModeById(int taskId) {
10736        synchronized (this) {
10737            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10738            if (task != null) {
10739                startLockTaskModeLocked(task);
10740            }
10741        }
10742    }
10743
10744    @Override
10745    public void startLockTaskModeByToken(IBinder token) {
10746        synchronized (this) {
10747            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10748            if (r == null) {
10749                return;
10750            }
10751            final TaskRecord task = r.getTask();
10752            if (task != null) {
10753                startLockTaskModeLocked(task);
10754            }
10755        }
10756    }
10757
10758    @Override
10759    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10760        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10761        // This makes inner call to look as if it was initiated by system.
10762        long ident = Binder.clearCallingIdentity();
10763        try {
10764            synchronized (this) {
10765                startLockTaskModeById(taskId);
10766            }
10767        } finally {
10768            Binder.restoreCallingIdentity(ident);
10769        }
10770    }
10771
10772    @Override
10773    public void stopLockTaskMode() {
10774        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10775        if (lockTask == null) {
10776            // Our work here is done.
10777            return;
10778        }
10779
10780        final int callingUid = Binder.getCallingUid();
10781        final int lockTaskUid = lockTask.mLockTaskUid;
10782        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10783        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10784            // Done.
10785            return;
10786        } else {
10787            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10788            // It is possible lockTaskMode was started by the system process because
10789            // android:lockTaskMode is set to a locking value in the application manifest
10790            // instead of the app calling startLockTaskMode. In this case
10791            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10792            // {@link TaskRecord.effectiveUid} instead. Also caller with
10793            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10794            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10795                    && callingUid != lockTaskUid
10796                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10797                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10798                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10799            }
10800        }
10801        long ident = Binder.clearCallingIdentity();
10802        try {
10803            Log.d(TAG, "stopLockTaskMode");
10804            // Stop lock task
10805            synchronized (this) {
10806                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10807                        "stopLockTask", true);
10808            }
10809            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10810            if (tm != null) {
10811                tm.showInCallScreen(false);
10812            }
10813        } finally {
10814            Binder.restoreCallingIdentity(ident);
10815        }
10816    }
10817
10818    /**
10819     * This API should be called by SystemUI only when user perform certain action to dismiss
10820     * lock task mode. We should only dismiss pinned lock task mode in this case.
10821     */
10822    @Override
10823    public void stopSystemLockTaskMode() throws RemoteException {
10824        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10825            stopLockTaskMode();
10826        } else {
10827            mStackSupervisor.showLockTaskToast();
10828        }
10829    }
10830
10831    @Override
10832    public boolean isInLockTaskMode() {
10833        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10834    }
10835
10836    @Override
10837    public int getLockTaskModeState() {
10838        synchronized (this) {
10839            return mStackSupervisor.getLockTaskModeState();
10840        }
10841    }
10842
10843    @Override
10844    public void showLockTaskEscapeMessage(IBinder token) {
10845        synchronized (this) {
10846            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10847            if (r == null) {
10848                return;
10849            }
10850            mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
10851        }
10852    }
10853
10854    @Override
10855    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
10856            throws RemoteException {
10857        synchronized (this) {
10858            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10859            if (r == null) {
10860                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
10861                        + token);
10862                return;
10863            }
10864            final long origId = Binder.clearCallingIdentity();
10865            try {
10866                r.setDisablePreviewScreenshots(disable);
10867            } finally {
10868                Binder.restoreCallingIdentity(origId);
10869            }
10870        }
10871    }
10872
10873    // =========================================================
10874    // CONTENT PROVIDERS
10875    // =========================================================
10876
10877    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10878        List<ProviderInfo> providers = null;
10879        try {
10880            providers = AppGlobals.getPackageManager()
10881                    .queryContentProviders(app.processName, app.uid,
10882                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10883                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
10884                    .getList();
10885        } catch (RemoteException ex) {
10886        }
10887        if (DEBUG_MU) Slog.v(TAG_MU,
10888                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10889        int userId = app.userId;
10890        if (providers != null) {
10891            int N = providers.size();
10892            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10893            for (int i=0; i<N; i++) {
10894                // TODO: keep logic in sync with installEncryptionUnawareProviders
10895                ProviderInfo cpi =
10896                    (ProviderInfo)providers.get(i);
10897                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10898                        cpi.name, cpi.flags);
10899                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10900                    // This is a singleton provider, but a user besides the
10901                    // default user is asking to initialize a process it runs
10902                    // in...  well, no, it doesn't actually run in this process,
10903                    // it runs in the process of the default user.  Get rid of it.
10904                    providers.remove(i);
10905                    N--;
10906                    i--;
10907                    continue;
10908                }
10909
10910                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10911                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10912                if (cpr == null) {
10913                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10914                    mProviderMap.putProviderByClass(comp, cpr);
10915                }
10916                if (DEBUG_MU) Slog.v(TAG_MU,
10917                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10918                app.pubProviders.put(cpi.name, cpr);
10919                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10920                    // Don't add this if it is a platform component that is marked
10921                    // to run in multiple processes, because this is actually
10922                    // part of the framework so doesn't make sense to track as a
10923                    // separate apk in the process.
10924                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10925                            mProcessStats);
10926                }
10927                notifyPackageUse(cpi.applicationInfo.packageName,
10928                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10929            }
10930        }
10931        return providers;
10932    }
10933
10934    /**
10935     * Check if the calling UID has a possible chance at accessing the provider
10936     * at the given authority and user.
10937     */
10938    public String checkContentProviderAccess(String authority, int userId) {
10939        if (userId == UserHandle.USER_ALL) {
10940            mContext.enforceCallingOrSelfPermission(
10941                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10942            userId = UserHandle.getCallingUserId();
10943        }
10944
10945        ProviderInfo cpi = null;
10946        try {
10947            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10948                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10949                            | PackageManager.MATCH_DISABLED_COMPONENTS
10950                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10951                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10952                    userId);
10953        } catch (RemoteException ignored) {
10954        }
10955        if (cpi == null) {
10956            return "Failed to find provider " + authority + " for user " + userId
10957                    + "; expected to find a valid ContentProvider for this authority";
10958        }
10959
10960        ProcessRecord r = null;
10961        synchronized (mPidsSelfLocked) {
10962            r = mPidsSelfLocked.get(Binder.getCallingPid());
10963        }
10964        if (r == null) {
10965            return "Failed to find PID " + Binder.getCallingPid();
10966        }
10967
10968        synchronized (this) {
10969            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10970        }
10971    }
10972
10973    /**
10974     * Check if {@link ProcessRecord} has a possible chance at accessing the
10975     * given {@link ProviderInfo}. Final permission checking is always done
10976     * in {@link ContentProvider}.
10977     */
10978    private final String checkContentProviderPermissionLocked(
10979            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10980        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10981        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10982        boolean checkedGrants = false;
10983        if (checkUser) {
10984            // Looking for cross-user grants before enforcing the typical cross-users permissions
10985            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10986            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10987                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10988                    return null;
10989                }
10990                checkedGrants = true;
10991            }
10992            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10993                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10994            if (userId != tmpTargetUserId) {
10995                // When we actually went to determine the final targer user ID, this ended
10996                // up different than our initial check for the authority.  This is because
10997                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10998                // SELF.  So we need to re-check the grants again.
10999                checkedGrants = false;
11000            }
11001        }
11002        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11003                cpi.applicationInfo.uid, cpi.exported)
11004                == PackageManager.PERMISSION_GRANTED) {
11005            return null;
11006        }
11007        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11008                cpi.applicationInfo.uid, cpi.exported)
11009                == PackageManager.PERMISSION_GRANTED) {
11010            return null;
11011        }
11012
11013        PathPermission[] pps = cpi.pathPermissions;
11014        if (pps != null) {
11015            int i = pps.length;
11016            while (i > 0) {
11017                i--;
11018                PathPermission pp = pps[i];
11019                String pprperm = pp.getReadPermission();
11020                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11021                        cpi.applicationInfo.uid, cpi.exported)
11022                        == PackageManager.PERMISSION_GRANTED) {
11023                    return null;
11024                }
11025                String ppwperm = pp.getWritePermission();
11026                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11027                        cpi.applicationInfo.uid, cpi.exported)
11028                        == PackageManager.PERMISSION_GRANTED) {
11029                    return null;
11030                }
11031            }
11032        }
11033        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11034            return null;
11035        }
11036
11037        final String suffix;
11038        if (!cpi.exported) {
11039            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11040        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11041            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11042        } else {
11043            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11044        }
11045        final String msg = "Permission Denial: opening provider " + cpi.name
11046                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11047                + ", uid=" + callingUid + ")" + suffix;
11048        Slog.w(TAG, msg);
11049        return msg;
11050    }
11051
11052    /**
11053     * Returns if the ContentProvider has granted a uri to callingUid
11054     */
11055    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11056        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11057        if (perms != null) {
11058            for (int i=perms.size()-1; i>=0; i--) {
11059                GrantUri grantUri = perms.keyAt(i);
11060                if (grantUri.sourceUserId == userId || !checkUser) {
11061                    if (matchesProvider(grantUri.uri, cpi)) {
11062                        return true;
11063                    }
11064                }
11065            }
11066        }
11067        return false;
11068    }
11069
11070    /**
11071     * Returns true if the uri authority is one of the authorities specified in the provider.
11072     */
11073    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11074        String uriAuth = uri.getAuthority();
11075        String cpiAuth = cpi.authority;
11076        if (cpiAuth.indexOf(';') == -1) {
11077            return cpiAuth.equals(uriAuth);
11078        }
11079        String[] cpiAuths = cpiAuth.split(";");
11080        int length = cpiAuths.length;
11081        for (int i = 0; i < length; i++) {
11082            if (cpiAuths[i].equals(uriAuth)) return true;
11083        }
11084        return false;
11085    }
11086
11087    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11088            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11089        if (r != null) {
11090            for (int i=0; i<r.conProviders.size(); i++) {
11091                ContentProviderConnection conn = r.conProviders.get(i);
11092                if (conn.provider == cpr) {
11093                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11094                            "Adding provider requested by "
11095                            + r.processName + " from process "
11096                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11097                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11098                    if (stable) {
11099                        conn.stableCount++;
11100                        conn.numStableIncs++;
11101                    } else {
11102                        conn.unstableCount++;
11103                        conn.numUnstableIncs++;
11104                    }
11105                    return conn;
11106                }
11107            }
11108            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11109            if (stable) {
11110                conn.stableCount = 1;
11111                conn.numStableIncs = 1;
11112            } else {
11113                conn.unstableCount = 1;
11114                conn.numUnstableIncs = 1;
11115            }
11116            cpr.connections.add(conn);
11117            r.conProviders.add(conn);
11118            startAssociationLocked(r.uid, r.processName, r.curProcState,
11119                    cpr.uid, cpr.name, cpr.info.processName);
11120            return conn;
11121        }
11122        cpr.addExternalProcessHandleLocked(externalProcessToken);
11123        return null;
11124    }
11125
11126    boolean decProviderCountLocked(ContentProviderConnection conn,
11127            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11128        if (conn != null) {
11129            cpr = conn.provider;
11130            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11131                    "Removing provider requested by "
11132                    + conn.client.processName + " from process "
11133                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11134                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11135            if (stable) {
11136                conn.stableCount--;
11137            } else {
11138                conn.unstableCount--;
11139            }
11140            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11141                cpr.connections.remove(conn);
11142                conn.client.conProviders.remove(conn);
11143                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11144                    // The client is more important than last activity -- note the time this
11145                    // is happening, so we keep the old provider process around a bit as last
11146                    // activity to avoid thrashing it.
11147                    if (cpr.proc != null) {
11148                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11149                    }
11150                }
11151                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11152                return true;
11153            }
11154            return false;
11155        }
11156        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11157        return false;
11158    }
11159
11160    private void checkTime(long startTime, String where) {
11161        long now = SystemClock.uptimeMillis();
11162        if ((now-startTime) > 50) {
11163            // If we are taking more than 50ms, log about it.
11164            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11165        }
11166    }
11167
11168    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11169            PROC_SPACE_TERM,
11170            PROC_SPACE_TERM|PROC_PARENS,
11171            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11172    };
11173
11174    private final long[] mProcessStateStatsLongs = new long[1];
11175
11176    boolean isProcessAliveLocked(ProcessRecord proc) {
11177        if (proc.procStatFile == null) {
11178            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11179        }
11180        mProcessStateStatsLongs[0] = 0;
11181        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11182                mProcessStateStatsLongs, null)) {
11183            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11184            return false;
11185        }
11186        final long state = mProcessStateStatsLongs[0];
11187        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11188                + (char)state);
11189        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11190    }
11191
11192    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11193            String name, IBinder token, boolean stable, int userId) {
11194        ContentProviderRecord cpr;
11195        ContentProviderConnection conn = null;
11196        ProviderInfo cpi = null;
11197
11198        synchronized(this) {
11199            long startTime = SystemClock.uptimeMillis();
11200
11201            ProcessRecord r = null;
11202            if (caller != null) {
11203                r = getRecordForAppLocked(caller);
11204                if (r == null) {
11205                    throw new SecurityException(
11206                            "Unable to find app for caller " + caller
11207                          + " (pid=" + Binder.getCallingPid()
11208                          + ") when getting content provider " + name);
11209                }
11210            }
11211
11212            boolean checkCrossUser = true;
11213
11214            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11215
11216            // First check if this content provider has been published...
11217            cpr = mProviderMap.getProviderByName(name, userId);
11218            // If that didn't work, check if it exists for user 0 and then
11219            // verify that it's a singleton provider before using it.
11220            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11221                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11222                if (cpr != null) {
11223                    cpi = cpr.info;
11224                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11225                            cpi.name, cpi.flags)
11226                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11227                        userId = UserHandle.USER_SYSTEM;
11228                        checkCrossUser = false;
11229                    } else {
11230                        cpr = null;
11231                        cpi = null;
11232                    }
11233                }
11234            }
11235
11236            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11237            if (providerRunning) {
11238                cpi = cpr.info;
11239                String msg;
11240                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11241                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11242                        != null) {
11243                    throw new SecurityException(msg);
11244                }
11245                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11246
11247                if (r != null && cpr.canRunHere(r)) {
11248                    // This provider has been published or is in the process
11249                    // of being published...  but it is also allowed to run
11250                    // in the caller's process, so don't make a connection
11251                    // and just let the caller instantiate its own instance.
11252                    ContentProviderHolder holder = cpr.newHolder(null);
11253                    // don't give caller the provider object, it needs
11254                    // to make its own.
11255                    holder.provider = null;
11256                    return holder;
11257                }
11258                // Don't expose providers between normal apps and instant apps
11259                try {
11260                    if (AppGlobals.getPackageManager()
11261                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11262                        return null;
11263                    }
11264                } catch (RemoteException e) {
11265                }
11266
11267                final long origId = Binder.clearCallingIdentity();
11268
11269                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11270
11271                // In this case the provider instance already exists, so we can
11272                // return it right away.
11273                conn = incProviderCountLocked(r, cpr, token, stable);
11274                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11275                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11276                        // If this is a perceptible app accessing the provider,
11277                        // make sure to count it as being accessed and thus
11278                        // back up on the LRU list.  This is good because
11279                        // content providers are often expensive to start.
11280                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11281                        updateLruProcessLocked(cpr.proc, false, null);
11282                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11283                    }
11284                }
11285
11286                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11287                final int verifiedAdj = cpr.proc.verifiedAdj;
11288                boolean success = updateOomAdjLocked(cpr.proc);
11289                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11290                // if the process has been successfully adjusted.  So to reduce races with
11291                // it, we will check whether the process still exists.  Note that this doesn't
11292                // completely get rid of races with LMK killing the process, but should make
11293                // them much smaller.
11294                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11295                    success = false;
11296                }
11297                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11298                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11299                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11300                // NOTE: there is still a race here where a signal could be
11301                // pending on the process even though we managed to update its
11302                // adj level.  Not sure what to do about this, but at least
11303                // the race is now smaller.
11304                if (!success) {
11305                    // Uh oh...  it looks like the provider's process
11306                    // has been killed on us.  We need to wait for a new
11307                    // process to be started, and make sure its death
11308                    // doesn't kill our process.
11309                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11310                            + " is crashing; detaching " + r);
11311                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11312                    checkTime(startTime, "getContentProviderImpl: before appDied");
11313                    appDiedLocked(cpr.proc);
11314                    checkTime(startTime, "getContentProviderImpl: after appDied");
11315                    if (!lastRef) {
11316                        // This wasn't the last ref our process had on
11317                        // the provider...  we have now been killed, bail.
11318                        return null;
11319                    }
11320                    providerRunning = false;
11321                    conn = null;
11322                } else {
11323                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11324                }
11325
11326                Binder.restoreCallingIdentity(origId);
11327            }
11328
11329            if (!providerRunning) {
11330                try {
11331                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11332                    cpi = AppGlobals.getPackageManager().
11333                        resolveContentProvider(name,
11334                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11335                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11336                } catch (RemoteException ex) {
11337                }
11338                if (cpi == null) {
11339                    return null;
11340                }
11341                // If the provider is a singleton AND
11342                // (it's a call within the same user || the provider is a
11343                // privileged app)
11344                // Then allow connecting to the singleton provider
11345                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11346                        cpi.name, cpi.flags)
11347                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11348                if (singleton) {
11349                    userId = UserHandle.USER_SYSTEM;
11350                }
11351                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11352                checkTime(startTime, "getContentProviderImpl: got app info for user");
11353
11354                String msg;
11355                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11356                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11357                        != null) {
11358                    throw new SecurityException(msg);
11359                }
11360                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11361
11362                if (!mProcessesReady
11363                        && !cpi.processName.equals("system")) {
11364                    // If this content provider does not run in the system
11365                    // process, and the system is not yet ready to run other
11366                    // processes, then fail fast instead of hanging.
11367                    throw new IllegalArgumentException(
11368                            "Attempt to launch content provider before system ready");
11369                }
11370
11371                // Make sure that the user who owns this provider is running.  If not,
11372                // we don't want to allow it to run.
11373                if (!mUserController.isUserRunningLocked(userId, 0)) {
11374                    Slog.w(TAG, "Unable to launch app "
11375                            + cpi.applicationInfo.packageName + "/"
11376                            + cpi.applicationInfo.uid + " for provider "
11377                            + name + ": user " + userId + " is stopped");
11378                    return null;
11379                }
11380
11381                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11382                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11383                cpr = mProviderMap.getProviderByClass(comp, userId);
11384                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11385                final boolean firstClass = cpr == null;
11386                if (firstClass) {
11387                    final long ident = Binder.clearCallingIdentity();
11388
11389                    // If permissions need a review before any of the app components can run,
11390                    // we return no provider and launch a review activity if the calling app
11391                    // is in the foreground.
11392                    if (mPermissionReviewRequired) {
11393                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11394                            return null;
11395                        }
11396                    }
11397
11398                    try {
11399                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11400                        ApplicationInfo ai =
11401                            AppGlobals.getPackageManager().
11402                                getApplicationInfo(
11403                                        cpi.applicationInfo.packageName,
11404                                        STOCK_PM_FLAGS, userId);
11405                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11406                        if (ai == null) {
11407                            Slog.w(TAG, "No package info for content provider "
11408                                    + cpi.name);
11409                            return null;
11410                        }
11411                        ai = getAppInfoForUser(ai, userId);
11412                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11413                    } catch (RemoteException ex) {
11414                        // pm is in same process, this will never happen.
11415                    } finally {
11416                        Binder.restoreCallingIdentity(ident);
11417                    }
11418                }
11419
11420                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11421
11422                if (r != null && cpr.canRunHere(r)) {
11423                    // If this is a multiprocess provider, then just return its
11424                    // info and allow the caller to instantiate it.  Only do
11425                    // this if the provider is the same user as the caller's
11426                    // process, or can run as root (so can be in any process).
11427                    return cpr.newHolder(null);
11428                }
11429
11430                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11431                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11432                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11433
11434                // This is single process, and our app is now connecting to it.
11435                // See if we are already in the process of launching this
11436                // provider.
11437                final int N = mLaunchingProviders.size();
11438                int i;
11439                for (i = 0; i < N; i++) {
11440                    if (mLaunchingProviders.get(i) == cpr) {
11441                        break;
11442                    }
11443                }
11444
11445                // If the provider is not already being launched, then get it
11446                // started.
11447                if (i >= N) {
11448                    final long origId = Binder.clearCallingIdentity();
11449
11450                    try {
11451                        // Content provider is now in use, its package can't be stopped.
11452                        try {
11453                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11454                            AppGlobals.getPackageManager().setPackageStoppedState(
11455                                    cpr.appInfo.packageName, false, userId);
11456                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11457                        } catch (RemoteException e) {
11458                        } catch (IllegalArgumentException e) {
11459                            Slog.w(TAG, "Failed trying to unstop package "
11460                                    + cpr.appInfo.packageName + ": " + e);
11461                        }
11462
11463                        // Use existing process if already started
11464                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11465                        ProcessRecord proc = getProcessRecordLocked(
11466                                cpi.processName, cpr.appInfo.uid, false);
11467                        if (proc != null && proc.thread != null && !proc.killed) {
11468                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11469                                    "Installing in existing process " + proc);
11470                            if (!proc.pubProviders.containsKey(cpi.name)) {
11471                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11472                                proc.pubProviders.put(cpi.name, cpr);
11473                                try {
11474                                    proc.thread.scheduleInstallProvider(cpi);
11475                                } catch (RemoteException e) {
11476                                }
11477                            }
11478                        } else {
11479                            checkTime(startTime, "getContentProviderImpl: before start process");
11480                            proc = startProcessLocked(cpi.processName,
11481                                    cpr.appInfo, false, 0, "content provider",
11482                                    new ComponentName(cpi.applicationInfo.packageName,
11483                                            cpi.name), false, false, false);
11484                            checkTime(startTime, "getContentProviderImpl: after start process");
11485                            if (proc == null) {
11486                                Slog.w(TAG, "Unable to launch app "
11487                                        + cpi.applicationInfo.packageName + "/"
11488                                        + cpi.applicationInfo.uid + " for provider "
11489                                        + name + ": process is bad");
11490                                return null;
11491                            }
11492                        }
11493                        cpr.launchingApp = proc;
11494                        mLaunchingProviders.add(cpr);
11495                    } finally {
11496                        Binder.restoreCallingIdentity(origId);
11497                    }
11498                }
11499
11500                checkTime(startTime, "getContentProviderImpl: updating data structures");
11501
11502                // Make sure the provider is published (the same provider class
11503                // may be published under multiple names).
11504                if (firstClass) {
11505                    mProviderMap.putProviderByClass(comp, cpr);
11506                }
11507
11508                mProviderMap.putProviderByName(name, cpr);
11509                conn = incProviderCountLocked(r, cpr, token, stable);
11510                if (conn != null) {
11511                    conn.waiting = true;
11512                }
11513            }
11514            checkTime(startTime, "getContentProviderImpl: done!");
11515
11516            grantEphemeralAccessLocked(userId, null /*intent*/,
11517                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11518        }
11519
11520        // Wait for the provider to be published...
11521        synchronized (cpr) {
11522            while (cpr.provider == null) {
11523                if (cpr.launchingApp == null) {
11524                    Slog.w(TAG, "Unable to launch app "
11525                            + cpi.applicationInfo.packageName + "/"
11526                            + cpi.applicationInfo.uid + " for provider "
11527                            + name + ": launching app became null");
11528                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11529                            UserHandle.getUserId(cpi.applicationInfo.uid),
11530                            cpi.applicationInfo.packageName,
11531                            cpi.applicationInfo.uid, name);
11532                    return null;
11533                }
11534                try {
11535                    if (DEBUG_MU) Slog.v(TAG_MU,
11536                            "Waiting to start provider " + cpr
11537                            + " launchingApp=" + cpr.launchingApp);
11538                    if (conn != null) {
11539                        conn.waiting = true;
11540                    }
11541                    cpr.wait();
11542                } catch (InterruptedException ex) {
11543                } finally {
11544                    if (conn != null) {
11545                        conn.waiting = false;
11546                    }
11547                }
11548            }
11549        }
11550        return cpr != null ? cpr.newHolder(conn) : null;
11551    }
11552
11553    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11554            ProcessRecord r, final int userId) {
11555        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11556                cpi.packageName, userId)) {
11557
11558            final boolean callerForeground = r == null || r.setSchedGroup
11559                    != ProcessList.SCHED_GROUP_BACKGROUND;
11560
11561            // Show a permission review UI only for starting from a foreground app
11562            if (!callerForeground) {
11563                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11564                        + cpi.packageName + " requires a permissions review");
11565                return false;
11566            }
11567
11568            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11569            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11570                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11571            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11572
11573            if (DEBUG_PERMISSIONS_REVIEW) {
11574                Slog.i(TAG, "u" + userId + " Launching permission review "
11575                        + "for package " + cpi.packageName);
11576            }
11577
11578            final UserHandle userHandle = new UserHandle(userId);
11579            mHandler.post(new Runnable() {
11580                @Override
11581                public void run() {
11582                    mContext.startActivityAsUser(intent, userHandle);
11583                }
11584            });
11585
11586            return false;
11587        }
11588
11589        return true;
11590    }
11591
11592    PackageManagerInternal getPackageManagerInternalLocked() {
11593        if (mPackageManagerInt == null) {
11594            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11595        }
11596        return mPackageManagerInt;
11597    }
11598
11599    @Override
11600    public final ContentProviderHolder getContentProvider(
11601            IApplicationThread caller, String name, int userId, boolean stable) {
11602        enforceNotIsolatedCaller("getContentProvider");
11603        if (caller == null) {
11604            String msg = "null IApplicationThread when getting content provider "
11605                    + name;
11606            Slog.w(TAG, msg);
11607            throw new SecurityException(msg);
11608        }
11609        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11610        // with cross-user grant.
11611        return getContentProviderImpl(caller, name, null, stable, userId);
11612    }
11613
11614    public ContentProviderHolder getContentProviderExternal(
11615            String name, int userId, IBinder token) {
11616        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11617            "Do not have permission in call getContentProviderExternal()");
11618        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11619                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11620        return getContentProviderExternalUnchecked(name, token, userId);
11621    }
11622
11623    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11624            IBinder token, int userId) {
11625        return getContentProviderImpl(null, name, token, true, userId);
11626    }
11627
11628    /**
11629     * Drop a content provider from a ProcessRecord's bookkeeping
11630     */
11631    public void removeContentProvider(IBinder connection, boolean stable) {
11632        enforceNotIsolatedCaller("removeContentProvider");
11633        long ident = Binder.clearCallingIdentity();
11634        try {
11635            synchronized (this) {
11636                ContentProviderConnection conn;
11637                try {
11638                    conn = (ContentProviderConnection)connection;
11639                } catch (ClassCastException e) {
11640                    String msg ="removeContentProvider: " + connection
11641                            + " not a ContentProviderConnection";
11642                    Slog.w(TAG, msg);
11643                    throw new IllegalArgumentException(msg);
11644                }
11645                if (conn == null) {
11646                    throw new NullPointerException("connection is null");
11647                }
11648                if (decProviderCountLocked(conn, null, null, stable)) {
11649                    updateOomAdjLocked();
11650                }
11651            }
11652        } finally {
11653            Binder.restoreCallingIdentity(ident);
11654        }
11655    }
11656
11657    public void removeContentProviderExternal(String name, IBinder token) {
11658        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11659            "Do not have permission in call removeContentProviderExternal()");
11660        int userId = UserHandle.getCallingUserId();
11661        long ident = Binder.clearCallingIdentity();
11662        try {
11663            removeContentProviderExternalUnchecked(name, token, userId);
11664        } finally {
11665            Binder.restoreCallingIdentity(ident);
11666        }
11667    }
11668
11669    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11670        synchronized (this) {
11671            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11672            if(cpr == null) {
11673                //remove from mProvidersByClass
11674                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11675                return;
11676            }
11677
11678            //update content provider record entry info
11679            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11680            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11681            if (localCpr.hasExternalProcessHandles()) {
11682                if (localCpr.removeExternalProcessHandleLocked(token)) {
11683                    updateOomAdjLocked();
11684                } else {
11685                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11686                            + " with no external reference for token: "
11687                            + token + ".");
11688                }
11689            } else {
11690                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11691                        + " with no external references.");
11692            }
11693        }
11694    }
11695
11696    public final void publishContentProviders(IApplicationThread caller,
11697            List<ContentProviderHolder> providers) {
11698        if (providers == null) {
11699            return;
11700        }
11701
11702        enforceNotIsolatedCaller("publishContentProviders");
11703        synchronized (this) {
11704            final ProcessRecord r = getRecordForAppLocked(caller);
11705            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11706            if (r == null) {
11707                throw new SecurityException(
11708                        "Unable to find app for caller " + caller
11709                      + " (pid=" + Binder.getCallingPid()
11710                      + ") when publishing content providers");
11711            }
11712
11713            final long origId = Binder.clearCallingIdentity();
11714
11715            final int N = providers.size();
11716            for (int i = 0; i < N; i++) {
11717                ContentProviderHolder src = providers.get(i);
11718                if (src == null || src.info == null || src.provider == null) {
11719                    continue;
11720                }
11721                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11722                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11723                if (dst != null) {
11724                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11725                    mProviderMap.putProviderByClass(comp, dst);
11726                    String names[] = dst.info.authority.split(";");
11727                    for (int j = 0; j < names.length; j++) {
11728                        mProviderMap.putProviderByName(names[j], dst);
11729                    }
11730
11731                    int launchingCount = mLaunchingProviders.size();
11732                    int j;
11733                    boolean wasInLaunchingProviders = false;
11734                    for (j = 0; j < launchingCount; j++) {
11735                        if (mLaunchingProviders.get(j) == dst) {
11736                            mLaunchingProviders.remove(j);
11737                            wasInLaunchingProviders = true;
11738                            j--;
11739                            launchingCount--;
11740                        }
11741                    }
11742                    if (wasInLaunchingProviders) {
11743                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11744                    }
11745                    synchronized (dst) {
11746                        dst.provider = src.provider;
11747                        dst.proc = r;
11748                        dst.notifyAll();
11749                    }
11750                    updateOomAdjLocked(r);
11751                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11752                            src.info.authority);
11753                }
11754            }
11755
11756            Binder.restoreCallingIdentity(origId);
11757        }
11758    }
11759
11760    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11761        ContentProviderConnection conn;
11762        try {
11763            conn = (ContentProviderConnection)connection;
11764        } catch (ClassCastException e) {
11765            String msg ="refContentProvider: " + connection
11766                    + " not a ContentProviderConnection";
11767            Slog.w(TAG, msg);
11768            throw new IllegalArgumentException(msg);
11769        }
11770        if (conn == null) {
11771            throw new NullPointerException("connection is null");
11772        }
11773
11774        synchronized (this) {
11775            if (stable > 0) {
11776                conn.numStableIncs += stable;
11777            }
11778            stable = conn.stableCount + stable;
11779            if (stable < 0) {
11780                throw new IllegalStateException("stableCount < 0: " + stable);
11781            }
11782
11783            if (unstable > 0) {
11784                conn.numUnstableIncs += unstable;
11785            }
11786            unstable = conn.unstableCount + unstable;
11787            if (unstable < 0) {
11788                throw new IllegalStateException("unstableCount < 0: " + unstable);
11789            }
11790
11791            if ((stable+unstable) <= 0) {
11792                throw new IllegalStateException("ref counts can't go to zero here: stable="
11793                        + stable + " unstable=" + unstable);
11794            }
11795            conn.stableCount = stable;
11796            conn.unstableCount = unstable;
11797            return !conn.dead;
11798        }
11799    }
11800
11801    public void unstableProviderDied(IBinder connection) {
11802        ContentProviderConnection conn;
11803        try {
11804            conn = (ContentProviderConnection)connection;
11805        } catch (ClassCastException e) {
11806            String msg ="refContentProvider: " + connection
11807                    + " not a ContentProviderConnection";
11808            Slog.w(TAG, msg);
11809            throw new IllegalArgumentException(msg);
11810        }
11811        if (conn == null) {
11812            throw new NullPointerException("connection is null");
11813        }
11814
11815        // Safely retrieve the content provider associated with the connection.
11816        IContentProvider provider;
11817        synchronized (this) {
11818            provider = conn.provider.provider;
11819        }
11820
11821        if (provider == null) {
11822            // Um, yeah, we're way ahead of you.
11823            return;
11824        }
11825
11826        // Make sure the caller is being honest with us.
11827        if (provider.asBinder().pingBinder()) {
11828            // Er, no, still looks good to us.
11829            synchronized (this) {
11830                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11831                        + " says " + conn + " died, but we don't agree");
11832                return;
11833            }
11834        }
11835
11836        // Well look at that!  It's dead!
11837        synchronized (this) {
11838            if (conn.provider.provider != provider) {
11839                // But something changed...  good enough.
11840                return;
11841            }
11842
11843            ProcessRecord proc = conn.provider.proc;
11844            if (proc == null || proc.thread == null) {
11845                // Seems like the process is already cleaned up.
11846                return;
11847            }
11848
11849            // As far as we're concerned, this is just like receiving a
11850            // death notification...  just a bit prematurely.
11851            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11852                    + ") early provider death");
11853            final long ident = Binder.clearCallingIdentity();
11854            try {
11855                appDiedLocked(proc);
11856            } finally {
11857                Binder.restoreCallingIdentity(ident);
11858            }
11859        }
11860    }
11861
11862    @Override
11863    public void appNotRespondingViaProvider(IBinder connection) {
11864        enforceCallingPermission(
11865                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11866
11867        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11868        if (conn == null) {
11869            Slog.w(TAG, "ContentProviderConnection is null");
11870            return;
11871        }
11872
11873        final ProcessRecord host = conn.provider.proc;
11874        if (host == null) {
11875            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11876            return;
11877        }
11878
11879        mHandler.post(new Runnable() {
11880            @Override
11881            public void run() {
11882                mAppErrors.appNotResponding(host, null, null, false,
11883                        "ContentProvider not responding");
11884            }
11885        });
11886    }
11887
11888    public final void installSystemProviders() {
11889        List<ProviderInfo> providers;
11890        synchronized (this) {
11891            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
11892            providers = generateApplicationProvidersLocked(app);
11893            if (providers != null) {
11894                for (int i=providers.size()-1; i>=0; i--) {
11895                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11896                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11897                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11898                                + ": not system .apk");
11899                        providers.remove(i);
11900                    }
11901                }
11902            }
11903        }
11904        if (providers != null) {
11905            mSystemThread.installSystemProviders(providers);
11906        }
11907
11908        mConstants.start(mContext.getContentResolver());
11909        mCoreSettingsObserver = new CoreSettingsObserver(this);
11910        mFontScaleSettingObserver = new FontScaleSettingObserver();
11911
11912        // Now that the settings provider is published we can consider sending
11913        // in a rescue party.
11914        RescueParty.onSettingsProviderPublished(mContext);
11915
11916        //mUsageStatsService.monitorPackages();
11917    }
11918
11919    private void startPersistentApps(int matchFlags) {
11920        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11921
11922        synchronized (this) {
11923            try {
11924                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11925                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11926                for (ApplicationInfo app : apps) {
11927                    if (!"android".equals(app.packageName)) {
11928                        addAppLocked(app, null, false, null /* ABI override */);
11929                    }
11930                }
11931            } catch (RemoteException ex) {
11932            }
11933        }
11934    }
11935
11936    /**
11937     * When a user is unlocked, we need to install encryption-unaware providers
11938     * belonging to any running apps.
11939     */
11940    private void installEncryptionUnawareProviders(int userId) {
11941        // We're only interested in providers that are encryption unaware, and
11942        // we don't care about uninstalled apps, since there's no way they're
11943        // running at this point.
11944        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11945
11946        synchronized (this) {
11947            final int NP = mProcessNames.getMap().size();
11948            for (int ip = 0; ip < NP; ip++) {
11949                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11950                final int NA = apps.size();
11951                for (int ia = 0; ia < NA; ia++) {
11952                    final ProcessRecord app = apps.valueAt(ia);
11953                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11954
11955                    final int NG = app.pkgList.size();
11956                    for (int ig = 0; ig < NG; ig++) {
11957                        try {
11958                            final String pkgName = app.pkgList.keyAt(ig);
11959                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11960                                    .getPackageInfo(pkgName, matchFlags, userId);
11961                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11962                                for (ProviderInfo pi : pkgInfo.providers) {
11963                                    // TODO: keep in sync with generateApplicationProvidersLocked
11964                                    final boolean processMatch = Objects.equals(pi.processName,
11965                                            app.processName) || pi.multiprocess;
11966                                    final boolean userMatch = isSingleton(pi.processName,
11967                                            pi.applicationInfo, pi.name, pi.flags)
11968                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11969                                    if (processMatch && userMatch) {
11970                                        Log.v(TAG, "Installing " + pi);
11971                                        app.thread.scheduleInstallProvider(pi);
11972                                    } else {
11973                                        Log.v(TAG, "Skipping " + pi);
11974                                    }
11975                                }
11976                            }
11977                        } catch (RemoteException ignored) {
11978                        }
11979                    }
11980                }
11981            }
11982        }
11983    }
11984
11985    /**
11986     * Allows apps to retrieve the MIME type of a URI.
11987     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11988     * users, then it does not need permission to access the ContentProvider.
11989     * Either, it needs cross-user uri grants.
11990     *
11991     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11992     *
11993     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11994     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11995     */
11996    public String getProviderMimeType(Uri uri, int userId) {
11997        enforceNotIsolatedCaller("getProviderMimeType");
11998        final String name = uri.getAuthority();
11999        int callingUid = Binder.getCallingUid();
12000        int callingPid = Binder.getCallingPid();
12001        long ident = 0;
12002        boolean clearedIdentity = false;
12003        synchronized (this) {
12004            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12005        }
12006        if (canClearIdentity(callingPid, callingUid, userId)) {
12007            clearedIdentity = true;
12008            ident = Binder.clearCallingIdentity();
12009        }
12010        ContentProviderHolder holder = null;
12011        try {
12012            holder = getContentProviderExternalUnchecked(name, null, userId);
12013            if (holder != null) {
12014                return holder.provider.getType(uri);
12015            }
12016        } catch (RemoteException e) {
12017            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12018            return null;
12019        } catch (Exception e) {
12020            Log.w(TAG, "Exception while determining type of " + uri, e);
12021            return null;
12022        } finally {
12023            // We need to clear the identity to call removeContentProviderExternalUnchecked
12024            if (!clearedIdentity) {
12025                ident = Binder.clearCallingIdentity();
12026            }
12027            try {
12028                if (holder != null) {
12029                    removeContentProviderExternalUnchecked(name, null, userId);
12030                }
12031            } finally {
12032                Binder.restoreCallingIdentity(ident);
12033            }
12034        }
12035
12036        return null;
12037    }
12038
12039    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12040        if (UserHandle.getUserId(callingUid) == userId) {
12041            return true;
12042        }
12043        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12044                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12045                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12046                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12047                return true;
12048        }
12049        return false;
12050    }
12051
12052    // =========================================================
12053    // GLOBAL MANAGEMENT
12054    // =========================================================
12055
12056    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12057            boolean isolated, int isolatedUid) {
12058        String proc = customProcess != null ? customProcess : info.processName;
12059        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12060        final int userId = UserHandle.getUserId(info.uid);
12061        int uid = info.uid;
12062        if (isolated) {
12063            if (isolatedUid == 0) {
12064                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12065                while (true) {
12066                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12067                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12068                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12069                    }
12070                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12071                    mNextIsolatedProcessUid++;
12072                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12073                        // No process for this uid, use it.
12074                        break;
12075                    }
12076                    stepsLeft--;
12077                    if (stepsLeft <= 0) {
12078                        return null;
12079                    }
12080                }
12081            } else {
12082                // Special case for startIsolatedProcess (internal only), where
12083                // the uid of the isolated process is specified by the caller.
12084                uid = isolatedUid;
12085            }
12086            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12087
12088            // Register the isolated UID with this application so BatteryStats knows to
12089            // attribute resource usage to the application.
12090            //
12091            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12092            // about the process state of the isolated UID *before* it is registered with the
12093            // owning application.
12094            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12095        }
12096        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12097        if (!mBooted && !mBooting
12098                && userId == UserHandle.USER_SYSTEM
12099                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12100            r.persistent = true;
12101            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12102        }
12103        addProcessNameLocked(r);
12104        return r;
12105    }
12106
12107    private boolean uidOnBackgroundWhitelist(final int uid) {
12108        final int appId = UserHandle.getAppId(uid);
12109        final int[] whitelist = mBackgroundAppIdWhitelist;
12110        final int N = whitelist.length;
12111        for (int i = 0; i < N; i++) {
12112            if (appId == whitelist[i]) {
12113                return true;
12114            }
12115        }
12116        return false;
12117    }
12118
12119    @Override
12120    public void backgroundWhitelistUid(final int uid) {
12121        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12122            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12123        }
12124
12125        if (DEBUG_BACKGROUND_CHECK) {
12126            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12127        }
12128        synchronized (this) {
12129            final int N = mBackgroundAppIdWhitelist.length;
12130            int[] newList = new int[N+1];
12131            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12132            newList[N] = UserHandle.getAppId(uid);
12133            mBackgroundAppIdWhitelist = newList;
12134        }
12135    }
12136
12137    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12138            String abiOverride) {
12139        ProcessRecord app;
12140        if (!isolated) {
12141            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12142                    info.uid, true);
12143        } else {
12144            app = null;
12145        }
12146
12147        if (app == null) {
12148            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12149            updateLruProcessLocked(app, false, null);
12150            updateOomAdjLocked();
12151        }
12152
12153        // This package really, really can not be stopped.
12154        try {
12155            AppGlobals.getPackageManager().setPackageStoppedState(
12156                    info.packageName, false, UserHandle.getUserId(app.uid));
12157        } catch (RemoteException e) {
12158        } catch (IllegalArgumentException e) {
12159            Slog.w(TAG, "Failed trying to unstop package "
12160                    + info.packageName + ": " + e);
12161        }
12162
12163        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12164            app.persistent = true;
12165            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12166        }
12167        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12168            mPersistentStartingProcesses.add(app);
12169            startProcessLocked(app, "added application",
12170                    customProcess != null ? customProcess : app.processName, abiOverride,
12171                    null /* entryPoint */, null /* entryPointArgs */);
12172        }
12173
12174        return app;
12175    }
12176
12177    public void unhandledBack() {
12178        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12179                "unhandledBack()");
12180
12181        synchronized(this) {
12182            final long origId = Binder.clearCallingIdentity();
12183            try {
12184                getFocusedStack().unhandledBackLocked();
12185            } finally {
12186                Binder.restoreCallingIdentity(origId);
12187            }
12188        }
12189    }
12190
12191    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12192        enforceNotIsolatedCaller("openContentUri");
12193        final int userId = UserHandle.getCallingUserId();
12194        final Uri uri = Uri.parse(uriString);
12195        String name = uri.getAuthority();
12196        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12197        ParcelFileDescriptor pfd = null;
12198        if (cph != null) {
12199            // We record the binder invoker's uid in thread-local storage before
12200            // going to the content provider to open the file.  Later, in the code
12201            // that handles all permissions checks, we look for this uid and use
12202            // that rather than the Activity Manager's own uid.  The effect is that
12203            // we do the check against the caller's permissions even though it looks
12204            // to the content provider like the Activity Manager itself is making
12205            // the request.
12206            Binder token = new Binder();
12207            sCallerIdentity.set(new Identity(
12208                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12209            try {
12210                pfd = cph.provider.openFile(null, uri, "r", null, token);
12211            } catch (FileNotFoundException e) {
12212                // do nothing; pfd will be returned null
12213            } finally {
12214                // Ensure that whatever happens, we clean up the identity state
12215                sCallerIdentity.remove();
12216                // Ensure we're done with the provider.
12217                removeContentProviderExternalUnchecked(name, null, userId);
12218            }
12219        } else {
12220            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12221        }
12222        return pfd;
12223    }
12224
12225    // Actually is sleeping or shutting down or whatever else in the future
12226    // is an inactive state.
12227    boolean isSleepingOrShuttingDownLocked() {
12228        return isSleepingLocked() || mShuttingDown;
12229    }
12230
12231    boolean isShuttingDownLocked() {
12232        return mShuttingDown;
12233    }
12234
12235    boolean isSleepingLocked() {
12236        return mSleeping;
12237    }
12238
12239    void onWakefulnessChanged(int wakefulness) {
12240        synchronized(this) {
12241            mWakefulness = wakefulness;
12242            updateSleepIfNeededLocked();
12243        }
12244    }
12245
12246    void finishRunningVoiceLocked() {
12247        if (mRunningVoice != null) {
12248            mRunningVoice = null;
12249            mVoiceWakeLock.release();
12250            updateSleepIfNeededLocked();
12251        }
12252    }
12253
12254    void startTimeTrackingFocusedActivityLocked() {
12255        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12256        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12257            mCurAppTimeTracker.start(resumedActivity.packageName);
12258        }
12259    }
12260
12261    void updateSleepIfNeededLocked() {
12262        if (mSleeping && !shouldSleepLocked()) {
12263            mSleeping = false;
12264            startTimeTrackingFocusedActivityLocked();
12265            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12266            mStackSupervisor.comeOutOfSleepIfNeededLocked();
12267            sendNotifyVrManagerOfSleepState(false);
12268            updateOomAdjLocked();
12269        } else if (!mSleeping && shouldSleepLocked()) {
12270            mSleeping = true;
12271            if (mCurAppTimeTracker != null) {
12272                mCurAppTimeTracker.stop();
12273            }
12274            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12275            mStackSupervisor.goingToSleepLocked();
12276            sendNotifyVrManagerOfSleepState(true);
12277            updateOomAdjLocked();
12278
12279            // Initialize the wake times of all processes.
12280            checkExcessivePowerUsageLocked(false);
12281            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12282            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12283            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
12284        }
12285    }
12286
12287    private boolean shouldSleepLocked() {
12288        // Resume applications while running a voice interactor.
12289        if (mRunningVoice != null) {
12290            return false;
12291        }
12292
12293        // TODO: Transform the lock screen state into a sleep token instead.
12294        switch (mWakefulness) {
12295            case PowerManagerInternal.WAKEFULNESS_AWAKE:
12296            case PowerManagerInternal.WAKEFULNESS_DREAMING:
12297            case PowerManagerInternal.WAKEFULNESS_DOZING:
12298                // Pause applications whenever the lock screen is shown or any sleep
12299                // tokens have been acquired.
12300                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12301            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12302            default:
12303                // If we're asleep then pause applications unconditionally.
12304                return true;
12305        }
12306    }
12307
12308    /** Pokes the task persister. */
12309    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12310        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12311    }
12312
12313    /**
12314     * Notifies all listeners when the pinned stack animation starts.
12315     */
12316    @Override
12317    public void notifyPinnedStackAnimationStarted() {
12318        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12319    }
12320
12321    /**
12322     * Notifies all listeners when the pinned stack animation ends.
12323     */
12324    @Override
12325    public void notifyPinnedStackAnimationEnded() {
12326        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12327    }
12328
12329    @Override
12330    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12331        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12332    }
12333
12334    @Override
12335    public boolean shutdown(int timeout) {
12336        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12337                != PackageManager.PERMISSION_GRANTED) {
12338            throw new SecurityException("Requires permission "
12339                    + android.Manifest.permission.SHUTDOWN);
12340        }
12341
12342        boolean timedout = false;
12343
12344        synchronized(this) {
12345            mShuttingDown = true;
12346            updateEventDispatchingLocked();
12347            timedout = mStackSupervisor.shutdownLocked(timeout);
12348        }
12349
12350        mAppOpsService.shutdown();
12351        if (mUsageStatsService != null) {
12352            mUsageStatsService.prepareShutdown();
12353        }
12354        mBatteryStatsService.shutdown();
12355        synchronized (this) {
12356            mProcessStats.shutdownLocked();
12357            notifyTaskPersisterLocked(null, true);
12358        }
12359
12360        return timedout;
12361    }
12362
12363    public final void activitySlept(IBinder token) {
12364        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12365
12366        final long origId = Binder.clearCallingIdentity();
12367
12368        synchronized (this) {
12369            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12370            if (r != null) {
12371                mStackSupervisor.activitySleptLocked(r);
12372            }
12373        }
12374
12375        Binder.restoreCallingIdentity(origId);
12376    }
12377
12378    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12379        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12380        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12381        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12382            boolean wasRunningVoice = mRunningVoice != null;
12383            mRunningVoice = session;
12384            if (!wasRunningVoice) {
12385                mVoiceWakeLock.acquire();
12386                updateSleepIfNeededLocked();
12387            }
12388        }
12389    }
12390
12391    private void updateEventDispatchingLocked() {
12392        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12393    }
12394
12395    @Override
12396    public void setLockScreenShown(boolean showing) {
12397        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12398                != PackageManager.PERMISSION_GRANTED) {
12399            throw new SecurityException("Requires permission "
12400                    + android.Manifest.permission.DEVICE_POWER);
12401        }
12402
12403        synchronized(this) {
12404            long ident = Binder.clearCallingIdentity();
12405            try {
12406                mKeyguardController.setKeyguardShown(showing);
12407            } finally {
12408                Binder.restoreCallingIdentity(ident);
12409            }
12410        }
12411    }
12412
12413    @Override
12414    public void notifyLockedProfile(@UserIdInt int userId) {
12415        try {
12416            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12417                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12418            }
12419        } catch (RemoteException ex) {
12420            throw new SecurityException("Fail to check is caller a privileged app", ex);
12421        }
12422
12423        synchronized (this) {
12424            final long ident = Binder.clearCallingIdentity();
12425            try {
12426                if (mUserController.shouldConfirmCredentials(userId)) {
12427                    if (mKeyguardController.isKeyguardLocked()) {
12428                        // Showing launcher to avoid user entering credential twice.
12429                        final int currentUserId = mUserController.getCurrentUserIdLocked();
12430                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12431                    }
12432                    mStackSupervisor.lockAllProfileTasks(userId);
12433                }
12434            } finally {
12435                Binder.restoreCallingIdentity(ident);
12436            }
12437        }
12438    }
12439
12440    @Override
12441    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12442        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12443        synchronized (this) {
12444            final long ident = Binder.clearCallingIdentity();
12445            try {
12446                mActivityStarter.startConfirmCredentialIntent(intent, options);
12447            } finally {
12448                Binder.restoreCallingIdentity(ident);
12449            }
12450        }
12451    }
12452
12453    @Override
12454    public void stopAppSwitches() {
12455        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12456                != PackageManager.PERMISSION_GRANTED) {
12457            throw new SecurityException("viewquires permission "
12458                    + android.Manifest.permission.STOP_APP_SWITCHES);
12459        }
12460
12461        synchronized(this) {
12462            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12463                    + APP_SWITCH_DELAY_TIME;
12464            mDidAppSwitch = false;
12465            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12466            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12467            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12468        }
12469    }
12470
12471    public void resumeAppSwitches() {
12472        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12473                != PackageManager.PERMISSION_GRANTED) {
12474            throw new SecurityException("Requires permission "
12475                    + android.Manifest.permission.STOP_APP_SWITCHES);
12476        }
12477
12478        synchronized(this) {
12479            // Note that we don't execute any pending app switches... we will
12480            // let those wait until either the timeout, or the next start
12481            // activity request.
12482            mAppSwitchesAllowedTime = 0;
12483        }
12484    }
12485
12486    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12487            int callingPid, int callingUid, String name) {
12488        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12489            return true;
12490        }
12491
12492        int perm = checkComponentPermission(
12493                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12494                sourceUid, -1, true);
12495        if (perm == PackageManager.PERMISSION_GRANTED) {
12496            return true;
12497        }
12498
12499        // If the actual IPC caller is different from the logical source, then
12500        // also see if they are allowed to control app switches.
12501        if (callingUid != -1 && callingUid != sourceUid) {
12502            perm = checkComponentPermission(
12503                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12504                    callingUid, -1, true);
12505            if (perm == PackageManager.PERMISSION_GRANTED) {
12506                return true;
12507            }
12508        }
12509
12510        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12511        return false;
12512    }
12513
12514    public void setDebugApp(String packageName, boolean waitForDebugger,
12515            boolean persistent) {
12516        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12517                "setDebugApp()");
12518
12519        long ident = Binder.clearCallingIdentity();
12520        try {
12521            // Note that this is not really thread safe if there are multiple
12522            // callers into it at the same time, but that's not a situation we
12523            // care about.
12524            if (persistent) {
12525                final ContentResolver resolver = mContext.getContentResolver();
12526                Settings.Global.putString(
12527                    resolver, Settings.Global.DEBUG_APP,
12528                    packageName);
12529                Settings.Global.putInt(
12530                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12531                    waitForDebugger ? 1 : 0);
12532            }
12533
12534            synchronized (this) {
12535                if (!persistent) {
12536                    mOrigDebugApp = mDebugApp;
12537                    mOrigWaitForDebugger = mWaitForDebugger;
12538                }
12539                mDebugApp = packageName;
12540                mWaitForDebugger = waitForDebugger;
12541                mDebugTransient = !persistent;
12542                if (packageName != null) {
12543                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12544                            false, UserHandle.USER_ALL, "set debug app");
12545                }
12546            }
12547        } finally {
12548            Binder.restoreCallingIdentity(ident);
12549        }
12550    }
12551
12552    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12553        synchronized (this) {
12554            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12555            if (!isDebuggable) {
12556                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12557                    throw new SecurityException("Process not debuggable: " + app.packageName);
12558                }
12559            }
12560
12561            mTrackAllocationApp = processName;
12562        }
12563    }
12564
12565    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12566        synchronized (this) {
12567            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12568            if (!isDebuggable) {
12569                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12570                    throw new SecurityException("Process not debuggable: " + app.packageName);
12571                }
12572            }
12573            mProfileApp = processName;
12574            mProfileFile = profilerInfo.profileFile;
12575            if (mProfileFd != null) {
12576                try {
12577                    mProfileFd.close();
12578                } catch (IOException e) {
12579                }
12580                mProfileFd = null;
12581            }
12582            mProfileFd = profilerInfo.profileFd;
12583            mSamplingInterval = profilerInfo.samplingInterval;
12584            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12585            mStreamingOutput = profilerInfo.streamingOutput;
12586            mProfileType = 0;
12587        }
12588    }
12589
12590    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12591        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12592        if (!isDebuggable) {
12593            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12594                throw new SecurityException("Process not debuggable: " + app.packageName);
12595            }
12596        }
12597        mNativeDebuggingApp = processName;
12598    }
12599
12600    @Override
12601    public void setAlwaysFinish(boolean enabled) {
12602        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12603                "setAlwaysFinish()");
12604
12605        long ident = Binder.clearCallingIdentity();
12606        try {
12607            Settings.Global.putInt(
12608                    mContext.getContentResolver(),
12609                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12610
12611            synchronized (this) {
12612                mAlwaysFinishActivities = enabled;
12613            }
12614        } finally {
12615            Binder.restoreCallingIdentity(ident);
12616        }
12617    }
12618
12619    @Override
12620    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12621        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12622                "setActivityController()");
12623        synchronized (this) {
12624            mController = controller;
12625            mControllerIsAMonkey = imAMonkey;
12626            Watchdog.getInstance().setActivityController(controller);
12627        }
12628    }
12629
12630    @Override
12631    public void setUserIsMonkey(boolean userIsMonkey) {
12632        synchronized (this) {
12633            synchronized (mPidsSelfLocked) {
12634                final int callingPid = Binder.getCallingPid();
12635                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12636                if (proc == null) {
12637                    throw new SecurityException("Unknown process: " + callingPid);
12638                }
12639                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12640                    throw new SecurityException("Only an instrumentation process "
12641                            + "with a UiAutomation can call setUserIsMonkey");
12642                }
12643            }
12644            mUserIsMonkey = userIsMonkey;
12645        }
12646    }
12647
12648    @Override
12649    public boolean isUserAMonkey() {
12650        synchronized (this) {
12651            // If there is a controller also implies the user is a monkey.
12652            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12653        }
12654    }
12655
12656    /**
12657     * @deprecated This method is only used by a few internal components and it will soon be
12658     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12659     * No new code should be calling it.
12660     */
12661    @Deprecated
12662    @Override
12663    public void requestBugReport(int bugreportType) {
12664        String extraOptions = null;
12665        switch (bugreportType) {
12666            case ActivityManager.BUGREPORT_OPTION_FULL:
12667                // Default options.
12668                break;
12669            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12670                extraOptions = "bugreportplus";
12671                break;
12672            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12673                extraOptions = "bugreportremote";
12674                break;
12675            case ActivityManager.BUGREPORT_OPTION_WEAR:
12676                extraOptions = "bugreportwear";
12677                break;
12678            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12679                extraOptions = "bugreporttelephony";
12680                break;
12681            default:
12682                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12683                        + bugreportType);
12684        }
12685        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12686        if (extraOptions != null) {
12687            SystemProperties.set("dumpstate.options", extraOptions);
12688        }
12689        SystemProperties.set("ctl.start", "bugreport");
12690    }
12691
12692    /**
12693     * @deprecated This method is only used by a few internal components and it will soon be
12694     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12695     * No new code should be calling it.
12696     */
12697    @Deprecated
12698    @Override
12699    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12700
12701        if (!TextUtils.isEmpty(shareTitle)) {
12702            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12703                String errorStr = "shareTitle should be less than " +
12704                        MAX_BUGREPORT_TITLE_SIZE + " characters";
12705                throw new IllegalArgumentException(errorStr);
12706            } else {
12707                if (!TextUtils.isEmpty(shareDescription)) {
12708                    int length;
12709                    try {
12710                        length = shareDescription.getBytes("UTF-8").length;
12711                    } catch (UnsupportedEncodingException e) {
12712                        String errorStr = "shareDescription: UnsupportedEncodingException";
12713                        throw new IllegalArgumentException(errorStr);
12714                    }
12715                    if (length > SystemProperties.PROP_VALUE_MAX) {
12716                        String errorStr = "shareTitle should be less than " +
12717                                SystemProperties.PROP_VALUE_MAX + " bytes";
12718                        throw new IllegalArgumentException(errorStr);
12719                    } else {
12720                        SystemProperties.set("dumpstate.options.description", shareDescription);
12721                    }
12722                }
12723                SystemProperties.set("dumpstate.options.title", shareTitle);
12724            }
12725        }
12726
12727        Slog.d(TAG, "Bugreport notification title " + shareTitle
12728                + " description " + shareDescription);
12729        requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12730    }
12731
12732    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12733        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12734    }
12735
12736    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12737        if (r != null && (r.instr != null || r.usingWrapper)) {
12738            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12739        }
12740        return KEY_DISPATCHING_TIMEOUT;
12741    }
12742
12743    @Override
12744    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12745        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12746                != PackageManager.PERMISSION_GRANTED) {
12747            throw new SecurityException("Requires permission "
12748                    + android.Manifest.permission.FILTER_EVENTS);
12749        }
12750        ProcessRecord proc;
12751        long timeout;
12752        synchronized (this) {
12753            synchronized (mPidsSelfLocked) {
12754                proc = mPidsSelfLocked.get(pid);
12755            }
12756            timeout = getInputDispatchingTimeoutLocked(proc);
12757        }
12758
12759        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12760            return -1;
12761        }
12762
12763        return timeout;
12764    }
12765
12766    /**
12767     * Handle input dispatching timeouts.
12768     * Returns whether input dispatching should be aborted or not.
12769     */
12770    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12771            final ActivityRecord activity, final ActivityRecord parent,
12772            final boolean aboveSystem, String reason) {
12773        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12774                != PackageManager.PERMISSION_GRANTED) {
12775            throw new SecurityException("Requires permission "
12776                    + android.Manifest.permission.FILTER_EVENTS);
12777        }
12778
12779        final String annotation;
12780        if (reason == null) {
12781            annotation = "Input dispatching timed out";
12782        } else {
12783            annotation = "Input dispatching timed out (" + reason + ")";
12784        }
12785
12786        if (proc != null) {
12787            synchronized (this) {
12788                if (proc.debugging) {
12789                    return false;
12790                }
12791
12792                if (mDidDexOpt) {
12793                    // Give more time since we were dexopting.
12794                    mDidDexOpt = false;
12795                    return false;
12796                }
12797
12798                if (proc.instr != null) {
12799                    Bundle info = new Bundle();
12800                    info.putString("shortMsg", "keyDispatchingTimedOut");
12801                    info.putString("longMsg", annotation);
12802                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12803                    return true;
12804                }
12805            }
12806            mHandler.post(new Runnable() {
12807                @Override
12808                public void run() {
12809                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12810                }
12811            });
12812        }
12813
12814        return true;
12815    }
12816
12817    @Override
12818    public Bundle getAssistContextExtras(int requestType) {
12819        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12820                null, null, true /* focused */, true /* newSessionId */,
12821                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12822        if (pae == null) {
12823            return null;
12824        }
12825        synchronized (pae) {
12826            while (!pae.haveResult) {
12827                try {
12828                    pae.wait();
12829                } catch (InterruptedException e) {
12830                }
12831            }
12832        }
12833        synchronized (this) {
12834            buildAssistBundleLocked(pae, pae.result);
12835            mPendingAssistExtras.remove(pae);
12836            mUiHandler.removeCallbacks(pae);
12837        }
12838        return pae.extras;
12839    }
12840
12841    @Override
12842    public boolean isAssistDataAllowedOnCurrentActivity() {
12843        int userId;
12844        synchronized (this) {
12845            final ActivityStack focusedStack = getFocusedStack();
12846            if (focusedStack == null || focusedStack.isAssistantStack()) {
12847                return false;
12848            }
12849
12850            final ActivityRecord activity = focusedStack.topActivity();
12851            if (activity == null) {
12852                return false;
12853            }
12854            userId = activity.userId;
12855        }
12856        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12857                Context.DEVICE_POLICY_SERVICE);
12858        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12859    }
12860
12861    @Override
12862    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12863        long ident = Binder.clearCallingIdentity();
12864        try {
12865            synchronized (this) {
12866                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12867                ActivityRecord top = getFocusedStack().topActivity();
12868                if (top != caller) {
12869                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12870                            + " is not current top " + top);
12871                    return false;
12872                }
12873                if (!top.nowVisible) {
12874                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12875                            + " is not visible");
12876                    return false;
12877                }
12878            }
12879            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
12880                    token);
12881        } finally {
12882            Binder.restoreCallingIdentity(ident);
12883        }
12884    }
12885
12886    @Override
12887    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12888            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
12889        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12890                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
12891                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
12892    }
12893
12894    @Override
12895    public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
12896            IBinder activityToken) {
12897        // NOTE: we could always use ActivityManager.ASSIST_CONTEXT_FULL and let ActivityThread
12898        // rely on the flags to decide whether the handleRequestAssistContextExtras() is for
12899        // autofill, but it's safer to explicitly use new AutoFill types, in case the Assist
12900        // requests use flags in the future as well (since their flags value might collide with the
12901        // autofill flag values).
12902        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
12903                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
12904                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT) != null;
12905    }
12906
12907    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12908            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12909            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12910        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12911                "enqueueAssistContext()");
12912
12913        synchronized (this) {
12914            ActivityRecord activity = getFocusedStack().topActivity();
12915            if (activity == null) {
12916                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12917                return null;
12918            }
12919            if (activity.app == null || activity.app.thread == null) {
12920                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12921                return null;
12922            }
12923            if (focused) {
12924                if (activityToken != null) {
12925                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12926                    if (activity != caller) {
12927                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12928                                + " is not current top " + activity);
12929                        return null;
12930                    }
12931                }
12932            } else {
12933                activity = ActivityRecord.forTokenLocked(activityToken);
12934                if (activity == null) {
12935                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12936                            + " couldn't be found");
12937                    return null;
12938                }
12939            }
12940
12941            PendingAssistExtras pae;
12942            Bundle extras = new Bundle();
12943            if (args != null) {
12944                extras.putAll(args);
12945            }
12946            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12947            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12948
12949            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12950                    userHandle);
12951            pae.isHome = activity.isHomeActivity();
12952
12953            // Increment the sessionId if necessary
12954            if (newSessionId) {
12955                mViSessionId++;
12956            }
12957            try {
12958                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
12959                        mViSessionId);
12960                mPendingAssistExtras.add(pae);
12961                mUiHandler.postDelayed(pae, timeout);
12962            } catch (RemoteException e) {
12963                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12964                return null;
12965            }
12966            return pae;
12967        }
12968    }
12969
12970    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12971        IResultReceiver receiver;
12972        synchronized (this) {
12973            mPendingAssistExtras.remove(pae);
12974            receiver = pae.receiver;
12975        }
12976        if (receiver != null) {
12977            // Caller wants result sent back to them.
12978            Bundle sendBundle = new Bundle();
12979            // At least return the receiver extras
12980            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12981                    pae.receiverExtras);
12982            try {
12983                pae.receiver.send(0, sendBundle);
12984            } catch (RemoteException e) {
12985            }
12986        }
12987    }
12988
12989    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12990        if (result != null) {
12991            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12992        }
12993        if (pae.hint != null) {
12994            pae.extras.putBoolean(pae.hint, true);
12995        }
12996    }
12997
12998    /** Called from an app when assist data is ready. */
12999    @Override
13000    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13001            AssistContent content, Uri referrer) {
13002        PendingAssistExtras pae = (PendingAssistExtras)token;
13003        synchronized (pae) {
13004            pae.result = extras;
13005            pae.structure = structure;
13006            pae.content = content;
13007            if (referrer != null) {
13008                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13009            }
13010            if (structure != null) {
13011                structure.setHomeActivity(pae.isHome);
13012            }
13013            pae.haveResult = true;
13014            pae.notifyAll();
13015            if (pae.intent == null && pae.receiver == null) {
13016                // Caller is just waiting for the result.
13017                return;
13018            }
13019        }
13020
13021        // We are now ready to launch the assist activity.
13022        IResultReceiver sendReceiver = null;
13023        Bundle sendBundle = null;
13024        synchronized (this) {
13025            buildAssistBundleLocked(pae, extras);
13026            boolean exists = mPendingAssistExtras.remove(pae);
13027            mUiHandler.removeCallbacks(pae);
13028            if (!exists) {
13029                // Timed out.
13030                return;
13031            }
13032            if ((sendReceiver=pae.receiver) != null) {
13033                // Caller wants result sent back to them.
13034                sendBundle = new Bundle();
13035                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13036                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13037                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13038                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13039                        pae.receiverExtras);
13040            }
13041        }
13042        if (sendReceiver != null) {
13043            try {
13044                sendReceiver.send(0, sendBundle);
13045            } catch (RemoteException e) {
13046            }
13047            return;
13048        }
13049
13050        long ident = Binder.clearCallingIdentity();
13051        try {
13052            pae.intent.replaceExtras(pae.extras);
13053            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13054                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
13055                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13056            closeSystemDialogs("assist");
13057            try {
13058                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13059            } catch (ActivityNotFoundException e) {
13060                Slog.w(TAG, "No activity to handle assist action.", e);
13061            }
13062        } finally {
13063            Binder.restoreCallingIdentity(ident);
13064        }
13065    }
13066
13067    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13068            Bundle args) {
13069        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13070                true /* focused */, true /* newSessionId */, userHandle, args,
13071                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
13072    }
13073
13074    public void registerProcessObserver(IProcessObserver observer) {
13075        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13076                "registerProcessObserver()");
13077        synchronized (this) {
13078            mProcessObservers.register(observer);
13079        }
13080    }
13081
13082    @Override
13083    public void unregisterProcessObserver(IProcessObserver observer) {
13084        synchronized (this) {
13085            mProcessObservers.unregister(observer);
13086        }
13087    }
13088
13089    @Override
13090    public int getUidProcessState(int uid, String callingPackage) {
13091        if (!hasUsageStatsPermission(callingPackage)) {
13092            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13093                    "getUidProcessState");
13094        }
13095
13096        synchronized (this) {
13097            UidRecord uidRec = mActiveUids.get(uid);
13098            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13099        }
13100    }
13101
13102    @Override
13103    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13104            String callingPackage) {
13105        if (!hasUsageStatsPermission(callingPackage)) {
13106            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13107                    "registerUidObserver");
13108        }
13109        synchronized (this) {
13110            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13111                    callingPackage, which, cutpoint));
13112        }
13113    }
13114
13115    @Override
13116    public void unregisterUidObserver(IUidObserver observer) {
13117        synchronized (this) {
13118            mUidObservers.unregister(observer);
13119        }
13120    }
13121
13122    @Override
13123    public boolean convertFromTranslucent(IBinder token) {
13124        final long origId = Binder.clearCallingIdentity();
13125        try {
13126            synchronized (this) {
13127                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13128                if (r == null) {
13129                    return false;
13130                }
13131                final boolean translucentChanged = r.changeWindowTranslucency(true);
13132                if (translucentChanged) {
13133                    r.getStack().releaseBackgroundResources(r);
13134                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13135                }
13136                mWindowManager.setAppFullscreen(token, true);
13137                return translucentChanged;
13138            }
13139        } finally {
13140            Binder.restoreCallingIdentity(origId);
13141        }
13142    }
13143
13144    @Override
13145    public boolean convertToTranslucent(IBinder token, Bundle options) {
13146        final long origId = Binder.clearCallingIdentity();
13147        try {
13148            synchronized (this) {
13149                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13150                if (r == null) {
13151                    return false;
13152                }
13153                final TaskRecord task = r.getTask();
13154                int index = task.mActivities.lastIndexOf(r);
13155                if (index > 0) {
13156                    ActivityRecord under = task.mActivities.get(index - 1);
13157                    under.returningOptions = ActivityOptions.fromBundle(options);
13158                }
13159                final boolean translucentChanged = r.changeWindowTranslucency(false);
13160                if (translucentChanged) {
13161                    r.getStack().convertActivityToTranslucent(r);
13162                }
13163                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13164                mWindowManager.setAppFullscreen(token, false);
13165                return translucentChanged;
13166            }
13167        } finally {
13168            Binder.restoreCallingIdentity(origId);
13169        }
13170    }
13171
13172    @Override
13173    public boolean requestVisibleBehind(IBinder token, boolean visible) {
13174        final long origId = Binder.clearCallingIdentity();
13175        try {
13176            synchronized (this) {
13177                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13178                if (r != null) {
13179                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13180                }
13181            }
13182            return false;
13183        } finally {
13184            Binder.restoreCallingIdentity(origId);
13185        }
13186    }
13187
13188    @Override
13189    public boolean isBackgroundVisibleBehind(IBinder token) {
13190        final long origId = Binder.clearCallingIdentity();
13191        try {
13192            synchronized (this) {
13193                final ActivityStack stack = ActivityRecord.getStackLocked(token);
13194                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13195                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13196                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13197                return visible;
13198            }
13199        } finally {
13200            Binder.restoreCallingIdentity(origId);
13201        }
13202    }
13203
13204    @Override
13205    public Bundle getActivityOptions(IBinder token) {
13206        final long origId = Binder.clearCallingIdentity();
13207        try {
13208            synchronized (this) {
13209                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13210                if (r != null) {
13211                    final ActivityOptions activityOptions = r.pendingOptions;
13212                    r.pendingOptions = null;
13213                    return activityOptions == null ? null : activityOptions.toBundle();
13214                }
13215                return null;
13216            }
13217        } finally {
13218            Binder.restoreCallingIdentity(origId);
13219        }
13220    }
13221
13222    @Override
13223    public void setImmersive(IBinder token, boolean immersive) {
13224        synchronized(this) {
13225            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13226            if (r == null) {
13227                throw new IllegalArgumentException();
13228            }
13229            r.immersive = immersive;
13230
13231            // update associated state if we're frontmost
13232            if (r == mStackSupervisor.getResumedActivityLocked()) {
13233                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13234                applyUpdateLockStateLocked(r);
13235            }
13236        }
13237    }
13238
13239    @Override
13240    public boolean isImmersive(IBinder token) {
13241        synchronized (this) {
13242            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13243            if (r == null) {
13244                throw new IllegalArgumentException();
13245            }
13246            return r.immersive;
13247        }
13248    }
13249
13250    @Override
13251    public void setVrThread(int tid) {
13252        enforceSystemHasVrFeature();
13253        synchronized (this) {
13254            synchronized (mPidsSelfLocked) {
13255                final int pid = Binder.getCallingPid();
13256                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13257                mVrController.setVrThreadLocked(tid, pid, proc);
13258            }
13259        }
13260    }
13261
13262    @Override
13263    public void setPersistentVrThread(int tid) {
13264        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13265            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13266                    + Binder.getCallingPid()
13267                    + ", uid=" + Binder.getCallingUid()
13268                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13269            Slog.w(TAG, msg);
13270            throw new SecurityException(msg);
13271        }
13272        enforceSystemHasVrFeature();
13273        synchronized (this) {
13274            synchronized (mPidsSelfLocked) {
13275                final int pid = Binder.getCallingPid();
13276                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13277                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13278            }
13279        }
13280    }
13281
13282    /**
13283     * Schedule the given thread a normal scheduling priority.
13284     *
13285     * @param newTid the tid of the thread to adjust the scheduling of.
13286     * @param suppressLogs {@code true} if any error logging should be disabled.
13287     *
13288     * @return {@code true} if this succeeded.
13289     */
13290    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13291        try {
13292            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13293            return true;
13294        } catch (IllegalArgumentException e) {
13295            if (!suppressLogs) {
13296                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13297            }
13298        }
13299        return false;
13300    }
13301
13302    /**
13303     * Schedule the given thread an FIFO scheduling priority.
13304     *
13305     * @param newTid the tid of the thread to adjust the scheduling of.
13306     * @param suppressLogs {@code true} if any error logging should be disabled.
13307     *
13308     * @return {@code true} if this succeeded.
13309     */
13310    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13311        try {
13312            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13313            return true;
13314        } catch (IllegalArgumentException e) {
13315            if (!suppressLogs) {
13316                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13317            }
13318        }
13319        return false;
13320    }
13321
13322    /**
13323     * Check that we have the features required for VR-related API calls, and throw an exception if
13324     * not.
13325     */
13326    private void enforceSystemHasVrFeature() {
13327        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13328            throw new UnsupportedOperationException("VR mode not supported on this device!");
13329        }
13330    }
13331
13332    @Override
13333    public void setRenderThread(int tid) {
13334        synchronized (this) {
13335            ProcessRecord proc;
13336            synchronized (mPidsSelfLocked) {
13337                int pid = Binder.getCallingPid();
13338                proc = mPidsSelfLocked.get(pid);
13339                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13340                    // ensure the tid belongs to the process
13341                    if (!isThreadInProcess(pid, tid)) {
13342                        throw new IllegalArgumentException(
13343                            "Render thread does not belong to process");
13344                    }
13345                    proc.renderThreadTid = tid;
13346                    if (DEBUG_OOM_ADJ) {
13347                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13348                    }
13349                    // promote to FIFO now
13350                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13351                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13352                        if (mUseFifoUiScheduling) {
13353                            setThreadScheduler(proc.renderThreadTid,
13354                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13355                        } else {
13356                            setThreadPriority(proc.renderThreadTid, -10);
13357                        }
13358                    }
13359                } else {
13360                    if (DEBUG_OOM_ADJ) {
13361                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13362                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13363                               mUseFifoUiScheduling);
13364                    }
13365                }
13366            }
13367        }
13368    }
13369
13370    @Override
13371    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13372        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13373            throw new UnsupportedOperationException("VR mode not supported on this device!");
13374        }
13375
13376        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13377
13378        ActivityRecord r;
13379        synchronized (this) {
13380            r = ActivityRecord.isInStackLocked(token);
13381        }
13382
13383        if (r == null) {
13384            throw new IllegalArgumentException();
13385        }
13386
13387        int err;
13388        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13389                VrManagerInternal.NO_ERROR) {
13390            return err;
13391        }
13392
13393        synchronized(this) {
13394            r.requestedVrComponent = (enabled) ? packageName : null;
13395
13396            // Update associated state if this activity is currently focused
13397            if (r == mStackSupervisor.getResumedActivityLocked()) {
13398                applyUpdateVrModeLocked(r);
13399            }
13400            return 0;
13401        }
13402    }
13403
13404    @Override
13405    public boolean isVrModePackageEnabled(ComponentName packageName) {
13406        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13407            throw new UnsupportedOperationException("VR mode not supported on this device!");
13408        }
13409
13410        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13411
13412        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13413                VrManagerInternal.NO_ERROR;
13414    }
13415
13416    public boolean isTopActivityImmersive() {
13417        enforceNotIsolatedCaller("startActivity");
13418        synchronized (this) {
13419            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13420            return (r != null) ? r.immersive : false;
13421        }
13422    }
13423
13424    /**
13425     * @return whether the system should disable UI modes incompatible with VR mode.
13426     */
13427    boolean shouldDisableNonVrUiLocked() {
13428        return mVrController.shouldDisableNonVrUiLocked();
13429    }
13430
13431    @Override
13432    public boolean isTopOfTask(IBinder token) {
13433        synchronized (this) {
13434            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13435            if (r == null) {
13436                throw new IllegalArgumentException();
13437            }
13438            return r.getTask().getTopActivity() == r;
13439        }
13440    }
13441
13442    @Override
13443    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13444        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13445            String msg = "Permission Denial: setHasTopUi() from pid="
13446                    + Binder.getCallingPid()
13447                    + ", uid=" + Binder.getCallingUid()
13448                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13449            Slog.w(TAG, msg);
13450            throw new SecurityException(msg);
13451        }
13452        final int pid = Binder.getCallingPid();
13453        final long origId = Binder.clearCallingIdentity();
13454        try {
13455            synchronized (this) {
13456                boolean changed = false;
13457                ProcessRecord pr;
13458                synchronized (mPidsSelfLocked) {
13459                    pr = mPidsSelfLocked.get(pid);
13460                    if (pr == null) {
13461                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13462                        return;
13463                    }
13464                    if (pr.hasTopUi != hasTopUi) {
13465                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13466                        pr.hasTopUi = hasTopUi;
13467                        changed = true;
13468                    }
13469                }
13470                if (changed) {
13471                    updateOomAdjLocked(pr);
13472                }
13473            }
13474        } finally {
13475            Binder.restoreCallingIdentity(origId);
13476        }
13477    }
13478
13479    public final void enterSafeMode() {
13480        synchronized(this) {
13481            // It only makes sense to do this before the system is ready
13482            // and started launching other packages.
13483            if (!mSystemReady) {
13484                try {
13485                    AppGlobals.getPackageManager().enterSafeMode();
13486                } catch (RemoteException e) {
13487                }
13488            }
13489
13490            mSafeMode = true;
13491        }
13492    }
13493
13494    public final void showSafeModeOverlay() {
13495        View v = LayoutInflater.from(mContext).inflate(
13496                com.android.internal.R.layout.safe_mode, null);
13497        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13498        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13499        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13500        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13501        lp.gravity = Gravity.BOTTOM | Gravity.START;
13502        lp.format = v.getBackground().getOpacity();
13503        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13504                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13505        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13506        ((WindowManager)mContext.getSystemService(
13507                Context.WINDOW_SERVICE)).addView(v, lp);
13508    }
13509
13510    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13511        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13512            return;
13513        }
13514        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13515        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13516        synchronized (stats) {
13517            if (mBatteryStatsService.isOnBattery()) {
13518                mBatteryStatsService.enforceCallingPermission();
13519                int MY_UID = Binder.getCallingUid();
13520                final int uid;
13521                if (sender == null) {
13522                    uid = sourceUid;
13523                } else {
13524                    uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13525                }
13526                BatteryStatsImpl.Uid.Pkg pkg =
13527                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13528                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13529                pkg.noteWakeupAlarmLocked(tag);
13530            }
13531        }
13532    }
13533
13534    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13535        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13536            return;
13537        }
13538        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13539        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13540        synchronized (stats) {
13541            mBatteryStatsService.enforceCallingPermission();
13542            int MY_UID = Binder.getCallingUid();
13543            final int uid;
13544            if (sender == null) {
13545                uid = sourceUid;
13546            } else {
13547                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13548            }
13549            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13550        }
13551    }
13552
13553    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13554        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13555            return;
13556        }
13557        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13558        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13559        synchronized (stats) {
13560            mBatteryStatsService.enforceCallingPermission();
13561            int MY_UID = Binder.getCallingUid();
13562            final int uid;
13563            if (sender == null) {
13564                uid = sourceUid;
13565            } else {
13566                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13567            }
13568            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13569        }
13570    }
13571
13572    public boolean killPids(int[] pids, String pReason, boolean secure) {
13573        if (Binder.getCallingUid() != SYSTEM_UID) {
13574            throw new SecurityException("killPids only available to the system");
13575        }
13576        String reason = (pReason == null) ? "Unknown" : pReason;
13577        // XXX Note: don't acquire main activity lock here, because the window
13578        // manager calls in with its locks held.
13579
13580        boolean killed = false;
13581        synchronized (mPidsSelfLocked) {
13582            int worstType = 0;
13583            for (int i=0; i<pids.length; i++) {
13584                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13585                if (proc != null) {
13586                    int type = proc.setAdj;
13587                    if (type > worstType) {
13588                        worstType = type;
13589                    }
13590                }
13591            }
13592
13593            // If the worst oom_adj is somewhere in the cached proc LRU range,
13594            // then constrain it so we will kill all cached procs.
13595            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13596                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13597                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13598            }
13599
13600            // If this is not a secure call, don't let it kill processes that
13601            // are important.
13602            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13603                worstType = ProcessList.SERVICE_ADJ;
13604            }
13605
13606            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13607            for (int i=0; i<pids.length; i++) {
13608                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13609                if (proc == null) {
13610                    continue;
13611                }
13612                int adj = proc.setAdj;
13613                if (adj >= worstType && !proc.killedByAm) {
13614                    proc.kill(reason, true);
13615                    killed = true;
13616                }
13617            }
13618        }
13619        return killed;
13620    }
13621
13622    @Override
13623    public void killUid(int appId, int userId, String reason) {
13624        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13625        synchronized (this) {
13626            final long identity = Binder.clearCallingIdentity();
13627            try {
13628                killPackageProcessesLocked(null, appId, userId,
13629                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13630                        reason != null ? reason : "kill uid");
13631            } finally {
13632                Binder.restoreCallingIdentity(identity);
13633            }
13634        }
13635    }
13636
13637    @Override
13638    public boolean killProcessesBelowForeground(String reason) {
13639        if (Binder.getCallingUid() != SYSTEM_UID) {
13640            throw new SecurityException("killProcessesBelowForeground() only available to system");
13641        }
13642
13643        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13644    }
13645
13646    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13647        if (Binder.getCallingUid() != SYSTEM_UID) {
13648            throw new SecurityException("killProcessesBelowAdj() only available to system");
13649        }
13650
13651        boolean killed = false;
13652        synchronized (mPidsSelfLocked) {
13653            final int size = mPidsSelfLocked.size();
13654            for (int i = 0; i < size; i++) {
13655                final int pid = mPidsSelfLocked.keyAt(i);
13656                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13657                if (proc == null) continue;
13658
13659                final int adj = proc.setAdj;
13660                if (adj > belowAdj && !proc.killedByAm) {
13661                    proc.kill(reason, true);
13662                    killed = true;
13663                }
13664            }
13665        }
13666        return killed;
13667    }
13668
13669    @Override
13670    public void hang(final IBinder who, boolean allowRestart) {
13671        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13672                != PackageManager.PERMISSION_GRANTED) {
13673            throw new SecurityException("Requires permission "
13674                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13675        }
13676
13677        final IBinder.DeathRecipient death = new DeathRecipient() {
13678            @Override
13679            public void binderDied() {
13680                synchronized (this) {
13681                    notifyAll();
13682                }
13683            }
13684        };
13685
13686        try {
13687            who.linkToDeath(death, 0);
13688        } catch (RemoteException e) {
13689            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13690            return;
13691        }
13692
13693        synchronized (this) {
13694            Watchdog.getInstance().setAllowRestart(allowRestart);
13695            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13696            synchronized (death) {
13697                while (who.isBinderAlive()) {
13698                    try {
13699                        death.wait();
13700                    } catch (InterruptedException e) {
13701                    }
13702                }
13703            }
13704            Watchdog.getInstance().setAllowRestart(true);
13705        }
13706    }
13707
13708    @Override
13709    public void restart() {
13710        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13711                != PackageManager.PERMISSION_GRANTED) {
13712            throw new SecurityException("Requires permission "
13713                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13714        }
13715
13716        Log.i(TAG, "Sending shutdown broadcast...");
13717
13718        BroadcastReceiver br = new BroadcastReceiver() {
13719            @Override public void onReceive(Context context, Intent intent) {
13720                // Now the broadcast is done, finish up the low-level shutdown.
13721                Log.i(TAG, "Shutting down activity manager...");
13722                shutdown(10000);
13723                Log.i(TAG, "Shutdown complete, restarting!");
13724                killProcess(myPid());
13725                System.exit(10);
13726            }
13727        };
13728
13729        // First send the high-level shut down broadcast.
13730        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13731        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13732        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13733        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13734        mContext.sendOrderedBroadcastAsUser(intent,
13735                UserHandle.ALL, null, br, mHandler, 0, null, null);
13736        */
13737        br.onReceive(mContext, intent);
13738    }
13739
13740    private long getLowRamTimeSinceIdle(long now) {
13741        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13742    }
13743
13744    @Override
13745    public void performIdleMaintenance() {
13746        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13747                != PackageManager.PERMISSION_GRANTED) {
13748            throw new SecurityException("Requires permission "
13749                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13750        }
13751
13752        synchronized (this) {
13753            final long now = SystemClock.uptimeMillis();
13754            final long timeSinceLastIdle = now - mLastIdleTime;
13755            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13756            mLastIdleTime = now;
13757            mLowRamTimeSinceLastIdle = 0;
13758            if (mLowRamStartTime != 0) {
13759                mLowRamStartTime = now;
13760            }
13761
13762            StringBuilder sb = new StringBuilder(128);
13763            sb.append("Idle maintenance over ");
13764            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13765            sb.append(" low RAM for ");
13766            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13767            Slog.i(TAG, sb.toString());
13768
13769            // If at least 1/3 of our time since the last idle period has been spent
13770            // with RAM low, then we want to kill processes.
13771            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13772
13773            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13774                ProcessRecord proc = mLruProcesses.get(i);
13775                if (proc.notCachedSinceIdle) {
13776                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13777                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13778                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13779                        if (doKilling && proc.initialIdlePss != 0
13780                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13781                            sb = new StringBuilder(128);
13782                            sb.append("Kill");
13783                            sb.append(proc.processName);
13784                            sb.append(" in idle maint: pss=");
13785                            sb.append(proc.lastPss);
13786                            sb.append(", swapPss=");
13787                            sb.append(proc.lastSwapPss);
13788                            sb.append(", initialPss=");
13789                            sb.append(proc.initialIdlePss);
13790                            sb.append(", period=");
13791                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13792                            sb.append(", lowRamPeriod=");
13793                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13794                            Slog.wtfQuiet(TAG, sb.toString());
13795                            proc.kill("idle maint (pss " + proc.lastPss
13796                                    + " from " + proc.initialIdlePss + ")", true);
13797                        }
13798                    }
13799                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13800                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13801                    proc.notCachedSinceIdle = true;
13802                    proc.initialIdlePss = 0;
13803                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13804                            mTestPssMode, isSleepingLocked(), now);
13805                }
13806            }
13807
13808            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13809            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13810        }
13811    }
13812
13813    @Override
13814    public void sendIdleJobTrigger() {
13815        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13816                != PackageManager.PERMISSION_GRANTED) {
13817            throw new SecurityException("Requires permission "
13818                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13819        }
13820
13821        final long ident = Binder.clearCallingIdentity();
13822        try {
13823            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13824                    .setPackage("android")
13825                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13826            broadcastIntent(null, intent, null, null, 0, null, null, null,
13827                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13828        } finally {
13829            Binder.restoreCallingIdentity(ident);
13830        }
13831    }
13832
13833    private void retrieveSettings() {
13834        final ContentResolver resolver = mContext.getContentResolver();
13835        final boolean freeformWindowManagement =
13836                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13837                        || Settings.Global.getInt(
13838                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13839        final boolean supportsPictureInPicture =
13840                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13841
13842        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13843        final boolean supportsSplitScreenMultiWindow =
13844                ActivityManager.supportsSplitScreenMultiWindow();
13845        final boolean supportsMultiDisplay = mContext.getPackageManager()
13846                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
13847        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13848        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13849        final boolean alwaysFinishActivities =
13850                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13851        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13852        final boolean forceResizable = Settings.Global.getInt(
13853                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13854        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
13855                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
13856        final boolean supportsLeanbackOnly =
13857                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13858
13859        // Transfer any global setting for forcing RTL layout, into a System Property
13860        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13861
13862        final Configuration configuration = new Configuration();
13863        Settings.System.getConfiguration(resolver, configuration);
13864        if (forceRtl) {
13865            // This will take care of setting the correct layout direction flags
13866            configuration.setLayoutDirection(configuration.locale);
13867        }
13868
13869        synchronized (this) {
13870            mDebugApp = mOrigDebugApp = debugApp;
13871            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13872            mAlwaysFinishActivities = alwaysFinishActivities;
13873            mSupportsLeanbackOnly = supportsLeanbackOnly;
13874            mForceResizableActivities = forceResizable;
13875            if (supportsMultiWindow || forceResizable) {
13876                mSupportsMultiWindow = true;
13877                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13878            } else {
13879                mSupportsMultiWindow = false;
13880                mSupportsFreeformWindowManagement = false;
13881            }
13882            mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13883            mSupportsPictureInPicture = supportsPictureInPicture;
13884            mSupportsMultiDisplay = supportsMultiDisplay;
13885            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13886            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13887            // This happens before any activities are started, so we can change global configuration
13888            // in-place.
13889            updateConfigurationLocked(configuration, null, true);
13890            final Configuration globalConfig = getGlobalConfiguration();
13891            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13892
13893            // Load resources only after the current configuration has been set.
13894            final Resources res = mContext.getResources();
13895            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13896            mThumbnailWidth = res.getDimensionPixelSize(
13897                    com.android.internal.R.dimen.thumbnail_width);
13898            mThumbnailHeight = res.getDimensionPixelSize(
13899                    com.android.internal.R.dimen.thumbnail_height);
13900            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13901                    com.android.internal.R.string.config_appsNotReportingCrashes));
13902            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13903                    com.android.internal.R.bool.config_customUserSwitchUi);
13904            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13905                mFullscreenThumbnailScale = (float) res
13906                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13907                    (float) globalConfig.screenWidthDp;
13908            } else {
13909                mFullscreenThumbnailScale = res.getFraction(
13910                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13911            }
13912            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
13913        }
13914    }
13915
13916    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
13917        traceLog.traceBegin("PhaseActivityManagerReady");
13918        synchronized(this) {
13919            if (mSystemReady) {
13920                // If we're done calling all the receivers, run the next "boot phase" passed in
13921                // by the SystemServer
13922                if (goingCallback != null) {
13923                    goingCallback.run();
13924                }
13925                return;
13926            }
13927
13928            mLocalDeviceIdleController
13929                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13930            mAssistUtils = new AssistUtils(mContext);
13931            mVrController.onSystemReady();
13932            // Make sure we have the current profile info, since it is needed for security checks.
13933            mUserController.onSystemReady();
13934            mRecentTasks.onSystemReadyLocked();
13935            mAppOpsService.systemReady();
13936            mSystemReady = true;
13937        }
13938
13939        ArrayList<ProcessRecord> procsToKill = null;
13940        synchronized(mPidsSelfLocked) {
13941            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13942                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13943                if (!isAllowedWhileBooting(proc.info)){
13944                    if (procsToKill == null) {
13945                        procsToKill = new ArrayList<ProcessRecord>();
13946                    }
13947                    procsToKill.add(proc);
13948                }
13949            }
13950        }
13951
13952        synchronized(this) {
13953            if (procsToKill != null) {
13954                for (int i=procsToKill.size()-1; i>=0; i--) {
13955                    ProcessRecord proc = procsToKill.get(i);
13956                    Slog.i(TAG, "Removing system update proc: " + proc);
13957                    removeProcessLocked(proc, true, false, "system update done");
13958                }
13959            }
13960
13961            // Now that we have cleaned up any update processes, we
13962            // are ready to start launching real processes and know that
13963            // we won't trample on them any more.
13964            mProcessesReady = true;
13965        }
13966
13967        Slog.i(TAG, "System now ready");
13968        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13969            SystemClock.uptimeMillis());
13970
13971        synchronized(this) {
13972            // Make sure we have no pre-ready processes sitting around.
13973
13974            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13975                ResolveInfo ri = mContext.getPackageManager()
13976                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13977                                STOCK_PM_FLAGS);
13978                CharSequence errorMsg = null;
13979                if (ri != null) {
13980                    ActivityInfo ai = ri.activityInfo;
13981                    ApplicationInfo app = ai.applicationInfo;
13982                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13983                        mTopAction = Intent.ACTION_FACTORY_TEST;
13984                        mTopData = null;
13985                        mTopComponent = new ComponentName(app.packageName,
13986                                ai.name);
13987                    } else {
13988                        errorMsg = mContext.getResources().getText(
13989                                com.android.internal.R.string.factorytest_not_system);
13990                    }
13991                } else {
13992                    errorMsg = mContext.getResources().getText(
13993                            com.android.internal.R.string.factorytest_no_action);
13994                }
13995                if (errorMsg != null) {
13996                    mTopAction = null;
13997                    mTopData = null;
13998                    mTopComponent = null;
13999                    Message msg = Message.obtain();
14000                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14001                    msg.getData().putCharSequence("msg", errorMsg);
14002                    mUiHandler.sendMessage(msg);
14003                }
14004            }
14005        }
14006
14007        retrieveSettings();
14008        final int currentUserId;
14009        synchronized (this) {
14010            currentUserId = mUserController.getCurrentUserIdLocked();
14011            readGrantedUriPermissionsLocked();
14012        }
14013
14014        if (goingCallback != null) goingCallback.run();
14015        traceLog.traceBegin("ActivityManagerStartApps");
14016        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14017                Integer.toString(currentUserId), currentUserId);
14018        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14019                Integer.toString(currentUserId), currentUserId);
14020        mSystemServiceManager.startUser(currentUserId);
14021
14022        synchronized (this) {
14023            // Only start up encryption-aware persistent apps; once user is
14024            // unlocked we'll come back around and start unaware apps
14025            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14026
14027            // Start up initial activity.
14028            mBooting = true;
14029            // Enable home activity for system user, so that the system can always boot. We don't
14030            // do this when the system user is not setup since the setup wizard should be the one
14031            // to handle home activity in this case.
14032            if (UserManager.isSplitSystemUser() &&
14033                    Settings.Secure.getInt(mContext.getContentResolver(),
14034                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14035                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14036                try {
14037                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14038                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14039                            UserHandle.USER_SYSTEM);
14040                } catch (RemoteException e) {
14041                    throw e.rethrowAsRuntimeException();
14042                }
14043            }
14044            startHomeActivityLocked(currentUserId, "systemReady");
14045
14046            try {
14047                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14048                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14049                            + " data partition or your device will be unstable.");
14050                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14051                }
14052            } catch (RemoteException e) {
14053            }
14054
14055            if (!Build.isBuildConsistent()) {
14056                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14057                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14058            }
14059
14060            long ident = Binder.clearCallingIdentity();
14061            try {
14062                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14063                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14064                        | Intent.FLAG_RECEIVER_FOREGROUND);
14065                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14066                broadcastIntentLocked(null, null, intent,
14067                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14068                        null, false, false, MY_PID, SYSTEM_UID,
14069                        currentUserId);
14070                intent = new Intent(Intent.ACTION_USER_STARTING);
14071                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14072                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14073                broadcastIntentLocked(null, null, intent,
14074                        null, new IIntentReceiver.Stub() {
14075                            @Override
14076                            public void performReceive(Intent intent, int resultCode, String data,
14077                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14078                                    throws RemoteException {
14079                            }
14080                        }, 0, null, null,
14081                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14082                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14083            } catch (Throwable t) {
14084                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14085            } finally {
14086                Binder.restoreCallingIdentity(ident);
14087            }
14088            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14089            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14090            traceLog.traceEnd(); // ActivityManagerStartApps
14091            traceLog.traceEnd(); // PhaseActivityManagerReady
14092        }
14093    }
14094
14095    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14096        synchronized (this) {
14097            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14098        }
14099    }
14100
14101    void skipCurrentReceiverLocked(ProcessRecord app) {
14102        for (BroadcastQueue queue : mBroadcastQueues) {
14103            queue.skipCurrentReceiverLocked(app);
14104        }
14105    }
14106
14107    /**
14108     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14109     * The application process will exit immediately after this call returns.
14110     * @param app object of the crashing app, null for the system server
14111     * @param crashInfo describing the exception
14112     */
14113    public void handleApplicationCrash(IBinder app,
14114            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14115        ProcessRecord r = findAppProcess(app, "Crash");
14116        final String processName = app == null ? "system_server"
14117                : (r == null ? "unknown" : r.processName);
14118
14119        handleApplicationCrashInner("crash", r, processName, crashInfo);
14120    }
14121
14122    /* Native crash reporting uses this inner version because it needs to be somewhat
14123     * decoupled from the AM-managed cleanup lifecycle
14124     */
14125    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14126            ApplicationErrorReport.CrashInfo crashInfo) {
14127        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14128                UserHandle.getUserId(Binder.getCallingUid()), processName,
14129                r == null ? -1 : r.info.flags,
14130                crashInfo.exceptionClassName,
14131                crashInfo.exceptionMessage,
14132                crashInfo.throwFileName,
14133                crashInfo.throwLineNumber);
14134
14135        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14136
14137        mAppErrors.crashApplication(r, crashInfo);
14138    }
14139
14140    public void handleApplicationStrictModeViolation(
14141            IBinder app,
14142            int violationMask,
14143            StrictMode.ViolationInfo info) {
14144        ProcessRecord r = findAppProcess(app, "StrictMode");
14145        if (r == null) {
14146            return;
14147        }
14148
14149        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14150            Integer stackFingerprint = info.hashCode();
14151            boolean logIt = true;
14152            synchronized (mAlreadyLoggedViolatedStacks) {
14153                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14154                    logIt = false;
14155                    // TODO: sub-sample into EventLog for these, with
14156                    // the info.durationMillis?  Then we'd get
14157                    // the relative pain numbers, without logging all
14158                    // the stack traces repeatedly.  We'd want to do
14159                    // likewise in the client code, which also does
14160                    // dup suppression, before the Binder call.
14161                } else {
14162                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14163                        mAlreadyLoggedViolatedStacks.clear();
14164                    }
14165                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14166                }
14167            }
14168            if (logIt) {
14169                logStrictModeViolationToDropBox(r, info);
14170            }
14171        }
14172
14173        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14174            AppErrorResult result = new AppErrorResult();
14175            synchronized (this) {
14176                final long origId = Binder.clearCallingIdentity();
14177
14178                Message msg = Message.obtain();
14179                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14180                HashMap<String, Object> data = new HashMap<String, Object>();
14181                data.put("result", result);
14182                data.put("app", r);
14183                data.put("violationMask", violationMask);
14184                data.put("info", info);
14185                msg.obj = data;
14186                mUiHandler.sendMessage(msg);
14187
14188                Binder.restoreCallingIdentity(origId);
14189            }
14190            int res = result.get();
14191            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14192        }
14193    }
14194
14195    // Depending on the policy in effect, there could be a bunch of
14196    // these in quick succession so we try to batch these together to
14197    // minimize disk writes, number of dropbox entries, and maximize
14198    // compression, by having more fewer, larger records.
14199    private void logStrictModeViolationToDropBox(
14200            ProcessRecord process,
14201            StrictMode.ViolationInfo info) {
14202        if (info == null) {
14203            return;
14204        }
14205        final boolean isSystemApp = process == null ||
14206                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14207                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14208        final String processName = process == null ? "unknown" : process.processName;
14209        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14210        final DropBoxManager dbox = (DropBoxManager)
14211                mContext.getSystemService(Context.DROPBOX_SERVICE);
14212
14213        // Exit early if the dropbox isn't configured to accept this report type.
14214        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14215
14216        boolean bufferWasEmpty;
14217        boolean needsFlush;
14218        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14219        synchronized (sb) {
14220            bufferWasEmpty = sb.length() == 0;
14221            appendDropBoxProcessHeaders(process, processName, sb);
14222            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14223            sb.append("System-App: ").append(isSystemApp).append("\n");
14224            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14225            if (info.violationNumThisLoop != 0) {
14226                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14227            }
14228            if (info.numAnimationsRunning != 0) {
14229                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14230            }
14231            if (info.broadcastIntentAction != null) {
14232                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14233            }
14234            if (info.durationMillis != -1) {
14235                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14236            }
14237            if (info.numInstances != -1) {
14238                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14239            }
14240            if (info.tags != null) {
14241                for (String tag : info.tags) {
14242                    sb.append("Span-Tag: ").append(tag).append("\n");
14243                }
14244            }
14245            sb.append("\n");
14246            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14247                sb.append(info.crashInfo.stackTrace);
14248                sb.append("\n");
14249            }
14250            if (info.message != null) {
14251                sb.append(info.message);
14252                sb.append("\n");
14253            }
14254
14255            // Only buffer up to ~64k.  Various logging bits truncate
14256            // things at 128k.
14257            needsFlush = (sb.length() > 64 * 1024);
14258        }
14259
14260        // Flush immediately if the buffer's grown too large, or this
14261        // is a non-system app.  Non-system apps are isolated with a
14262        // different tag & policy and not batched.
14263        //
14264        // Batching is useful during internal testing with
14265        // StrictMode settings turned up high.  Without batching,
14266        // thousands of separate files could be created on boot.
14267        if (!isSystemApp || needsFlush) {
14268            new Thread("Error dump: " + dropboxTag) {
14269                @Override
14270                public void run() {
14271                    String report;
14272                    synchronized (sb) {
14273                        report = sb.toString();
14274                        sb.delete(0, sb.length());
14275                        sb.trimToSize();
14276                    }
14277                    if (report.length() != 0) {
14278                        dbox.addText(dropboxTag, report);
14279                    }
14280                }
14281            }.start();
14282            return;
14283        }
14284
14285        // System app batching:
14286        if (!bufferWasEmpty) {
14287            // An existing dropbox-writing thread is outstanding, so
14288            // we don't need to start it up.  The existing thread will
14289            // catch the buffer appends we just did.
14290            return;
14291        }
14292
14293        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14294        // (After this point, we shouldn't access AMS internal data structures.)
14295        new Thread("Error dump: " + dropboxTag) {
14296            @Override
14297            public void run() {
14298                // 5 second sleep to let stacks arrive and be batched together
14299                try {
14300                    Thread.sleep(5000);  // 5 seconds
14301                } catch (InterruptedException e) {}
14302
14303                String errorReport;
14304                synchronized (mStrictModeBuffer) {
14305                    errorReport = mStrictModeBuffer.toString();
14306                    if (errorReport.length() == 0) {
14307                        return;
14308                    }
14309                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14310                    mStrictModeBuffer.trimToSize();
14311                }
14312                dbox.addText(dropboxTag, errorReport);
14313            }
14314        }.start();
14315    }
14316
14317    /**
14318     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14319     * @param app object of the crashing app, null for the system server
14320     * @param tag reported by the caller
14321     * @param system whether this wtf is coming from the system
14322     * @param crashInfo describing the context of the error
14323     * @return true if the process should exit immediately (WTF is fatal)
14324     */
14325    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14326            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14327        final int callingUid = Binder.getCallingUid();
14328        final int callingPid = Binder.getCallingPid();
14329
14330        if (system) {
14331            // If this is coming from the system, we could very well have low-level
14332            // system locks held, so we want to do this all asynchronously.  And we
14333            // never want this to become fatal, so there is that too.
14334            mHandler.post(new Runnable() {
14335                @Override public void run() {
14336                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14337                }
14338            });
14339            return false;
14340        }
14341
14342        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14343                crashInfo);
14344
14345        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14346                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14347        final boolean isSystem = (r == null) || r.persistent;
14348
14349        if (isFatal && !isSystem) {
14350            mAppErrors.crashApplication(r, crashInfo);
14351            return true;
14352        } else {
14353            return false;
14354        }
14355    }
14356
14357    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14358            final ApplicationErrorReport.CrashInfo crashInfo) {
14359        final ProcessRecord r = findAppProcess(app, "WTF");
14360        final String processName = app == null ? "system_server"
14361                : (r == null ? "unknown" : r.processName);
14362
14363        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14364                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14365
14366        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14367
14368        return r;
14369    }
14370
14371    /**
14372     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14373     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14374     */
14375    private ProcessRecord findAppProcess(IBinder app, String reason) {
14376        if (app == null) {
14377            return null;
14378        }
14379
14380        synchronized (this) {
14381            final int NP = mProcessNames.getMap().size();
14382            for (int ip=0; ip<NP; ip++) {
14383                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14384                final int NA = apps.size();
14385                for (int ia=0; ia<NA; ia++) {
14386                    ProcessRecord p = apps.valueAt(ia);
14387                    if (p.thread != null && p.thread.asBinder() == app) {
14388                        return p;
14389                    }
14390                }
14391            }
14392
14393            Slog.w(TAG, "Can't find mystery application for " + reason
14394                    + " from pid=" + Binder.getCallingPid()
14395                    + " uid=" + Binder.getCallingUid() + ": " + app);
14396            return null;
14397        }
14398    }
14399
14400    /**
14401     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14402     * to append various headers to the dropbox log text.
14403     */
14404    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14405            StringBuilder sb) {
14406        // Watchdog thread ends up invoking this function (with
14407        // a null ProcessRecord) to add the stack file to dropbox.
14408        // Do not acquire a lock on this (am) in such cases, as it
14409        // could cause a potential deadlock, if and when watchdog
14410        // is invoked due to unavailability of lock on am and it
14411        // would prevent watchdog from killing system_server.
14412        if (process == null) {
14413            sb.append("Process: ").append(processName).append("\n");
14414            return;
14415        }
14416        // Note: ProcessRecord 'process' is guarded by the service
14417        // instance.  (notably process.pkgList, which could otherwise change
14418        // concurrently during execution of this method)
14419        synchronized (this) {
14420            sb.append("Process: ").append(processName).append("\n");
14421            int flags = process.info.flags;
14422            IPackageManager pm = AppGlobals.getPackageManager();
14423            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14424            for (int ip=0; ip<process.pkgList.size(); ip++) {
14425                String pkg = process.pkgList.keyAt(ip);
14426                sb.append("Package: ").append(pkg);
14427                try {
14428                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14429                    if (pi != null) {
14430                        sb.append(" v").append(pi.versionCode);
14431                        if (pi.versionName != null) {
14432                            sb.append(" (").append(pi.versionName).append(")");
14433                        }
14434                    }
14435                } catch (RemoteException e) {
14436                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14437                }
14438                sb.append("\n");
14439            }
14440        }
14441    }
14442
14443    private static String processClass(ProcessRecord process) {
14444        if (process == null || process.pid == MY_PID) {
14445            return "system_server";
14446        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14447            return "system_app";
14448        } else {
14449            return "data_app";
14450        }
14451    }
14452
14453    private volatile long mWtfClusterStart;
14454    private volatile int mWtfClusterCount;
14455
14456    /**
14457     * Write a description of an error (crash, WTF, ANR) to the drop box.
14458     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14459     * @param process which caused the error, null means the system server
14460     * @param activity which triggered the error, null if unknown
14461     * @param parent activity related to the error, null if unknown
14462     * @param subject line related to the error, null if absent
14463     * @param report in long form describing the error, null if absent
14464     * @param dataFile text file to include in the report, null if none
14465     * @param crashInfo giving an application stack trace, null if absent
14466     */
14467    public void addErrorToDropBox(String eventType,
14468            ProcessRecord process, String processName, ActivityRecord activity,
14469            ActivityRecord parent, String subject,
14470            final String report, final File dataFile,
14471            final ApplicationErrorReport.CrashInfo crashInfo) {
14472        // NOTE -- this must never acquire the ActivityManagerService lock,
14473        // otherwise the watchdog may be prevented from resetting the system.
14474
14475        // Bail early if not published yet
14476        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14477        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14478
14479        // Exit early if the dropbox isn't configured to accept this report type.
14480        final String dropboxTag = processClass(process) + "_" + eventType;
14481        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14482
14483        // Rate-limit how often we're willing to do the heavy lifting below to
14484        // collect and record logs; currently 5 logs per 10 second period.
14485        final long now = SystemClock.elapsedRealtime();
14486        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14487            mWtfClusterStart = now;
14488            mWtfClusterCount = 1;
14489        } else {
14490            if (mWtfClusterCount++ >= 5) return;
14491        }
14492
14493        final StringBuilder sb = new StringBuilder(1024);
14494        appendDropBoxProcessHeaders(process, processName, sb);
14495        if (process != null) {
14496            sb.append("Foreground: ")
14497                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14498                    .append("\n");
14499        }
14500        if (activity != null) {
14501            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14502        }
14503        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14504            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14505        }
14506        if (parent != null && parent != activity) {
14507            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14508        }
14509        if (subject != null) {
14510            sb.append("Subject: ").append(subject).append("\n");
14511        }
14512        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14513        if (Debug.isDebuggerConnected()) {
14514            sb.append("Debugger: Connected\n");
14515        }
14516        sb.append("\n");
14517
14518        // Do the rest in a worker thread to avoid blocking the caller on I/O
14519        // (After this point, we shouldn't access AMS internal data structures.)
14520        Thread worker = new Thread("Error dump: " + dropboxTag) {
14521            @Override
14522            public void run() {
14523                if (report != null) {
14524                    sb.append(report);
14525                }
14526
14527                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14528                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14529                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14530                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14531
14532                if (dataFile != null && maxDataFileSize > 0) {
14533                    try {
14534                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14535                                    "\n\n[[TRUNCATED]]"));
14536                    } catch (IOException e) {
14537                        Slog.e(TAG, "Error reading " + dataFile, e);
14538                    }
14539                }
14540                if (crashInfo != null && crashInfo.stackTrace != null) {
14541                    sb.append(crashInfo.stackTrace);
14542                }
14543
14544                if (lines > 0) {
14545                    sb.append("\n");
14546
14547                    // Merge several logcat streams, and take the last N lines
14548                    InputStreamReader input = null;
14549                    try {
14550                        java.lang.Process logcat = new ProcessBuilder(
14551                                "/system/bin/timeout", "-k", "15s", "10s",
14552                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14553                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14554                                        .redirectErrorStream(true).start();
14555
14556                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14557                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14558                        input = new InputStreamReader(logcat.getInputStream());
14559
14560                        int num;
14561                        char[] buf = new char[8192];
14562                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14563                    } catch (IOException e) {
14564                        Slog.e(TAG, "Error running logcat", e);
14565                    } finally {
14566                        if (input != null) try { input.close(); } catch (IOException e) {}
14567                    }
14568                }
14569
14570                dbox.addText(dropboxTag, sb.toString());
14571            }
14572        };
14573
14574        if (process == null) {
14575            // If process is null, we are being called from some internal code
14576            // and may be about to die -- run this synchronously.
14577            worker.run();
14578        } else {
14579            worker.start();
14580        }
14581    }
14582
14583    @Override
14584    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14585        enforceNotIsolatedCaller("getProcessesInErrorState");
14586        // assume our apps are happy - lazy create the list
14587        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14588
14589        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14590                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14591        int userId = UserHandle.getUserId(Binder.getCallingUid());
14592
14593        synchronized (this) {
14594
14595            // iterate across all processes
14596            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14597                ProcessRecord app = mLruProcesses.get(i);
14598                if (!allUsers && app.userId != userId) {
14599                    continue;
14600                }
14601                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14602                    // This one's in trouble, so we'll generate a report for it
14603                    // crashes are higher priority (in case there's a crash *and* an anr)
14604                    ActivityManager.ProcessErrorStateInfo report = null;
14605                    if (app.crashing) {
14606                        report = app.crashingReport;
14607                    } else if (app.notResponding) {
14608                        report = app.notRespondingReport;
14609                    }
14610
14611                    if (report != null) {
14612                        if (errList == null) {
14613                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14614                        }
14615                        errList.add(report);
14616                    } else {
14617                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14618                                " crashing = " + app.crashing +
14619                                " notResponding = " + app.notResponding);
14620                    }
14621                }
14622            }
14623        }
14624
14625        return errList;
14626    }
14627
14628    static int procStateToImportance(int procState, int memAdj,
14629            ActivityManager.RunningAppProcessInfo currApp) {
14630        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
14631        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14632            currApp.lru = memAdj;
14633        } else {
14634            currApp.lru = 0;
14635        }
14636        return imp;
14637    }
14638
14639    private void fillInProcMemInfo(ProcessRecord app,
14640            ActivityManager.RunningAppProcessInfo outInfo) {
14641        outInfo.pid = app.pid;
14642        outInfo.uid = app.info.uid;
14643        if (mHeavyWeightProcess == app) {
14644            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14645        }
14646        if (app.persistent) {
14647            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14648        }
14649        if (app.activities.size() > 0) {
14650            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14651        }
14652        outInfo.lastTrimLevel = app.trimMemoryLevel;
14653        int adj = app.curAdj;
14654        int procState = app.curProcState;
14655        outInfo.importance = procStateToImportance(procState, adj, outInfo);
14656        outInfo.importanceReasonCode = app.adjTypeCode;
14657        outInfo.processState = app.curProcState;
14658    }
14659
14660    @Override
14661    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14662        enforceNotIsolatedCaller("getRunningAppProcesses");
14663
14664        final int callingUid = Binder.getCallingUid();
14665
14666        // Lazy instantiation of list
14667        List<ActivityManager.RunningAppProcessInfo> runList = null;
14668        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14669                callingUid) == PackageManager.PERMISSION_GRANTED;
14670        final int userId = UserHandle.getUserId(callingUid);
14671        final boolean allUids = isGetTasksAllowed(
14672                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14673
14674        synchronized (this) {
14675            // Iterate across all processes
14676            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14677                ProcessRecord app = mLruProcesses.get(i);
14678                if ((!allUsers && app.userId != userId)
14679                        || (!allUids && app.uid != callingUid)) {
14680                    continue;
14681                }
14682                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14683                    // Generate process state info for running application
14684                    ActivityManager.RunningAppProcessInfo currApp =
14685                        new ActivityManager.RunningAppProcessInfo(app.processName,
14686                                app.pid, app.getPackageList());
14687                    fillInProcMemInfo(app, currApp);
14688                    if (app.adjSource instanceof ProcessRecord) {
14689                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14690                        currApp.importanceReasonImportance =
14691                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14692                                        app.adjSourceProcState);
14693                    } else if (app.adjSource instanceof ActivityRecord) {
14694                        ActivityRecord r = (ActivityRecord)app.adjSource;
14695                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14696                    }
14697                    if (app.adjTarget instanceof ComponentName) {
14698                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14699                    }
14700                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14701                    //        + " lru=" + currApp.lru);
14702                    if (runList == null) {
14703                        runList = new ArrayList<>();
14704                    }
14705                    runList.add(currApp);
14706                }
14707            }
14708        }
14709        return runList;
14710    }
14711
14712    @Override
14713    public List<ApplicationInfo> getRunningExternalApplications() {
14714        enforceNotIsolatedCaller("getRunningExternalApplications");
14715        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14716        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14717        if (runningApps != null && runningApps.size() > 0) {
14718            Set<String> extList = new HashSet<String>();
14719            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14720                if (app.pkgList != null) {
14721                    for (String pkg : app.pkgList) {
14722                        extList.add(pkg);
14723                    }
14724                }
14725            }
14726            IPackageManager pm = AppGlobals.getPackageManager();
14727            for (String pkg : extList) {
14728                try {
14729                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14730                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14731                        retList.add(info);
14732                    }
14733                } catch (RemoteException e) {
14734                }
14735            }
14736        }
14737        return retList;
14738    }
14739
14740    @Override
14741    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14742        enforceNotIsolatedCaller("getMyMemoryState");
14743        synchronized (this) {
14744            ProcessRecord proc;
14745            synchronized (mPidsSelfLocked) {
14746                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14747            }
14748            fillInProcMemInfo(proc, outInfo);
14749        }
14750    }
14751
14752    @Override
14753    public int getMemoryTrimLevel() {
14754        enforceNotIsolatedCaller("getMyMemoryState");
14755        synchronized (this) {
14756            return mLastMemoryLevel;
14757        }
14758    }
14759
14760    @Override
14761    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14762            FileDescriptor err, String[] args, ShellCallback callback,
14763            ResultReceiver resultReceiver) {
14764        (new ActivityManagerShellCommand(this, false)).exec(
14765                this, in, out, err, args, callback, resultReceiver);
14766    }
14767
14768    @Override
14769    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14770        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14771
14772        boolean dumpAll = false;
14773        boolean dumpClient = false;
14774        boolean dumpCheckin = false;
14775        boolean dumpCheckinFormat = false;
14776        boolean dumpVisibleStacksOnly = false;
14777        boolean dumpFocusedStackOnly = false;
14778        String dumpPackage = null;
14779
14780        int opti = 0;
14781        while (opti < args.length) {
14782            String opt = args[opti];
14783            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14784                break;
14785            }
14786            opti++;
14787            if ("-a".equals(opt)) {
14788                dumpAll = true;
14789            } else if ("-c".equals(opt)) {
14790                dumpClient = true;
14791            } else if ("-v".equals(opt)) {
14792                dumpVisibleStacksOnly = true;
14793            } else if ("-f".equals(opt)) {
14794                dumpFocusedStackOnly = true;
14795            } else if ("-p".equals(opt)) {
14796                if (opti < args.length) {
14797                    dumpPackage = args[opti];
14798                    opti++;
14799                } else {
14800                    pw.println("Error: -p option requires package argument");
14801                    return;
14802                }
14803                dumpClient = true;
14804            } else if ("--checkin".equals(opt)) {
14805                dumpCheckin = dumpCheckinFormat = true;
14806            } else if ("-C".equals(opt)) {
14807                dumpCheckinFormat = true;
14808            } else if ("-h".equals(opt)) {
14809                ActivityManagerShellCommand.dumpHelp(pw, true);
14810                return;
14811            } else {
14812                pw.println("Unknown argument: " + opt + "; use -h for help");
14813            }
14814        }
14815
14816        long origId = Binder.clearCallingIdentity();
14817        boolean more = false;
14818        // Is the caller requesting to dump a particular piece of data?
14819        if (opti < args.length) {
14820            String cmd = args[opti];
14821            opti++;
14822            if ("activities".equals(cmd) || "a".equals(cmd)) {
14823                synchronized (this) {
14824                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14825                }
14826            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14827                synchronized (this) {
14828                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14829                }
14830            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14831                String[] newArgs;
14832                String name;
14833                if (opti >= args.length) {
14834                    name = null;
14835                    newArgs = EMPTY_STRING_ARRAY;
14836                } else {
14837                    dumpPackage = args[opti];
14838                    opti++;
14839                    newArgs = new String[args.length - opti];
14840                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14841                            args.length - opti);
14842                }
14843                synchronized (this) {
14844                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14845                }
14846            } else if ("broadcast-stats".equals(cmd)) {
14847                String[] newArgs;
14848                String name;
14849                if (opti >= args.length) {
14850                    name = null;
14851                    newArgs = EMPTY_STRING_ARRAY;
14852                } else {
14853                    dumpPackage = args[opti];
14854                    opti++;
14855                    newArgs = new String[args.length - opti];
14856                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14857                            args.length - opti);
14858                }
14859                synchronized (this) {
14860                    if (dumpCheckinFormat) {
14861                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14862                                dumpPackage);
14863                    } else {
14864                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14865                    }
14866                }
14867            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14868                String[] newArgs;
14869                String name;
14870                if (opti >= args.length) {
14871                    name = null;
14872                    newArgs = EMPTY_STRING_ARRAY;
14873                } else {
14874                    dumpPackage = args[opti];
14875                    opti++;
14876                    newArgs = new String[args.length - opti];
14877                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14878                            args.length - opti);
14879                }
14880                synchronized (this) {
14881                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14882                }
14883            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14884                String[] newArgs;
14885                String name;
14886                if (opti >= args.length) {
14887                    name = null;
14888                    newArgs = EMPTY_STRING_ARRAY;
14889                } else {
14890                    dumpPackage = args[opti];
14891                    opti++;
14892                    newArgs = new String[args.length - opti];
14893                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14894                            args.length - opti);
14895                }
14896                synchronized (this) {
14897                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14898                }
14899            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14900                synchronized (this) {
14901                    dumpOomLocked(fd, pw, args, opti, true);
14902                }
14903            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14904                synchronized (this) {
14905                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14906                }
14907            } else if ("provider".equals(cmd)) {
14908                String[] newArgs;
14909                String name;
14910                if (opti >= args.length) {
14911                    name = null;
14912                    newArgs = EMPTY_STRING_ARRAY;
14913                } else {
14914                    name = args[opti];
14915                    opti++;
14916                    newArgs = new String[args.length - opti];
14917                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14918                }
14919                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14920                    pw.println("No providers match: " + name);
14921                    pw.println("Use -h for help.");
14922                }
14923            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14924                synchronized (this) {
14925                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14926                }
14927            } else if ("service".equals(cmd)) {
14928                String[] newArgs;
14929                String name;
14930                if (opti >= args.length) {
14931                    name = null;
14932                    newArgs = EMPTY_STRING_ARRAY;
14933                } else {
14934                    name = args[opti];
14935                    opti++;
14936                    newArgs = new String[args.length - opti];
14937                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14938                            args.length - opti);
14939                }
14940                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14941                    pw.println("No services match: " + name);
14942                    pw.println("Use -h for help.");
14943                }
14944            } else if ("package".equals(cmd)) {
14945                String[] newArgs;
14946                if (opti >= args.length) {
14947                    pw.println("package: no package name specified");
14948                    pw.println("Use -h for help.");
14949                } else {
14950                    dumpPackage = args[opti];
14951                    opti++;
14952                    newArgs = new String[args.length - opti];
14953                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14954                            args.length - opti);
14955                    args = newArgs;
14956                    opti = 0;
14957                    more = true;
14958                }
14959            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14960                synchronized (this) {
14961                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14962                }
14963            } else if ("settings".equals(cmd)) {
14964                synchronized (this) {
14965                    mConstants.dump(pw);
14966                }
14967            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14968                if (dumpClient) {
14969                    ActiveServices.ServiceDumper dumper;
14970                    synchronized (this) {
14971                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14972                                dumpPackage);
14973                    }
14974                    dumper.dumpWithClient();
14975                } else {
14976                    synchronized (this) {
14977                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14978                                dumpPackage).dumpLocked();
14979                    }
14980                }
14981            } else if ("locks".equals(cmd)) {
14982                LockGuard.dump(fd, pw, args);
14983            } else {
14984                // Dumping a single activity?
14985                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
14986                        dumpFocusedStackOnly)) {
14987                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14988                    int res = shell.exec(this, null, fd, null, args, null,
14989                            new ResultReceiver(null));
14990                    if (res < 0) {
14991                        pw.println("Bad activity command, or no activities match: " + cmd);
14992                        pw.println("Use -h for help.");
14993                    }
14994                }
14995            }
14996            if (!more) {
14997                Binder.restoreCallingIdentity(origId);
14998                return;
14999            }
15000        }
15001
15002        // No piece of data specified, dump everything.
15003        if (dumpCheckinFormat) {
15004            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15005        } else if (dumpClient) {
15006            ActiveServices.ServiceDumper sdumper;
15007            synchronized (this) {
15008                mConstants.dump(pw);
15009                pw.println();
15010                if (dumpAll) {
15011                    pw.println("-------------------------------------------------------------------------------");
15012                }
15013                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15014                pw.println();
15015                if (dumpAll) {
15016                    pw.println("-------------------------------------------------------------------------------");
15017                }
15018                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15019                pw.println();
15020                if (dumpAll) {
15021                    pw.println("-------------------------------------------------------------------------------");
15022                }
15023                if (dumpAll || dumpPackage != null) {
15024                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15025                    pw.println();
15026                    if (dumpAll) {
15027                        pw.println("-------------------------------------------------------------------------------");
15028                    }
15029                }
15030                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15031                pw.println();
15032                if (dumpAll) {
15033                    pw.println("-------------------------------------------------------------------------------");
15034                }
15035                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15036                pw.println();
15037                if (dumpAll) {
15038                    pw.println("-------------------------------------------------------------------------------");
15039                }
15040                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15041                        dumpPackage);
15042            }
15043            sdumper.dumpWithClient();
15044            pw.println();
15045            synchronized (this) {
15046                if (dumpAll) {
15047                    pw.println("-------------------------------------------------------------------------------");
15048                }
15049                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15050                pw.println();
15051                if (dumpAll) {
15052                    pw.println("-------------------------------------------------------------------------------");
15053                }
15054                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15055                if (mAssociations.size() > 0) {
15056                    pw.println();
15057                    if (dumpAll) {
15058                        pw.println("-------------------------------------------------------------------------------");
15059                    }
15060                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15061                }
15062                pw.println();
15063                if (dumpAll) {
15064                    pw.println("-------------------------------------------------------------------------------");
15065                }
15066                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15067            }
15068
15069        } else {
15070            synchronized (this) {
15071                mConstants.dump(pw);
15072                pw.println();
15073                if (dumpAll) {
15074                    pw.println("-------------------------------------------------------------------------------");
15075                }
15076                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15077                pw.println();
15078                if (dumpAll) {
15079                    pw.println("-------------------------------------------------------------------------------");
15080                }
15081                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15082                pw.println();
15083                if (dumpAll) {
15084                    pw.println("-------------------------------------------------------------------------------");
15085                }
15086                if (dumpAll || dumpPackage != null) {
15087                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15088                    pw.println();
15089                    if (dumpAll) {
15090                        pw.println("-------------------------------------------------------------------------------");
15091                    }
15092                }
15093                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15094                pw.println();
15095                if (dumpAll) {
15096                    pw.println("-------------------------------------------------------------------------------");
15097                }
15098                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15099                pw.println();
15100                if (dumpAll) {
15101                    pw.println("-------------------------------------------------------------------------------");
15102                }
15103                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15104                        .dumpLocked();
15105                pw.println();
15106                if (dumpAll) {
15107                    pw.println("-------------------------------------------------------------------------------");
15108                }
15109                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15110                pw.println();
15111                if (dumpAll) {
15112                    pw.println("-------------------------------------------------------------------------------");
15113                }
15114                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15115                if (mAssociations.size() > 0) {
15116                    pw.println();
15117                    if (dumpAll) {
15118                        pw.println("-------------------------------------------------------------------------------");
15119                    }
15120                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15121                }
15122                pw.println();
15123                if (dumpAll) {
15124                    pw.println("-------------------------------------------------------------------------------");
15125                }
15126                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15127            }
15128        }
15129        Binder.restoreCallingIdentity(origId);
15130    }
15131
15132    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15133            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15134        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15135
15136        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15137                dumpPackage);
15138        boolean needSep = printedAnything;
15139
15140        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15141                mStackSupervisor.getResumedActivityLocked(),
15142                dumpPackage, needSep, "  ResumedActivity: ");
15143        if (printed) {
15144            printedAnything = true;
15145            needSep = false;
15146        }
15147
15148        if (dumpPackage == null) {
15149            if (needSep) {
15150                pw.println();
15151            }
15152            needSep = true;
15153            printedAnything = true;
15154            mStackSupervisor.dump(pw, "  ");
15155        }
15156
15157        if (!printedAnything) {
15158            pw.println("  (nothing)");
15159        }
15160    }
15161
15162    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15163            int opti, boolean dumpAll, String dumpPackage) {
15164        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15165
15166        boolean printedAnything = false;
15167
15168        if (mRecentTasks != null && mRecentTasks.size() > 0) {
15169            boolean printedHeader = false;
15170
15171            final int N = mRecentTasks.size();
15172            for (int i=0; i<N; i++) {
15173                TaskRecord tr = mRecentTasks.get(i);
15174                if (dumpPackage != null) {
15175                    if (tr.realActivity == null ||
15176                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
15177                        continue;
15178                    }
15179                }
15180                if (!printedHeader) {
15181                    pw.println("  Recent tasks:");
15182                    printedHeader = true;
15183                    printedAnything = true;
15184                }
15185                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15186                        pw.println(tr);
15187                if (dumpAll) {
15188                    mRecentTasks.get(i).dump(pw, "    ");
15189                }
15190            }
15191        }
15192
15193        if (!printedAnything) {
15194            pw.println("  (nothing)");
15195        }
15196    }
15197
15198    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15199            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15200        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15201
15202        int dumpUid = 0;
15203        if (dumpPackage != null) {
15204            IPackageManager pm = AppGlobals.getPackageManager();
15205            try {
15206                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15207            } catch (RemoteException e) {
15208            }
15209        }
15210
15211        boolean printedAnything = false;
15212
15213        final long now = SystemClock.uptimeMillis();
15214
15215        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15216            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15217                    = mAssociations.valueAt(i1);
15218            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15219                SparseArray<ArrayMap<String, Association>> sourceUids
15220                        = targetComponents.valueAt(i2);
15221                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15222                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15223                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15224                        Association ass = sourceProcesses.valueAt(i4);
15225                        if (dumpPackage != null) {
15226                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15227                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15228                                continue;
15229                            }
15230                        }
15231                        printedAnything = true;
15232                        pw.print("  ");
15233                        pw.print(ass.mTargetProcess);
15234                        pw.print("/");
15235                        UserHandle.formatUid(pw, ass.mTargetUid);
15236                        pw.print(" <- ");
15237                        pw.print(ass.mSourceProcess);
15238                        pw.print("/");
15239                        UserHandle.formatUid(pw, ass.mSourceUid);
15240                        pw.println();
15241                        pw.print("    via ");
15242                        pw.print(ass.mTargetComponent.flattenToShortString());
15243                        pw.println();
15244                        pw.print("    ");
15245                        long dur = ass.mTime;
15246                        if (ass.mNesting > 0) {
15247                            dur += now - ass.mStartTime;
15248                        }
15249                        TimeUtils.formatDuration(dur, pw);
15250                        pw.print(" (");
15251                        pw.print(ass.mCount);
15252                        pw.print(" times)");
15253                        pw.print("  ");
15254                        for (int i=0; i<ass.mStateTimes.length; i++) {
15255                            long amt = ass.mStateTimes[i];
15256                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15257                                amt += now - ass.mLastStateUptime;
15258                            }
15259                            if (amt != 0) {
15260                                pw.print(" ");
15261                                pw.print(ProcessList.makeProcStateString(
15262                                            i + ActivityManager.MIN_PROCESS_STATE));
15263                                pw.print("=");
15264                                TimeUtils.formatDuration(amt, pw);
15265                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15266                                    pw.print("*");
15267                                }
15268                            }
15269                        }
15270                        pw.println();
15271                        if (ass.mNesting > 0) {
15272                            pw.print("    Currently active: ");
15273                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15274                            pw.println();
15275                        }
15276                    }
15277                }
15278            }
15279
15280        }
15281
15282        if (!printedAnything) {
15283            pw.println("  (nothing)");
15284        }
15285    }
15286
15287    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15288            String header, boolean needSep) {
15289        boolean printed = false;
15290        int whichAppId = -1;
15291        if (dumpPackage != null) {
15292            try {
15293                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15294                        dumpPackage, 0);
15295                whichAppId = UserHandle.getAppId(info.uid);
15296            } catch (NameNotFoundException e) {
15297                e.printStackTrace();
15298            }
15299        }
15300        for (int i=0; i<uids.size(); i++) {
15301            UidRecord uidRec = uids.valueAt(i);
15302            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15303                continue;
15304            }
15305            if (!printed) {
15306                printed = true;
15307                if (needSep) {
15308                    pw.println();
15309                }
15310                pw.print("  ");
15311                pw.println(header);
15312                needSep = true;
15313            }
15314            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15315            pw.print(": "); pw.println(uidRec);
15316        }
15317        return printed;
15318    }
15319
15320    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15321            int opti, boolean dumpAll, String dumpPackage) {
15322        boolean needSep = false;
15323        boolean printedAnything = false;
15324        int numPers = 0;
15325
15326        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15327
15328        if (dumpAll) {
15329            final int NP = mProcessNames.getMap().size();
15330            for (int ip=0; ip<NP; ip++) {
15331                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15332                final int NA = procs.size();
15333                for (int ia=0; ia<NA; ia++) {
15334                    ProcessRecord r = procs.valueAt(ia);
15335                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15336                        continue;
15337                    }
15338                    if (!needSep) {
15339                        pw.println("  All known processes:");
15340                        needSep = true;
15341                        printedAnything = true;
15342                    }
15343                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15344                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15345                        pw.print(" "); pw.println(r);
15346                    r.dump(pw, "    ");
15347                    if (r.persistent) {
15348                        numPers++;
15349                    }
15350                }
15351            }
15352        }
15353
15354        if (mIsolatedProcesses.size() > 0) {
15355            boolean printed = false;
15356            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15357                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15358                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15359                    continue;
15360                }
15361                if (!printed) {
15362                    if (needSep) {
15363                        pw.println();
15364                    }
15365                    pw.println("  Isolated process list (sorted by uid):");
15366                    printedAnything = true;
15367                    printed = true;
15368                    needSep = true;
15369                }
15370                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15371                pw.println(r);
15372            }
15373        }
15374
15375        if (mActiveInstrumentation.size() > 0) {
15376            boolean printed = false;
15377            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15378                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15379                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15380                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15381                    continue;
15382                }
15383                if (!printed) {
15384                    if (needSep) {
15385                        pw.println();
15386                    }
15387                    pw.println("  Active instrumentation:");
15388                    printedAnything = true;
15389                    printed = true;
15390                    needSep = true;
15391                }
15392                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15393                pw.println(ai);
15394                ai.dump(pw, "      ");
15395            }
15396        }
15397
15398        if (mActiveUids.size() > 0) {
15399            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15400                printedAnything = needSep = true;
15401            }
15402        }
15403        if (dumpAll) {
15404            if (mValidateUids.size() > 0) {
15405                if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15406                    printedAnything = needSep = true;
15407                }
15408            }
15409        }
15410
15411        if (mLruProcesses.size() > 0) {
15412            if (needSep) {
15413                pw.println();
15414            }
15415            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15416                    pw.print(" total, non-act at ");
15417                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15418                    pw.print(", non-svc at ");
15419                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15420                    pw.println("):");
15421            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15422            needSep = true;
15423            printedAnything = true;
15424        }
15425
15426        if (dumpAll || dumpPackage != null) {
15427            synchronized (mPidsSelfLocked) {
15428                boolean printed = false;
15429                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15430                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15431                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15432                        continue;
15433                    }
15434                    if (!printed) {
15435                        if (needSep) pw.println();
15436                        needSep = true;
15437                        pw.println("  PID mappings:");
15438                        printed = true;
15439                        printedAnything = true;
15440                    }
15441                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15442                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15443                }
15444            }
15445        }
15446
15447        if (mForegroundProcesses.size() > 0) {
15448            synchronized (mPidsSelfLocked) {
15449                boolean printed = false;
15450                for (int i=0; i<mForegroundProcesses.size(); i++) {
15451                    ProcessRecord r = mPidsSelfLocked.get(
15452                            mForegroundProcesses.valueAt(i).pid);
15453                    if (dumpPackage != null && (r == null
15454                            || !r.pkgList.containsKey(dumpPackage))) {
15455                        continue;
15456                    }
15457                    if (!printed) {
15458                        if (needSep) pw.println();
15459                        needSep = true;
15460                        pw.println("  Foreground Processes:");
15461                        printed = true;
15462                        printedAnything = true;
15463                    }
15464                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
15465                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
15466                }
15467            }
15468        }
15469
15470        if (mPersistentStartingProcesses.size() > 0) {
15471            if (needSep) pw.println();
15472            needSep = true;
15473            printedAnything = true;
15474            pw.println("  Persisent processes that are starting:");
15475            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15476                    "Starting Norm", "Restarting PERS", dumpPackage);
15477        }
15478
15479        if (mRemovedProcesses.size() > 0) {
15480            if (needSep) pw.println();
15481            needSep = true;
15482            printedAnything = true;
15483            pw.println("  Processes that are being removed:");
15484            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15485                    "Removed Norm", "Removed PERS", dumpPackage);
15486        }
15487
15488        if (mProcessesOnHold.size() > 0) {
15489            if (needSep) pw.println();
15490            needSep = true;
15491            printedAnything = true;
15492            pw.println("  Processes that are on old until the system is ready:");
15493            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15494                    "OnHold Norm", "OnHold PERS", dumpPackage);
15495        }
15496
15497        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15498
15499        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15500        if (needSep) {
15501            printedAnything = true;
15502        }
15503
15504        if (dumpPackage == null) {
15505            pw.println();
15506            needSep = false;
15507            mUserController.dump(pw, dumpAll);
15508        }
15509        if (mHomeProcess != null && (dumpPackage == null
15510                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15511            if (needSep) {
15512                pw.println();
15513                needSep = false;
15514            }
15515            pw.println("  mHomeProcess: " + mHomeProcess);
15516        }
15517        if (mPreviousProcess != null && (dumpPackage == null
15518                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15519            if (needSep) {
15520                pw.println();
15521                needSep = false;
15522            }
15523            pw.println("  mPreviousProcess: " + mPreviousProcess);
15524        }
15525        if (dumpAll) {
15526            StringBuilder sb = new StringBuilder(128);
15527            sb.append("  mPreviousProcessVisibleTime: ");
15528            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15529            pw.println(sb);
15530        }
15531        if (mHeavyWeightProcess != null && (dumpPackage == null
15532                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15533            if (needSep) {
15534                pw.println();
15535                needSep = false;
15536            }
15537            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15538        }
15539        if (dumpPackage == null) {
15540            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15541            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15542        }
15543        if (dumpAll) {
15544            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15545            if (mCompatModePackages.getPackages().size() > 0) {
15546                boolean printed = false;
15547                for (Map.Entry<String, Integer> entry
15548                        : mCompatModePackages.getPackages().entrySet()) {
15549                    String pkg = entry.getKey();
15550                    int mode = entry.getValue();
15551                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15552                        continue;
15553                    }
15554                    if (!printed) {
15555                        pw.println("  mScreenCompatPackages:");
15556                        printed = true;
15557                    }
15558                    pw.print("    "); pw.print(pkg); pw.print(": ");
15559                            pw.print(mode); pw.println();
15560                }
15561            }
15562            final int NI = mUidObservers.getRegisteredCallbackCount();
15563            boolean printed = false;
15564            for (int i=0; i<NI; i++) {
15565                final UidObserverRegistration reg = (UidObserverRegistration)
15566                        mUidObservers.getRegisteredCallbackCookie(i);
15567                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15568                    if (!printed) {
15569                        pw.println("  mUidObservers:");
15570                        printed = true;
15571                    }
15572                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15573                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15574                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15575                        pw.print(" IDLE");
15576                    }
15577                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15578                        pw.print(" ACT" );
15579                    }
15580                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15581                        pw.print(" GONE");
15582                    }
15583                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15584                        pw.print(" STATE");
15585                        pw.print(" (cut="); pw.print(reg.cutpoint);
15586                        pw.print(")");
15587                    }
15588                    pw.println();
15589                    if (reg.lastProcStates != null) {
15590                        final int NJ = reg.lastProcStates.size();
15591                        for (int j=0; j<NJ; j++) {
15592                            pw.print("      Last ");
15593                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15594                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15595                        }
15596                    }
15597                }
15598            }
15599            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15600            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15601            if (mPendingTempWhitelist.size() > 0) {
15602                pw.println("  mPendingTempWhitelist:");
15603                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15604                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15605                    pw.print("    ");
15606                    UserHandle.formatUid(pw, ptw.targetUid);
15607                    pw.print(": ");
15608                    TimeUtils.formatDuration(ptw.duration, pw);
15609                    pw.print(" ");
15610                    pw.println(ptw.tag);
15611                }
15612            }
15613        }
15614        if (dumpPackage == null) {
15615            pw.println("  mWakefulness="
15616                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15617            pw.println("  mSleepTokens=" + mSleepTokens);
15618            pw.println("  mSleeping=" + mSleeping);
15619            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15620            if (mRunningVoice != null) {
15621                pw.println("  mRunningVoice=" + mRunningVoice);
15622                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15623            }
15624        }
15625        pw.println("  mVrController=" + mVrController);
15626        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15627                || mOrigWaitForDebugger) {
15628            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15629                    || dumpPackage.equals(mOrigDebugApp)) {
15630                if (needSep) {
15631                    pw.println();
15632                    needSep = false;
15633                }
15634                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15635                        + " mDebugTransient=" + mDebugTransient
15636                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15637            }
15638        }
15639        if (mCurAppTimeTracker != null) {
15640            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15641        }
15642        if (mMemWatchProcesses.getMap().size() > 0) {
15643            pw.println("  Mem watch processes:");
15644            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15645                    = mMemWatchProcesses.getMap();
15646            for (int i=0; i<procs.size(); i++) {
15647                final String proc = procs.keyAt(i);
15648                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15649                for (int j=0; j<uids.size(); j++) {
15650                    if (needSep) {
15651                        pw.println();
15652                        needSep = false;
15653                    }
15654                    StringBuilder sb = new StringBuilder();
15655                    sb.append("    ").append(proc).append('/');
15656                    UserHandle.formatUid(sb, uids.keyAt(j));
15657                    Pair<Long, String> val = uids.valueAt(j);
15658                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15659                    if (val.second != null) {
15660                        sb.append(", report to ").append(val.second);
15661                    }
15662                    pw.println(sb.toString());
15663                }
15664            }
15665            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15666            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15667            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15668                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15669        }
15670        if (mTrackAllocationApp != null) {
15671            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15672                if (needSep) {
15673                    pw.println();
15674                    needSep = false;
15675                }
15676                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15677            }
15678        }
15679        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15680                || mProfileFd != null) {
15681            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15682                if (needSep) {
15683                    pw.println();
15684                    needSep = false;
15685                }
15686                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15687                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15688                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15689                        + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15690                pw.println("  mProfileType=" + mProfileType);
15691            }
15692        }
15693        if (mNativeDebuggingApp != null) {
15694            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15695                if (needSep) {
15696                    pw.println();
15697                    needSep = false;
15698                }
15699                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15700            }
15701        }
15702        if (dumpPackage == null) {
15703            if (mAlwaysFinishActivities) {
15704                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15705            }
15706            if (mController != null) {
15707                pw.println("  mController=" + mController
15708                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15709            }
15710            if (dumpAll) {
15711                pw.println("  Total persistent processes: " + numPers);
15712                pw.println("  mProcessesReady=" + mProcessesReady
15713                        + " mSystemReady=" + mSystemReady
15714                        + " mBooted=" + mBooted
15715                        + " mFactoryTest=" + mFactoryTest);
15716                pw.println("  mBooting=" + mBooting
15717                        + " mCallFinishBooting=" + mCallFinishBooting
15718                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15719                pw.print("  mLastPowerCheckRealtime=");
15720                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15721                        pw.println("");
15722                pw.print("  mLastPowerCheckUptime=");
15723                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15724                        pw.println("");
15725                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15726                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15727                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15728                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15729                        + " (" + mLruProcesses.size() + " total)"
15730                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15731                        + " mNumServiceProcs=" + mNumServiceProcs
15732                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15733                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15734                        + " mLastMemoryLevel=" + mLastMemoryLevel
15735                        + " mLastNumProcesses=" + mLastNumProcesses);
15736                long now = SystemClock.uptimeMillis();
15737                pw.print("  mLastIdleTime=");
15738                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15739                        pw.print(" mLowRamSinceLastIdle=");
15740                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15741                        pw.println();
15742            }
15743        }
15744
15745        if (!printedAnything) {
15746            pw.println("  (nothing)");
15747        }
15748    }
15749
15750    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15751            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15752        if (mProcessesToGc.size() > 0) {
15753            boolean printed = false;
15754            long now = SystemClock.uptimeMillis();
15755            for (int i=0; i<mProcessesToGc.size(); i++) {
15756                ProcessRecord proc = mProcessesToGc.get(i);
15757                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15758                    continue;
15759                }
15760                if (!printed) {
15761                    if (needSep) pw.println();
15762                    needSep = true;
15763                    pw.println("  Processes that are waiting to GC:");
15764                    printed = true;
15765                }
15766                pw.print("    Process "); pw.println(proc);
15767                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15768                        pw.print(", last gced=");
15769                        pw.print(now-proc.lastRequestedGc);
15770                        pw.print(" ms ago, last lowMem=");
15771                        pw.print(now-proc.lastLowMemory);
15772                        pw.println(" ms ago");
15773
15774            }
15775        }
15776        return needSep;
15777    }
15778
15779    void printOomLevel(PrintWriter pw, String name, int adj) {
15780        pw.print("    ");
15781        if (adj >= 0) {
15782            pw.print(' ');
15783            if (adj < 10) pw.print(' ');
15784        } else {
15785            if (adj > -10) pw.print(' ');
15786        }
15787        pw.print(adj);
15788        pw.print(": ");
15789        pw.print(name);
15790        pw.print(" (");
15791        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15792        pw.println(")");
15793    }
15794
15795    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15796            int opti, boolean dumpAll) {
15797        boolean needSep = false;
15798
15799        if (mLruProcesses.size() > 0) {
15800            if (needSep) pw.println();
15801            needSep = true;
15802            pw.println("  OOM levels:");
15803            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15804            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15805            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15806            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15807            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15808            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15809            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15810            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15811            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15812            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15813            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15814            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15815            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15816            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15817
15818            if (needSep) pw.println();
15819            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15820                    pw.print(" total, non-act at ");
15821                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15822                    pw.print(", non-svc at ");
15823                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15824                    pw.println("):");
15825            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15826            needSep = true;
15827        }
15828
15829        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15830
15831        pw.println();
15832        pw.println("  mHomeProcess: " + mHomeProcess);
15833        pw.println("  mPreviousProcess: " + mPreviousProcess);
15834        if (mHeavyWeightProcess != null) {
15835            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15836        }
15837
15838        return true;
15839    }
15840
15841    /**
15842     * There are three ways to call this:
15843     *  - no provider specified: dump all the providers
15844     *  - a flattened component name that matched an existing provider was specified as the
15845     *    first arg: dump that one provider
15846     *  - the first arg isn't the flattened component name of an existing provider:
15847     *    dump all providers whose component contains the first arg as a substring
15848     */
15849    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15850            int opti, boolean dumpAll) {
15851        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15852    }
15853
15854    static class ItemMatcher {
15855        ArrayList<ComponentName> components;
15856        ArrayList<String> strings;
15857        ArrayList<Integer> objects;
15858        boolean all;
15859
15860        ItemMatcher() {
15861            all = true;
15862        }
15863
15864        void build(String name) {
15865            ComponentName componentName = ComponentName.unflattenFromString(name);
15866            if (componentName != null) {
15867                if (components == null) {
15868                    components = new ArrayList<ComponentName>();
15869                }
15870                components.add(componentName);
15871                all = false;
15872            } else {
15873                int objectId = 0;
15874                // Not a '/' separated full component name; maybe an object ID?
15875                try {
15876                    objectId = Integer.parseInt(name, 16);
15877                    if (objects == null) {
15878                        objects = new ArrayList<Integer>();
15879                    }
15880                    objects.add(objectId);
15881                    all = false;
15882                } catch (RuntimeException e) {
15883                    // Not an integer; just do string match.
15884                    if (strings == null) {
15885                        strings = new ArrayList<String>();
15886                    }
15887                    strings.add(name);
15888                    all = false;
15889                }
15890            }
15891        }
15892
15893        int build(String[] args, int opti) {
15894            for (; opti<args.length; opti++) {
15895                String name = args[opti];
15896                if ("--".equals(name)) {
15897                    return opti+1;
15898                }
15899                build(name);
15900            }
15901            return opti;
15902        }
15903
15904        boolean match(Object object, ComponentName comp) {
15905            if (all) {
15906                return true;
15907            }
15908            if (components != null) {
15909                for (int i=0; i<components.size(); i++) {
15910                    if (components.get(i).equals(comp)) {
15911                        return true;
15912                    }
15913                }
15914            }
15915            if (objects != null) {
15916                for (int i=0; i<objects.size(); i++) {
15917                    if (System.identityHashCode(object) == objects.get(i)) {
15918                        return true;
15919                    }
15920                }
15921            }
15922            if (strings != null) {
15923                String flat = comp.flattenToString();
15924                for (int i=0; i<strings.size(); i++) {
15925                    if (flat.contains(strings.get(i))) {
15926                        return true;
15927                    }
15928                }
15929            }
15930            return false;
15931        }
15932    }
15933
15934    /**
15935     * There are three things that cmd can be:
15936     *  - a flattened component name that matches an existing activity
15937     *  - the cmd arg isn't the flattened component name of an existing activity:
15938     *    dump all activity whose component contains the cmd as a substring
15939     *  - A hex number of the ActivityRecord object instance.
15940     *
15941     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
15942     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
15943     */
15944    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15945            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
15946        ArrayList<ActivityRecord> activities;
15947
15948        synchronized (this) {
15949            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
15950                    dumpFocusedStackOnly);
15951        }
15952
15953        if (activities.size() <= 0) {
15954            return false;
15955        }
15956
15957        String[] newArgs = new String[args.length - opti];
15958        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15959
15960        TaskRecord lastTask = null;
15961        boolean needSep = false;
15962        for (int i=activities.size()-1; i>=0; i--) {
15963            ActivityRecord r = activities.get(i);
15964            if (needSep) {
15965                pw.println();
15966            }
15967            needSep = true;
15968            synchronized (this) {
15969                final TaskRecord task = r.getTask();
15970                if (lastTask != task) {
15971                    lastTask = task;
15972                    pw.print("TASK "); pw.print(lastTask.affinity);
15973                            pw.print(" id="); pw.print(lastTask.taskId);
15974                            pw.print(" userId="); pw.println(lastTask.userId);
15975                    if (dumpAll) {
15976                        lastTask.dump(pw, "  ");
15977                    }
15978                }
15979            }
15980            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15981        }
15982        return true;
15983    }
15984
15985    /**
15986     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15987     * there is a thread associated with the activity.
15988     */
15989    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15990            final ActivityRecord r, String[] args, boolean dumpAll) {
15991        String innerPrefix = prefix + "  ";
15992        synchronized (this) {
15993            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15994                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15995                    pw.print(" pid=");
15996                    if (r.app != null) pw.println(r.app.pid);
15997                    else pw.println("(not running)");
15998            if (dumpAll) {
15999                r.dump(pw, innerPrefix);
16000            }
16001        }
16002        if (r.app != null && r.app.thread != null) {
16003            // flush anything that is already in the PrintWriter since the thread is going
16004            // to write to the file descriptor directly
16005            pw.flush();
16006            try {
16007                TransferPipe tp = new TransferPipe();
16008                try {
16009                    r.app.thread.dumpActivity(tp.getWriteFd(),
16010                            r.appToken, innerPrefix, args);
16011                    tp.go(fd);
16012                } finally {
16013                    tp.kill();
16014                }
16015            } catch (IOException e) {
16016                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16017            } catch (RemoteException e) {
16018                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16019            }
16020        }
16021    }
16022
16023    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16024            int opti, boolean dumpAll, String dumpPackage) {
16025        boolean needSep = false;
16026        boolean onlyHistory = false;
16027        boolean printedAnything = false;
16028
16029        if ("history".equals(dumpPackage)) {
16030            if (opti < args.length && "-s".equals(args[opti])) {
16031                dumpAll = false;
16032            }
16033            onlyHistory = true;
16034            dumpPackage = null;
16035        }
16036
16037        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16038        if (!onlyHistory && dumpAll) {
16039            if (mRegisteredReceivers.size() > 0) {
16040                boolean printed = false;
16041                Iterator it = mRegisteredReceivers.values().iterator();
16042                while (it.hasNext()) {
16043                    ReceiverList r = (ReceiverList)it.next();
16044                    if (dumpPackage != null && (r.app == null ||
16045                            !dumpPackage.equals(r.app.info.packageName))) {
16046                        continue;
16047                    }
16048                    if (!printed) {
16049                        pw.println("  Registered Receivers:");
16050                        needSep = true;
16051                        printed = true;
16052                        printedAnything = true;
16053                    }
16054                    pw.print("  * "); pw.println(r);
16055                    r.dump(pw, "    ");
16056                }
16057            }
16058
16059            if (mReceiverResolver.dump(pw, needSep ?
16060                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16061                    "    ", dumpPackage, false, false)) {
16062                needSep = true;
16063                printedAnything = true;
16064            }
16065        }
16066
16067        for (BroadcastQueue q : mBroadcastQueues) {
16068            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16069            printedAnything |= needSep;
16070        }
16071
16072        needSep = true;
16073
16074        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16075            for (int user=0; user<mStickyBroadcasts.size(); user++) {
16076                if (needSep) {
16077                    pw.println();
16078                }
16079                needSep = true;
16080                printedAnything = true;
16081                pw.print("  Sticky broadcasts for user ");
16082                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16083                StringBuilder sb = new StringBuilder(128);
16084                for (Map.Entry<String, ArrayList<Intent>> ent
16085                        : mStickyBroadcasts.valueAt(user).entrySet()) {
16086                    pw.print("  * Sticky action "); pw.print(ent.getKey());
16087                    if (dumpAll) {
16088                        pw.println(":");
16089                        ArrayList<Intent> intents = ent.getValue();
16090                        final int N = intents.size();
16091                        for (int i=0; i<N; i++) {
16092                            sb.setLength(0);
16093                            sb.append("    Intent: ");
16094                            intents.get(i).toShortString(sb, false, true, false, false);
16095                            pw.println(sb.toString());
16096                            Bundle bundle = intents.get(i).getExtras();
16097                            if (bundle != null) {
16098                                pw.print("      ");
16099                                pw.println(bundle.toString());
16100                            }
16101                        }
16102                    } else {
16103                        pw.println("");
16104                    }
16105                }
16106            }
16107        }
16108
16109        if (!onlyHistory && dumpAll) {
16110            pw.println();
16111            for (BroadcastQueue queue : mBroadcastQueues) {
16112                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16113                        + queue.mBroadcastsScheduled);
16114            }
16115            pw.println("  mHandler:");
16116            mHandler.dump(new PrintWriterPrinter(pw), "    ");
16117            needSep = true;
16118            printedAnything = true;
16119        }
16120
16121        if (!printedAnything) {
16122            pw.println("  (nothing)");
16123        }
16124    }
16125
16126    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16127            int opti, boolean dumpAll, String dumpPackage) {
16128        if (mCurBroadcastStats == null) {
16129            return;
16130        }
16131
16132        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16133        final long now = SystemClock.elapsedRealtime();
16134        if (mLastBroadcastStats != null) {
16135            pw.print("  Last stats (from ");
16136            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16137            pw.print(" to ");
16138            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16139            pw.print(", ");
16140            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16141                    - mLastBroadcastStats.mStartUptime, pw);
16142            pw.println(" uptime):");
16143            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16144                pw.println("    (nothing)");
16145            }
16146            pw.println();
16147        }
16148        pw.print("  Current stats (from ");
16149        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16150        pw.print(" to now, ");
16151        TimeUtils.formatDuration(SystemClock.uptimeMillis()
16152                - mCurBroadcastStats.mStartUptime, pw);
16153        pw.println(" uptime):");
16154        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16155            pw.println("    (nothing)");
16156        }
16157    }
16158
16159    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16160            int opti, boolean fullCheckin, String dumpPackage) {
16161        if (mCurBroadcastStats == null) {
16162            return;
16163        }
16164
16165        if (mLastBroadcastStats != null) {
16166            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16167            if (fullCheckin) {
16168                mLastBroadcastStats = null;
16169                return;
16170            }
16171        }
16172        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16173        if (fullCheckin) {
16174            mCurBroadcastStats = null;
16175        }
16176    }
16177
16178    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16179            int opti, boolean dumpAll, String dumpPackage) {
16180        boolean needSep;
16181        boolean printedAnything = false;
16182
16183        ItemMatcher matcher = new ItemMatcher();
16184        matcher.build(args, opti);
16185
16186        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16187
16188        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16189        printedAnything |= needSep;
16190
16191        if (mLaunchingProviders.size() > 0) {
16192            boolean printed = false;
16193            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16194                ContentProviderRecord r = mLaunchingProviders.get(i);
16195                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16196                    continue;
16197                }
16198                if (!printed) {
16199                    if (needSep) pw.println();
16200                    needSep = true;
16201                    pw.println("  Launching content providers:");
16202                    printed = true;
16203                    printedAnything = true;
16204                }
16205                pw.print("  Launching #"); pw.print(i); pw.print(": ");
16206                        pw.println(r);
16207            }
16208        }
16209
16210        if (!printedAnything) {
16211            pw.println("  (nothing)");
16212        }
16213    }
16214
16215    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16216            int opti, boolean dumpAll, String dumpPackage) {
16217        boolean needSep = false;
16218        boolean printedAnything = false;
16219
16220        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16221
16222        if (mGrantedUriPermissions.size() > 0) {
16223            boolean printed = false;
16224            int dumpUid = -2;
16225            if (dumpPackage != null) {
16226                try {
16227                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16228                            MATCH_ANY_USER, 0);
16229                } catch (NameNotFoundException e) {
16230                    dumpUid = -1;
16231                }
16232            }
16233            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16234                int uid = mGrantedUriPermissions.keyAt(i);
16235                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16236                    continue;
16237                }
16238                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16239                if (!printed) {
16240                    if (needSep) pw.println();
16241                    needSep = true;
16242                    pw.println("  Granted Uri Permissions:");
16243                    printed = true;
16244                    printedAnything = true;
16245                }
16246                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16247                for (UriPermission perm : perms.values()) {
16248                    pw.print("    "); pw.println(perm);
16249                    if (dumpAll) {
16250                        perm.dump(pw, "      ");
16251                    }
16252                }
16253            }
16254        }
16255
16256        if (!printedAnything) {
16257            pw.println("  (nothing)");
16258        }
16259    }
16260
16261    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16262            int opti, boolean dumpAll, String dumpPackage) {
16263        boolean printed = false;
16264
16265        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16266
16267        if (mIntentSenderRecords.size() > 0) {
16268            // Organize these by package name, so they are easier to read.
16269            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16270            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16271            final Iterator<WeakReference<PendingIntentRecord>> it
16272                    = mIntentSenderRecords.values().iterator();
16273            while (it.hasNext()) {
16274                WeakReference<PendingIntentRecord> ref = it.next();
16275                PendingIntentRecord rec = ref != null ? ref.get() : null;
16276                if (rec == null) {
16277                    weakRefs.add(ref);
16278                    continue;
16279                }
16280                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16281                    continue;
16282                }
16283                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16284                if (list == null) {
16285                    list = new ArrayList<>();
16286                    byPackage.put(rec.key.packageName, list);
16287                }
16288                list.add(rec);
16289            }
16290            for (int i = 0; i < byPackage.size(); i++) {
16291                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16292                printed = true;
16293                pw.print("  * "); pw.print(byPackage.keyAt(i));
16294                pw.print(": "); pw.print(intents.size()); pw.println(" items");
16295                for (int j = 0; j < intents.size(); j++) {
16296                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16297                    if (dumpAll) {
16298                        intents.get(j).dump(pw, "      ");
16299                    }
16300                }
16301            }
16302            if (weakRefs.size() > 0) {
16303                printed = true;
16304                pw.println("  * WEAK REFS:");
16305                for (int i = 0; i < weakRefs.size(); i++) {
16306                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16307                }
16308            }
16309        }
16310
16311        if (!printed) {
16312            pw.println("  (nothing)");
16313        }
16314    }
16315
16316    private static final int dumpProcessList(PrintWriter pw,
16317            ActivityManagerService service, List list,
16318            String prefix, String normalLabel, String persistentLabel,
16319            String dumpPackage) {
16320        int numPers = 0;
16321        final int N = list.size()-1;
16322        for (int i=N; i>=0; i--) {
16323            ProcessRecord r = (ProcessRecord)list.get(i);
16324            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16325                continue;
16326            }
16327            pw.println(String.format("%s%s #%2d: %s",
16328                    prefix, (r.persistent ? persistentLabel : normalLabel),
16329                    i, r.toString()));
16330            if (r.persistent) {
16331                numPers++;
16332            }
16333        }
16334        return numPers;
16335    }
16336
16337    private static final boolean dumpProcessOomList(PrintWriter pw,
16338            ActivityManagerService service, List<ProcessRecord> origList,
16339            String prefix, String normalLabel, String persistentLabel,
16340            boolean inclDetails, String dumpPackage) {
16341
16342        ArrayList<Pair<ProcessRecord, Integer>> list
16343                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16344        for (int i=0; i<origList.size(); i++) {
16345            ProcessRecord r = origList.get(i);
16346            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16347                continue;
16348            }
16349            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16350        }
16351
16352        if (list.size() <= 0) {
16353            return false;
16354        }
16355
16356        Comparator<Pair<ProcessRecord, Integer>> comparator
16357                = new Comparator<Pair<ProcessRecord, Integer>>() {
16358            @Override
16359            public int compare(Pair<ProcessRecord, Integer> object1,
16360                    Pair<ProcessRecord, Integer> object2) {
16361                if (object1.first.setAdj != object2.first.setAdj) {
16362                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16363                }
16364                if (object1.first.setProcState != object2.first.setProcState) {
16365                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16366                }
16367                if (object1.second.intValue() != object2.second.intValue()) {
16368                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16369                }
16370                return 0;
16371            }
16372        };
16373
16374        Collections.sort(list, comparator);
16375
16376        final long curRealtime = SystemClock.elapsedRealtime();
16377        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16378        final long curUptime = SystemClock.uptimeMillis();
16379        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16380
16381        for (int i=list.size()-1; i>=0; i--) {
16382            ProcessRecord r = list.get(i).first;
16383            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16384            char schedGroup;
16385            switch (r.setSchedGroup) {
16386                case ProcessList.SCHED_GROUP_BACKGROUND:
16387                    schedGroup = 'B';
16388                    break;
16389                case ProcessList.SCHED_GROUP_DEFAULT:
16390                    schedGroup = 'F';
16391                    break;
16392                case ProcessList.SCHED_GROUP_TOP_APP:
16393                    schedGroup = 'T';
16394                    break;
16395                default:
16396                    schedGroup = '?';
16397                    break;
16398            }
16399            char foreground;
16400            if (r.foregroundActivities) {
16401                foreground = 'A';
16402            } else if (r.foregroundServices) {
16403                foreground = 'S';
16404            } else {
16405                foreground = ' ';
16406            }
16407            String procState = ProcessList.makeProcStateString(r.curProcState);
16408            pw.print(prefix);
16409            pw.print(r.persistent ? persistentLabel : normalLabel);
16410            pw.print(" #");
16411            int num = (origList.size()-1)-list.get(i).second;
16412            if (num < 10) pw.print(' ');
16413            pw.print(num);
16414            pw.print(": ");
16415            pw.print(oomAdj);
16416            pw.print(' ');
16417            pw.print(schedGroup);
16418            pw.print('/');
16419            pw.print(foreground);
16420            pw.print('/');
16421            pw.print(procState);
16422            pw.print(" trm:");
16423            if (r.trimMemoryLevel < 10) pw.print(' ');
16424            pw.print(r.trimMemoryLevel);
16425            pw.print(' ');
16426            pw.print(r.toShortString());
16427            pw.print(" (");
16428            pw.print(r.adjType);
16429            pw.println(')');
16430            if (r.adjSource != null || r.adjTarget != null) {
16431                pw.print(prefix);
16432                pw.print("    ");
16433                if (r.adjTarget instanceof ComponentName) {
16434                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16435                } else if (r.adjTarget != null) {
16436                    pw.print(r.adjTarget.toString());
16437                } else {
16438                    pw.print("{null}");
16439                }
16440                pw.print("<=");
16441                if (r.adjSource instanceof ProcessRecord) {
16442                    pw.print("Proc{");
16443                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16444                    pw.println("}");
16445                } else if (r.adjSource != null) {
16446                    pw.println(r.adjSource.toString());
16447                } else {
16448                    pw.println("{null}");
16449                }
16450            }
16451            if (inclDetails) {
16452                pw.print(prefix);
16453                pw.print("    ");
16454                pw.print("oom: max="); pw.print(r.maxAdj);
16455                pw.print(" curRaw="); pw.print(r.curRawAdj);
16456                pw.print(" setRaw="); pw.print(r.setRawAdj);
16457                pw.print(" cur="); pw.print(r.curAdj);
16458                pw.print(" set="); pw.println(r.setAdj);
16459                pw.print(prefix);
16460                pw.print("    ");
16461                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16462                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16463                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16464                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16465                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16466                pw.println();
16467                pw.print(prefix);
16468                pw.print("    ");
16469                pw.print("cached="); pw.print(r.cached);
16470                pw.print(" empty="); pw.print(r.empty);
16471                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16472
16473                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16474                    if (r.lastWakeTime != 0) {
16475                        long wtime;
16476                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16477                        synchronized (stats) {
16478                            wtime = stats.getProcessWakeTime(r.info.uid,
16479                                    r.pid, curRealtime);
16480                        }
16481                        long timeUsed = wtime - r.lastWakeTime;
16482                        pw.print(prefix);
16483                        pw.print("    ");
16484                        pw.print("keep awake over ");
16485                        TimeUtils.formatDuration(realtimeSince, pw);
16486                        pw.print(" used ");
16487                        TimeUtils.formatDuration(timeUsed, pw);
16488                        pw.print(" (");
16489                        pw.print((timeUsed*100)/realtimeSince);
16490                        pw.println("%)");
16491                    }
16492                    if (r.lastCpuTime != 0) {
16493                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16494                        pw.print(prefix);
16495                        pw.print("    ");
16496                        pw.print("run cpu over ");
16497                        TimeUtils.formatDuration(uptimeSince, pw);
16498                        pw.print(" used ");
16499                        TimeUtils.formatDuration(timeUsed, pw);
16500                        pw.print(" (");
16501                        pw.print((timeUsed*100)/uptimeSince);
16502                        pw.println("%)");
16503                    }
16504                }
16505            }
16506        }
16507        return true;
16508    }
16509
16510    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16511            String[] args) {
16512        ArrayList<ProcessRecord> procs;
16513        synchronized (this) {
16514            if (args != null && args.length > start
16515                    && args[start].charAt(0) != '-') {
16516                procs = new ArrayList<ProcessRecord>();
16517                int pid = -1;
16518                try {
16519                    pid = Integer.parseInt(args[start]);
16520                } catch (NumberFormatException e) {
16521                }
16522                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16523                    ProcessRecord proc = mLruProcesses.get(i);
16524                    if (proc.pid == pid) {
16525                        procs.add(proc);
16526                    } else if (allPkgs && proc.pkgList != null
16527                            && proc.pkgList.containsKey(args[start])) {
16528                        procs.add(proc);
16529                    } else if (proc.processName.equals(args[start])) {
16530                        procs.add(proc);
16531                    }
16532                }
16533                if (procs.size() <= 0) {
16534                    return null;
16535                }
16536            } else {
16537                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16538            }
16539        }
16540        return procs;
16541    }
16542
16543    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16544            PrintWriter pw, String[] args) {
16545        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16546        if (procs == null) {
16547            pw.println("No process found for: " + args[0]);
16548            return;
16549        }
16550
16551        long uptime = SystemClock.uptimeMillis();
16552        long realtime = SystemClock.elapsedRealtime();
16553        pw.println("Applications Graphics Acceleration Info:");
16554        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16555
16556        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16557            ProcessRecord r = procs.get(i);
16558            if (r.thread != null) {
16559                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16560                pw.flush();
16561                try {
16562                    TransferPipe tp = new TransferPipe();
16563                    try {
16564                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16565                        tp.go(fd);
16566                    } finally {
16567                        tp.kill();
16568                    }
16569                } catch (IOException e) {
16570                    pw.println("Failure while dumping the app: " + r);
16571                    pw.flush();
16572                } catch (RemoteException e) {
16573                    pw.println("Got a RemoteException while dumping the app " + r);
16574                    pw.flush();
16575                }
16576            }
16577        }
16578    }
16579
16580    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16581        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16582        if (procs == null) {
16583            pw.println("No process found for: " + args[0]);
16584            return;
16585        }
16586
16587        pw.println("Applications Database Info:");
16588
16589        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16590            ProcessRecord r = procs.get(i);
16591            if (r.thread != null) {
16592                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16593                pw.flush();
16594                try {
16595                    TransferPipe tp = new TransferPipe();
16596                    try {
16597                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16598                        tp.go(fd);
16599                    } finally {
16600                        tp.kill();
16601                    }
16602                } catch (IOException e) {
16603                    pw.println("Failure while dumping the app: " + r);
16604                    pw.flush();
16605                } catch (RemoteException e) {
16606                    pw.println("Got a RemoteException while dumping the app " + r);
16607                    pw.flush();
16608                }
16609            }
16610        }
16611    }
16612
16613    final static class MemItem {
16614        final boolean isProc;
16615        final String label;
16616        final String shortLabel;
16617        final long pss;
16618        final long swapPss;
16619        final int id;
16620        final boolean hasActivities;
16621        ArrayList<MemItem> subitems;
16622
16623        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16624                boolean _hasActivities) {
16625            isProc = true;
16626            label = _label;
16627            shortLabel = _shortLabel;
16628            pss = _pss;
16629            swapPss = _swapPss;
16630            id = _id;
16631            hasActivities = _hasActivities;
16632        }
16633
16634        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16635            isProc = false;
16636            label = _label;
16637            shortLabel = _shortLabel;
16638            pss = _pss;
16639            swapPss = _swapPss;
16640            id = _id;
16641            hasActivities = false;
16642        }
16643    }
16644
16645    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16646            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16647        if (sort && !isCompact) {
16648            Collections.sort(items, new Comparator<MemItem>() {
16649                @Override
16650                public int compare(MemItem lhs, MemItem rhs) {
16651                    if (lhs.pss < rhs.pss) {
16652                        return 1;
16653                    } else if (lhs.pss > rhs.pss) {
16654                        return -1;
16655                    }
16656                    return 0;
16657                }
16658            });
16659        }
16660
16661        for (int i=0; i<items.size(); i++) {
16662            MemItem mi = items.get(i);
16663            if (!isCompact) {
16664                if (dumpSwapPss) {
16665                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16666                            mi.label, stringifyKBSize(mi.swapPss));
16667                } else {
16668                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16669                }
16670            } else if (mi.isProc) {
16671                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16672                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16673                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16674                pw.println(mi.hasActivities ? ",a" : ",e");
16675            } else {
16676                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16677                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16678            }
16679            if (mi.subitems != null) {
16680                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16681                        true, isCompact, dumpSwapPss);
16682            }
16683        }
16684    }
16685
16686    // These are in KB.
16687    static final long[] DUMP_MEM_BUCKETS = new long[] {
16688        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16689        120*1024, 160*1024, 200*1024,
16690        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16691        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16692    };
16693
16694    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16695            boolean stackLike) {
16696        int start = label.lastIndexOf('.');
16697        if (start >= 0) start++;
16698        else start = 0;
16699        int end = label.length();
16700        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16701            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16702                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16703                out.append(bucket);
16704                out.append(stackLike ? "MB." : "MB ");
16705                out.append(label, start, end);
16706                return;
16707            }
16708        }
16709        out.append(memKB/1024);
16710        out.append(stackLike ? "MB." : "MB ");
16711        out.append(label, start, end);
16712    }
16713
16714    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16715            ProcessList.NATIVE_ADJ,
16716            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16717            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16718            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16719            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16720            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16721            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16722    };
16723    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16724            "Native",
16725            "System", "Persistent", "Persistent Service", "Foreground",
16726            "Visible", "Perceptible",
16727            "Heavy Weight", "Backup",
16728            "A Services", "Home",
16729            "Previous", "B Services", "Cached"
16730    };
16731    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16732            "native",
16733            "sys", "pers", "persvc", "fore",
16734            "vis", "percept",
16735            "heavy", "backup",
16736            "servicea", "home",
16737            "prev", "serviceb", "cached"
16738    };
16739
16740    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16741            long realtime, boolean isCheckinRequest, boolean isCompact) {
16742        if (isCompact) {
16743            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16744        }
16745        if (isCheckinRequest || isCompact) {
16746            // short checkin version
16747            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16748        } else {
16749            pw.println("Applications Memory Usage (in Kilobytes):");
16750            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16751        }
16752    }
16753
16754    private static final int KSM_SHARED = 0;
16755    private static final int KSM_SHARING = 1;
16756    private static final int KSM_UNSHARED = 2;
16757    private static final int KSM_VOLATILE = 3;
16758
16759    private final long[] getKsmInfo() {
16760        long[] longOut = new long[4];
16761        final int[] SINGLE_LONG_FORMAT = new int[] {
16762            PROC_SPACE_TERM| PROC_OUT_LONG
16763        };
16764        long[] longTmp = new long[1];
16765        readProcFile("/sys/kernel/mm/ksm/pages_shared",
16766                SINGLE_LONG_FORMAT, null, longTmp, null);
16767        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16768        longTmp[0] = 0;
16769        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16770                SINGLE_LONG_FORMAT, null, longTmp, null);
16771        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16772        longTmp[0] = 0;
16773        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16774                SINGLE_LONG_FORMAT, null, longTmp, null);
16775        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16776        longTmp[0] = 0;
16777        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16778                SINGLE_LONG_FORMAT, null, longTmp, null);
16779        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16780        return longOut;
16781    }
16782
16783    private static String stringifySize(long size, int order) {
16784        Locale locale = Locale.US;
16785        switch (order) {
16786            case 1:
16787                return String.format(locale, "%,13d", size);
16788            case 1024:
16789                return String.format(locale, "%,9dK", size / 1024);
16790            case 1024 * 1024:
16791                return String.format(locale, "%,5dM", size / 1024 / 1024);
16792            case 1024 * 1024 * 1024:
16793                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16794            default:
16795                throw new IllegalArgumentException("Invalid size order");
16796        }
16797    }
16798
16799    private static String stringifyKBSize(long size) {
16800        return stringifySize(size * 1024, 1024);
16801    }
16802
16803    // Update this version number in case you change the 'compact' format
16804    private static final int MEMINFO_COMPACT_VERSION = 1;
16805
16806    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16807            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16808        boolean dumpDetails = false;
16809        boolean dumpFullDetails = false;
16810        boolean dumpDalvik = false;
16811        boolean dumpSummaryOnly = false;
16812        boolean dumpUnreachable = false;
16813        boolean oomOnly = false;
16814        boolean isCompact = false;
16815        boolean localOnly = false;
16816        boolean packages = false;
16817        boolean isCheckinRequest = false;
16818        boolean dumpSwapPss = false;
16819
16820        int opti = 0;
16821        while (opti < args.length) {
16822            String opt = args[opti];
16823            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16824                break;
16825            }
16826            opti++;
16827            if ("-a".equals(opt)) {
16828                dumpDetails = true;
16829                dumpFullDetails = true;
16830                dumpDalvik = true;
16831                dumpSwapPss = true;
16832            } else if ("-d".equals(opt)) {
16833                dumpDalvik = true;
16834            } else if ("-c".equals(opt)) {
16835                isCompact = true;
16836            } else if ("-s".equals(opt)) {
16837                dumpDetails = true;
16838                dumpSummaryOnly = true;
16839            } else if ("-S".equals(opt)) {
16840                dumpSwapPss = true;
16841            } else if ("--unreachable".equals(opt)) {
16842                dumpUnreachable = true;
16843            } else if ("--oom".equals(opt)) {
16844                oomOnly = true;
16845            } else if ("--local".equals(opt)) {
16846                localOnly = true;
16847            } else if ("--package".equals(opt)) {
16848                packages = true;
16849            } else if ("--checkin".equals(opt)) {
16850                isCheckinRequest = true;
16851
16852            } else if ("-h".equals(opt)) {
16853                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16854                pw.println("  -a: include all available information for each process.");
16855                pw.println("  -d: include dalvik details.");
16856                pw.println("  -c: dump in a compact machine-parseable representation.");
16857                pw.println("  -s: dump only summary of application memory usage.");
16858                pw.println("  -S: dump also SwapPss.");
16859                pw.println("  --oom: only show processes organized by oom adj.");
16860                pw.println("  --local: only collect details locally, don't call process.");
16861                pw.println("  --package: interpret process arg as package, dumping all");
16862                pw.println("             processes that have loaded that package.");
16863                pw.println("  --checkin: dump data for a checkin");
16864                pw.println("If [process] is specified it can be the name or ");
16865                pw.println("pid of a specific process to dump.");
16866                return;
16867            } else {
16868                pw.println("Unknown argument: " + opt + "; use -h for help");
16869            }
16870        }
16871
16872        long uptime = SystemClock.uptimeMillis();
16873        long realtime = SystemClock.elapsedRealtime();
16874        final long[] tmpLong = new long[1];
16875
16876        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16877        if (procs == null) {
16878            // No Java processes.  Maybe they want to print a native process.
16879            if (args != null && args.length > opti
16880                    && args[opti].charAt(0) != '-') {
16881                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16882                        = new ArrayList<ProcessCpuTracker.Stats>();
16883                updateCpuStatsNow();
16884                int findPid = -1;
16885                try {
16886                    findPid = Integer.parseInt(args[opti]);
16887                } catch (NumberFormatException e) {
16888                }
16889                synchronized (mProcessCpuTracker) {
16890                    final int N = mProcessCpuTracker.countStats();
16891                    for (int i=0; i<N; i++) {
16892                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16893                        if (st.pid == findPid || (st.baseName != null
16894                                && st.baseName.equals(args[opti]))) {
16895                            nativeProcs.add(st);
16896                        }
16897                    }
16898                }
16899                if (nativeProcs.size() > 0) {
16900                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16901                            isCompact);
16902                    Debug.MemoryInfo mi = null;
16903                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16904                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16905                        final int pid = r.pid;
16906                        if (!isCheckinRequest && dumpDetails) {
16907                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16908                        }
16909                        if (mi == null) {
16910                            mi = new Debug.MemoryInfo();
16911                        }
16912                        if (dumpDetails || (!brief && !oomOnly)) {
16913                            Debug.getMemoryInfo(pid, mi);
16914                        } else {
16915                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16916                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16917                        }
16918                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16919                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16920                        if (isCheckinRequest) {
16921                            pw.println();
16922                        }
16923                    }
16924                    return;
16925                }
16926            }
16927            pw.println("No process found for: " + args[opti]);
16928            return;
16929        }
16930
16931        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16932            dumpDetails = true;
16933        }
16934
16935        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16936
16937        String[] innerArgs = new String[args.length-opti];
16938        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16939
16940        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16941        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16942        long nativePss = 0;
16943        long nativeSwapPss = 0;
16944        long dalvikPss = 0;
16945        long dalvikSwapPss = 0;
16946        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16947                EmptyArray.LONG;
16948        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16949                EmptyArray.LONG;
16950        long otherPss = 0;
16951        long otherSwapPss = 0;
16952        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16953        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16954
16955        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16956        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16957        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16958                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16959
16960        long totalPss = 0;
16961        long totalSwapPss = 0;
16962        long cachedPss = 0;
16963        long cachedSwapPss = 0;
16964        boolean hasSwapPss = false;
16965
16966        Debug.MemoryInfo mi = null;
16967        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16968            final ProcessRecord r = procs.get(i);
16969            final IApplicationThread thread;
16970            final int pid;
16971            final int oomAdj;
16972            final boolean hasActivities;
16973            synchronized (this) {
16974                thread = r.thread;
16975                pid = r.pid;
16976                oomAdj = r.getSetAdjWithServices();
16977                hasActivities = r.activities.size() > 0;
16978            }
16979            if (thread != null) {
16980                if (!isCheckinRequest && dumpDetails) {
16981                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16982                }
16983                if (mi == null) {
16984                    mi = new Debug.MemoryInfo();
16985                }
16986                if (dumpDetails || (!brief && !oomOnly)) {
16987                    Debug.getMemoryInfo(pid, mi);
16988                    hasSwapPss = mi.hasSwappedOutPss;
16989                } else {
16990                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16991                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16992                }
16993                if (dumpDetails) {
16994                    if (localOnly) {
16995                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16996                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16997                        if (isCheckinRequest) {
16998                            pw.println();
16999                        }
17000                    } else {
17001                        pw.flush();
17002                        try {
17003                            TransferPipe tp = new TransferPipe();
17004                            try {
17005                                thread.dumpMemInfo(tp.getWriteFd(),
17006                                        mi, isCheckinRequest, dumpFullDetails,
17007                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17008                                tp.go(fd);
17009                            } finally {
17010                                tp.kill();
17011                            }
17012                        } catch (IOException e) {
17013                            if (!isCheckinRequest) {
17014                                pw.println("Got IoException!");
17015                                pw.flush();
17016                            }
17017                        } catch (RemoteException e) {
17018                            if (!isCheckinRequest) {
17019                                pw.println("Got RemoteException!");
17020                                pw.flush();
17021                            }
17022                        }
17023                    }
17024                }
17025
17026                final long myTotalPss = mi.getTotalPss();
17027                final long myTotalUss = mi.getTotalUss();
17028                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17029
17030                synchronized (this) {
17031                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17032                        // Record this for posterity if the process has been stable.
17033                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17034                    }
17035                }
17036
17037                if (!isCheckinRequest && mi != null) {
17038                    totalPss += myTotalPss;
17039                    totalSwapPss += myTotalSwapPss;
17040                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17041                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17042                            myTotalSwapPss, pid, hasActivities);
17043                    procMems.add(pssItem);
17044                    procMemsMap.put(pid, pssItem);
17045
17046                    nativePss += mi.nativePss;
17047                    nativeSwapPss += mi.nativeSwappedOutPss;
17048                    dalvikPss += mi.dalvikPss;
17049                    dalvikSwapPss += mi.dalvikSwappedOutPss;
17050                    for (int j=0; j<dalvikSubitemPss.length; j++) {
17051                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17052                        dalvikSubitemSwapPss[j] +=
17053                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17054                    }
17055                    otherPss += mi.otherPss;
17056                    otherSwapPss += mi.otherSwappedOutPss;
17057                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17058                        long mem = mi.getOtherPss(j);
17059                        miscPss[j] += mem;
17060                        otherPss -= mem;
17061                        mem = mi.getOtherSwappedOutPss(j);
17062                        miscSwapPss[j] += mem;
17063                        otherSwapPss -= mem;
17064                    }
17065
17066                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17067                        cachedPss += myTotalPss;
17068                        cachedSwapPss += myTotalSwapPss;
17069                    }
17070
17071                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17072                        if (oomIndex == (oomPss.length - 1)
17073                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17074                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17075                            oomPss[oomIndex] += myTotalPss;
17076                            oomSwapPss[oomIndex] += myTotalSwapPss;
17077                            if (oomProcs[oomIndex] == null) {
17078                                oomProcs[oomIndex] = new ArrayList<MemItem>();
17079                            }
17080                            oomProcs[oomIndex].add(pssItem);
17081                            break;
17082                        }
17083                    }
17084                }
17085            }
17086        }
17087
17088        long nativeProcTotalPss = 0;
17089
17090        if (!isCheckinRequest && procs.size() > 1 && !packages) {
17091            // If we are showing aggregations, also look for native processes to
17092            // include so that our aggregations are more accurate.
17093            updateCpuStatsNow();
17094            mi = null;
17095            synchronized (mProcessCpuTracker) {
17096                final int N = mProcessCpuTracker.countStats();
17097                for (int i=0; i<N; i++) {
17098                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17099                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17100                        if (mi == null) {
17101                            mi = new Debug.MemoryInfo();
17102                        }
17103                        if (!brief && !oomOnly) {
17104                            Debug.getMemoryInfo(st.pid, mi);
17105                        } else {
17106                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17107                            mi.nativePrivateDirty = (int)tmpLong[0];
17108                        }
17109
17110                        final long myTotalPss = mi.getTotalPss();
17111                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17112                        totalPss += myTotalPss;
17113                        nativeProcTotalPss += myTotalPss;
17114
17115                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17116                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17117                        procMems.add(pssItem);
17118
17119                        nativePss += mi.nativePss;
17120                        nativeSwapPss += mi.nativeSwappedOutPss;
17121                        dalvikPss += mi.dalvikPss;
17122                        dalvikSwapPss += mi.dalvikSwappedOutPss;
17123                        for (int j=0; j<dalvikSubitemPss.length; j++) {
17124                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17125                            dalvikSubitemSwapPss[j] +=
17126                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17127                        }
17128                        otherPss += mi.otherPss;
17129                        otherSwapPss += mi.otherSwappedOutPss;
17130                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17131                            long mem = mi.getOtherPss(j);
17132                            miscPss[j] += mem;
17133                            otherPss -= mem;
17134                            mem = mi.getOtherSwappedOutPss(j);
17135                            miscSwapPss[j] += mem;
17136                            otherSwapPss -= mem;
17137                        }
17138                        oomPss[0] += myTotalPss;
17139                        oomSwapPss[0] += myTotalSwapPss;
17140                        if (oomProcs[0] == null) {
17141                            oomProcs[0] = new ArrayList<MemItem>();
17142                        }
17143                        oomProcs[0].add(pssItem);
17144                    }
17145                }
17146            }
17147
17148            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17149
17150            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17151            final MemItem dalvikItem =
17152                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17153            if (dalvikSubitemPss.length > 0) {
17154                dalvikItem.subitems = new ArrayList<MemItem>();
17155                for (int j=0; j<dalvikSubitemPss.length; j++) {
17156                    final String name = Debug.MemoryInfo.getOtherLabel(
17157                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
17158                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17159                                    dalvikSubitemSwapPss[j], j));
17160                }
17161            }
17162            catMems.add(dalvikItem);
17163            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17164            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17165                String label = Debug.MemoryInfo.getOtherLabel(j);
17166                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17167            }
17168
17169            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17170            for (int j=0; j<oomPss.length; j++) {
17171                if (oomPss[j] != 0) {
17172                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17173                            : DUMP_MEM_OOM_LABEL[j];
17174                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17175                            DUMP_MEM_OOM_ADJ[j]);
17176                    item.subitems = oomProcs[j];
17177                    oomMems.add(item);
17178                }
17179            }
17180
17181            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17182            if (!brief && !oomOnly && !isCompact) {
17183                pw.println();
17184                pw.println("Total PSS by process:");
17185                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17186                pw.println();
17187            }
17188            if (!isCompact) {
17189                pw.println("Total PSS by OOM adjustment:");
17190            }
17191            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17192            if (!brief && !oomOnly) {
17193                PrintWriter out = categoryPw != null ? categoryPw : pw;
17194                if (!isCompact) {
17195                    out.println();
17196                    out.println("Total PSS by category:");
17197                }
17198                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17199            }
17200            if (!isCompact) {
17201                pw.println();
17202            }
17203            MemInfoReader memInfo = new MemInfoReader();
17204            memInfo.readMemInfo();
17205            if (nativeProcTotalPss > 0) {
17206                synchronized (this) {
17207                    final long cachedKb = memInfo.getCachedSizeKb();
17208                    final long freeKb = memInfo.getFreeSizeKb();
17209                    final long zramKb = memInfo.getZramTotalSizeKb();
17210                    final long kernelKb = memInfo.getKernelUsedSizeKb();
17211                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17212                            kernelKb*1024, nativeProcTotalPss*1024);
17213                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17214                            nativeProcTotalPss);
17215                }
17216            }
17217            if (!brief) {
17218                if (!isCompact) {
17219                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17220                    pw.print(" (status ");
17221                    switch (mLastMemoryLevel) {
17222                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17223                            pw.println("normal)");
17224                            break;
17225                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17226                            pw.println("moderate)");
17227                            break;
17228                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
17229                            pw.println("low)");
17230                            break;
17231                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17232                            pw.println("critical)");
17233                            break;
17234                        default:
17235                            pw.print(mLastMemoryLevel);
17236                            pw.println(")");
17237                            break;
17238                    }
17239                    pw.print(" Free RAM: ");
17240                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17241                            + memInfo.getFreeSizeKb()));
17242                    pw.print(" (");
17243                    pw.print(stringifyKBSize(cachedPss));
17244                    pw.print(" cached pss + ");
17245                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17246                    pw.print(" cached kernel + ");
17247                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17248                    pw.println(" free)");
17249                } else {
17250                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17251                    pw.print(cachedPss + memInfo.getCachedSizeKb()
17252                            + memInfo.getFreeSizeKb()); pw.print(",");
17253                    pw.println(totalPss - cachedPss);
17254                }
17255            }
17256            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17257                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17258                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17259            if (!isCompact) {
17260                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17261                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17262                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17263                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17264                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17265            } else {
17266                pw.print("lostram,"); pw.println(lostRAM);
17267            }
17268            if (!brief) {
17269                if (memInfo.getZramTotalSizeKb() != 0) {
17270                    if (!isCompact) {
17271                        pw.print("     ZRAM: ");
17272                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17273                                pw.print(" physical used for ");
17274                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17275                                        - memInfo.getSwapFreeSizeKb()));
17276                                pw.print(" in swap (");
17277                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17278                                pw.println(" total swap)");
17279                    } else {
17280                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17281                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17282                                pw.println(memInfo.getSwapFreeSizeKb());
17283                    }
17284                }
17285                final long[] ksm = getKsmInfo();
17286                if (!isCompact) {
17287                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17288                            || ksm[KSM_VOLATILE] != 0) {
17289                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17290                                pw.print(" saved from shared ");
17291                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17292                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17293                                pw.print(" unshared; ");
17294                                pw.print(stringifyKBSize(
17295                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
17296                    }
17297                    pw.print("   Tuning: ");
17298                    pw.print(ActivityManager.staticGetMemoryClass());
17299                    pw.print(" (large ");
17300                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17301                    pw.print("), oom ");
17302                    pw.print(stringifySize(
17303                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17304                    pw.print(", restore limit ");
17305                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17306                    if (ActivityManager.isLowRamDeviceStatic()) {
17307                        pw.print(" (low-ram)");
17308                    }
17309                    if (ActivityManager.isHighEndGfx()) {
17310                        pw.print(" (high-end-gfx)");
17311                    }
17312                    pw.println();
17313                } else {
17314                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17315                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17316                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17317                    pw.print("tuning,");
17318                    pw.print(ActivityManager.staticGetMemoryClass());
17319                    pw.print(',');
17320                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17321                    pw.print(',');
17322                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17323                    if (ActivityManager.isLowRamDeviceStatic()) {
17324                        pw.print(",low-ram");
17325                    }
17326                    if (ActivityManager.isHighEndGfx()) {
17327                        pw.print(",high-end-gfx");
17328                    }
17329                    pw.println();
17330                }
17331            }
17332        }
17333    }
17334
17335    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17336            long memtrack, String name) {
17337        sb.append("  ");
17338        sb.append(ProcessList.makeOomAdjString(oomAdj));
17339        sb.append(' ');
17340        sb.append(ProcessList.makeProcStateString(procState));
17341        sb.append(' ');
17342        ProcessList.appendRamKb(sb, pss);
17343        sb.append(": ");
17344        sb.append(name);
17345        if (memtrack > 0) {
17346            sb.append(" (");
17347            sb.append(stringifyKBSize(memtrack));
17348            sb.append(" memtrack)");
17349        }
17350    }
17351
17352    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17353        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17354        sb.append(" (pid ");
17355        sb.append(mi.pid);
17356        sb.append(") ");
17357        sb.append(mi.adjType);
17358        sb.append('\n');
17359        if (mi.adjReason != null) {
17360            sb.append("                      ");
17361            sb.append(mi.adjReason);
17362            sb.append('\n');
17363        }
17364    }
17365
17366    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17367        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17368        for (int i=0, N=memInfos.size(); i<N; i++) {
17369            ProcessMemInfo mi = memInfos.get(i);
17370            infoMap.put(mi.pid, mi);
17371        }
17372        updateCpuStatsNow();
17373        long[] memtrackTmp = new long[1];
17374        final List<ProcessCpuTracker.Stats> stats;
17375        // Get a list of Stats that have vsize > 0
17376        synchronized (mProcessCpuTracker) {
17377            stats = mProcessCpuTracker.getStats((st) -> {
17378                return st.vsize > 0;
17379            });
17380        }
17381        final int statsCount = stats.size();
17382        for (int i = 0; i < statsCount; i++) {
17383            ProcessCpuTracker.Stats st = stats.get(i);
17384            long pss = Debug.getPss(st.pid, null, memtrackTmp);
17385            if (pss > 0) {
17386                if (infoMap.indexOfKey(st.pid) < 0) {
17387                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17388                            ProcessList.NATIVE_ADJ, -1, "native", null);
17389                    mi.pss = pss;
17390                    mi.memtrack = memtrackTmp[0];
17391                    memInfos.add(mi);
17392                }
17393            }
17394        }
17395
17396        long totalPss = 0;
17397        long totalMemtrack = 0;
17398        for (int i=0, N=memInfos.size(); i<N; i++) {
17399            ProcessMemInfo mi = memInfos.get(i);
17400            if (mi.pss == 0) {
17401                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17402                mi.memtrack = memtrackTmp[0];
17403            }
17404            totalPss += mi.pss;
17405            totalMemtrack += mi.memtrack;
17406        }
17407        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17408            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17409                if (lhs.oomAdj != rhs.oomAdj) {
17410                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17411                }
17412                if (lhs.pss != rhs.pss) {
17413                    return lhs.pss < rhs.pss ? 1 : -1;
17414                }
17415                return 0;
17416            }
17417        });
17418
17419        StringBuilder tag = new StringBuilder(128);
17420        StringBuilder stack = new StringBuilder(128);
17421        tag.append("Low on memory -- ");
17422        appendMemBucket(tag, totalPss, "total", false);
17423        appendMemBucket(stack, totalPss, "total", true);
17424
17425        StringBuilder fullNativeBuilder = new StringBuilder(1024);
17426        StringBuilder shortNativeBuilder = new StringBuilder(1024);
17427        StringBuilder fullJavaBuilder = new StringBuilder(1024);
17428
17429        boolean firstLine = true;
17430        int lastOomAdj = Integer.MIN_VALUE;
17431        long extraNativeRam = 0;
17432        long extraNativeMemtrack = 0;
17433        long cachedPss = 0;
17434        for (int i=0, N=memInfos.size(); i<N; i++) {
17435            ProcessMemInfo mi = memInfos.get(i);
17436
17437            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17438                cachedPss += mi.pss;
17439            }
17440
17441            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17442                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17443                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17444                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17445                if (lastOomAdj != mi.oomAdj) {
17446                    lastOomAdj = mi.oomAdj;
17447                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17448                        tag.append(" / ");
17449                    }
17450                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17451                        if (firstLine) {
17452                            stack.append(":");
17453                            firstLine = false;
17454                        }
17455                        stack.append("\n\t at ");
17456                    } else {
17457                        stack.append("$");
17458                    }
17459                } else {
17460                    tag.append(" ");
17461                    stack.append("$");
17462                }
17463                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17464                    appendMemBucket(tag, mi.pss, mi.name, false);
17465                }
17466                appendMemBucket(stack, mi.pss, mi.name, true);
17467                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17468                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17469                    stack.append("(");
17470                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17471                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17472                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17473                            stack.append(":");
17474                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17475                        }
17476                    }
17477                    stack.append(")");
17478                }
17479            }
17480
17481            appendMemInfo(fullNativeBuilder, mi);
17482            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17483                // The short form only has native processes that are >= 512K.
17484                if (mi.pss >= 512) {
17485                    appendMemInfo(shortNativeBuilder, mi);
17486                } else {
17487                    extraNativeRam += mi.pss;
17488                    extraNativeMemtrack += mi.memtrack;
17489                }
17490            } else {
17491                // Short form has all other details, but if we have collected RAM
17492                // from smaller native processes let's dump a summary of that.
17493                if (extraNativeRam > 0) {
17494                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17495                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17496                    shortNativeBuilder.append('\n');
17497                    extraNativeRam = 0;
17498                }
17499                appendMemInfo(fullJavaBuilder, mi);
17500            }
17501        }
17502
17503        fullJavaBuilder.append("           ");
17504        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17505        fullJavaBuilder.append(": TOTAL");
17506        if (totalMemtrack > 0) {
17507            fullJavaBuilder.append(" (");
17508            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17509            fullJavaBuilder.append(" memtrack)");
17510        } else {
17511        }
17512        fullJavaBuilder.append("\n");
17513
17514        MemInfoReader memInfo = new MemInfoReader();
17515        memInfo.readMemInfo();
17516        final long[] infos = memInfo.getRawInfo();
17517
17518        StringBuilder memInfoBuilder = new StringBuilder(1024);
17519        Debug.getMemInfo(infos);
17520        memInfoBuilder.append("  MemInfo: ");
17521        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17522        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17523        memInfoBuilder.append(stringifyKBSize(
17524                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17525        memInfoBuilder.append(stringifyKBSize(
17526                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17527        memInfoBuilder.append(stringifyKBSize(
17528                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17529        memInfoBuilder.append("           ");
17530        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17531        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17532        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17533        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17534        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17535            memInfoBuilder.append("  ZRAM: ");
17536            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17537            memInfoBuilder.append(" RAM, ");
17538            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17539            memInfoBuilder.append(" swap total, ");
17540            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17541            memInfoBuilder.append(" swap free\n");
17542        }
17543        final long[] ksm = getKsmInfo();
17544        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17545                || ksm[KSM_VOLATILE] != 0) {
17546            memInfoBuilder.append("  KSM: ");
17547            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17548            memInfoBuilder.append(" saved from shared ");
17549            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17550            memInfoBuilder.append("\n       ");
17551            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17552            memInfoBuilder.append(" unshared; ");
17553            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17554            memInfoBuilder.append(" volatile\n");
17555        }
17556        memInfoBuilder.append("  Free RAM: ");
17557        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17558                + memInfo.getFreeSizeKb()));
17559        memInfoBuilder.append("\n");
17560        memInfoBuilder.append("  Used RAM: ");
17561        memInfoBuilder.append(stringifyKBSize(
17562                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17563        memInfoBuilder.append("\n");
17564        memInfoBuilder.append("  Lost RAM: ");
17565        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17566                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17567                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17568        memInfoBuilder.append("\n");
17569        Slog.i(TAG, "Low on memory:");
17570        Slog.i(TAG, shortNativeBuilder.toString());
17571        Slog.i(TAG, fullJavaBuilder.toString());
17572        Slog.i(TAG, memInfoBuilder.toString());
17573
17574        StringBuilder dropBuilder = new StringBuilder(1024);
17575        /*
17576        StringWriter oomSw = new StringWriter();
17577        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17578        StringWriter catSw = new StringWriter();
17579        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17580        String[] emptyArgs = new String[] { };
17581        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17582        oomPw.flush();
17583        String oomString = oomSw.toString();
17584        */
17585        dropBuilder.append("Low on memory:");
17586        dropBuilder.append(stack);
17587        dropBuilder.append('\n');
17588        dropBuilder.append(fullNativeBuilder);
17589        dropBuilder.append(fullJavaBuilder);
17590        dropBuilder.append('\n');
17591        dropBuilder.append(memInfoBuilder);
17592        dropBuilder.append('\n');
17593        /*
17594        dropBuilder.append(oomString);
17595        dropBuilder.append('\n');
17596        */
17597        StringWriter catSw = new StringWriter();
17598        synchronized (ActivityManagerService.this) {
17599            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17600            String[] emptyArgs = new String[] { };
17601            catPw.println();
17602            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17603            catPw.println();
17604            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17605                    false, null).dumpLocked();
17606            catPw.println();
17607            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17608            catPw.flush();
17609        }
17610        dropBuilder.append(catSw.toString());
17611        addErrorToDropBox("lowmem", null, "system_server", null,
17612                null, tag.toString(), dropBuilder.toString(), null, null);
17613        //Slog.i(TAG, "Sent to dropbox:");
17614        //Slog.i(TAG, dropBuilder.toString());
17615        synchronized (ActivityManagerService.this) {
17616            long now = SystemClock.uptimeMillis();
17617            if (mLastMemUsageReportTime < now) {
17618                mLastMemUsageReportTime = now;
17619            }
17620        }
17621    }
17622
17623    /**
17624     * Searches array of arguments for the specified string
17625     * @param args array of argument strings
17626     * @param value value to search for
17627     * @return true if the value is contained in the array
17628     */
17629    private static boolean scanArgs(String[] args, String value) {
17630        if (args != null) {
17631            for (String arg : args) {
17632                if (value.equals(arg)) {
17633                    return true;
17634                }
17635            }
17636        }
17637        return false;
17638    }
17639
17640    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17641            ContentProviderRecord cpr, boolean always) {
17642        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17643
17644        if (!inLaunching || always) {
17645            synchronized (cpr) {
17646                cpr.launchingApp = null;
17647                cpr.notifyAll();
17648            }
17649            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17650            String names[] = cpr.info.authority.split(";");
17651            for (int j = 0; j < names.length; j++) {
17652                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17653            }
17654        }
17655
17656        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17657            ContentProviderConnection conn = cpr.connections.get(i);
17658            if (conn.waiting) {
17659                // If this connection is waiting for the provider, then we don't
17660                // need to mess with its process unless we are always removing
17661                // or for some reason the provider is not currently launching.
17662                if (inLaunching && !always) {
17663                    continue;
17664                }
17665            }
17666            ProcessRecord capp = conn.client;
17667            conn.dead = true;
17668            if (conn.stableCount > 0) {
17669                if (!capp.persistent && capp.thread != null
17670                        && capp.pid != 0
17671                        && capp.pid != MY_PID) {
17672                    capp.kill("depends on provider "
17673                            + cpr.name.flattenToShortString()
17674                            + " in dying proc " + (proc != null ? proc.processName : "??")
17675                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17676                }
17677            } else if (capp.thread != null && conn.provider.provider != null) {
17678                try {
17679                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17680                } catch (RemoteException e) {
17681                }
17682                // In the protocol here, we don't expect the client to correctly
17683                // clean up this connection, we'll just remove it.
17684                cpr.connections.remove(i);
17685                if (conn.client.conProviders.remove(conn)) {
17686                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17687                }
17688            }
17689        }
17690
17691        if (inLaunching && always) {
17692            mLaunchingProviders.remove(cpr);
17693        }
17694        return inLaunching;
17695    }
17696
17697    /**
17698     * Main code for cleaning up a process when it has gone away.  This is
17699     * called both as a result of the process dying, or directly when stopping
17700     * a process when running in single process mode.
17701     *
17702     * @return Returns true if the given process has been restarted, so the
17703     * app that was passed in must remain on the process lists.
17704     */
17705    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17706            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17707        if (index >= 0) {
17708            removeLruProcessLocked(app);
17709            ProcessList.remove(app.pid);
17710        }
17711
17712        mProcessesToGc.remove(app);
17713        mPendingPssProcesses.remove(app);
17714
17715        // Dismiss any open dialogs.
17716        if (app.crashDialog != null && !app.forceCrashReport) {
17717            app.crashDialog.dismiss();
17718            app.crashDialog = null;
17719        }
17720        if (app.anrDialog != null) {
17721            app.anrDialog.dismiss();
17722            app.anrDialog = null;
17723        }
17724        if (app.waitDialog != null) {
17725            app.waitDialog.dismiss();
17726            app.waitDialog = null;
17727        }
17728
17729        app.crashing = false;
17730        app.notResponding = false;
17731
17732        app.resetPackageList(mProcessStats);
17733        app.unlinkDeathRecipient();
17734        app.makeInactive(mProcessStats);
17735        app.waitingToKill = null;
17736        app.forcingToForeground = null;
17737        updateProcessForegroundLocked(app, false, false);
17738        app.foregroundActivities = false;
17739        app.hasShownUi = false;
17740        app.treatLikeActivity = false;
17741        app.hasAboveClient = false;
17742        app.hasClientActivities = false;
17743
17744        mServices.killServicesLocked(app, allowRestart);
17745
17746        boolean restart = false;
17747
17748        // Remove published content providers.
17749        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17750            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17751            final boolean always = app.bad || !allowRestart;
17752            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17753            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17754                // We left the provider in the launching list, need to
17755                // restart it.
17756                restart = true;
17757            }
17758
17759            cpr.provider = null;
17760            cpr.proc = null;
17761        }
17762        app.pubProviders.clear();
17763
17764        // Take care of any launching providers waiting for this process.
17765        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17766            restart = true;
17767        }
17768
17769        // Unregister from connected content providers.
17770        if (!app.conProviders.isEmpty()) {
17771            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17772                ContentProviderConnection conn = app.conProviders.get(i);
17773                conn.provider.connections.remove(conn);
17774                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17775                        conn.provider.name);
17776            }
17777            app.conProviders.clear();
17778        }
17779
17780        // At this point there may be remaining entries in mLaunchingProviders
17781        // where we were the only one waiting, so they are no longer of use.
17782        // Look for these and clean up if found.
17783        // XXX Commented out for now.  Trying to figure out a way to reproduce
17784        // the actual situation to identify what is actually going on.
17785        if (false) {
17786            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17787                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17788                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17789                    synchronized (cpr) {
17790                        cpr.launchingApp = null;
17791                        cpr.notifyAll();
17792                    }
17793                }
17794            }
17795        }
17796
17797        skipCurrentReceiverLocked(app);
17798
17799        // Unregister any receivers.
17800        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17801            removeReceiverLocked(app.receivers.valueAt(i));
17802        }
17803        app.receivers.clear();
17804
17805        // If the app is undergoing backup, tell the backup manager about it
17806        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17807            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17808                    + mBackupTarget.appInfo + " died during backup");
17809            mHandler.post(new Runnable() {
17810                @Override
17811                public void run(){
17812                    try {
17813                        IBackupManager bm = IBackupManager.Stub.asInterface(
17814                                ServiceManager.getService(Context.BACKUP_SERVICE));
17815                        bm.agentDisconnected(app.info.packageName);
17816                    } catch (RemoteException e) {
17817                        // can't happen; backup manager is local
17818                    }
17819                }
17820            });
17821        }
17822
17823        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17824            ProcessChangeItem item = mPendingProcessChanges.get(i);
17825            if (item.pid == app.pid) {
17826                mPendingProcessChanges.remove(i);
17827                mAvailProcessChanges.add(item);
17828            }
17829        }
17830        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17831                null).sendToTarget();
17832
17833        // If the caller is restarting this app, then leave it in its
17834        // current lists and let the caller take care of it.
17835        if (restarting) {
17836            return false;
17837        }
17838
17839        if (!app.persistent || app.isolated) {
17840            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17841                    "Removing non-persistent process during cleanup: " + app);
17842            if (!replacingPid) {
17843                removeProcessNameLocked(app.processName, app.uid, app);
17844            }
17845            if (mHeavyWeightProcess == app) {
17846                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17847                        mHeavyWeightProcess.userId, 0));
17848                mHeavyWeightProcess = null;
17849            }
17850        } else if (!app.removed) {
17851            // This app is persistent, so we need to keep its record around.
17852            // If it is not already on the pending app list, add it there
17853            // and start a new process for it.
17854            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17855                mPersistentStartingProcesses.add(app);
17856                restart = true;
17857            }
17858        }
17859        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17860                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17861        mProcessesOnHold.remove(app);
17862
17863        if (app == mHomeProcess) {
17864            mHomeProcess = null;
17865        }
17866        if (app == mPreviousProcess) {
17867            mPreviousProcess = null;
17868        }
17869
17870        if (restart && !app.isolated) {
17871            // We have components that still need to be running in the
17872            // process, so re-launch it.
17873            if (index < 0) {
17874                ProcessList.remove(app.pid);
17875            }
17876            addProcessNameLocked(app);
17877            startProcessLocked(app, "restart", app.processName);
17878            return true;
17879        } else if (app.pid > 0 && app.pid != MY_PID) {
17880            // Goodbye!
17881            boolean removed;
17882            synchronized (mPidsSelfLocked) {
17883                mPidsSelfLocked.remove(app.pid);
17884                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17885            }
17886            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17887            if (app.isolated) {
17888                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17889            }
17890            app.setPid(0);
17891        }
17892        return false;
17893    }
17894
17895    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17896        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17897            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17898            if (cpr.launchingApp == app) {
17899                return true;
17900            }
17901        }
17902        return false;
17903    }
17904
17905    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17906        // Look through the content providers we are waiting to have launched,
17907        // and if any run in this process then either schedule a restart of
17908        // the process or kill the client waiting for it if this process has
17909        // gone bad.
17910        boolean restart = false;
17911        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17912            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17913            if (cpr.launchingApp == app) {
17914                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17915                    restart = true;
17916                } else {
17917                    removeDyingProviderLocked(app, cpr, true);
17918                }
17919            }
17920        }
17921        return restart;
17922    }
17923
17924    // =========================================================
17925    // SERVICES
17926    // =========================================================
17927
17928    @Override
17929    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17930            int flags) {
17931        enforceNotIsolatedCaller("getServices");
17932
17933        final int callingUid = Binder.getCallingUid();
17934        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
17935            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
17936        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
17937            callingUid);
17938        synchronized (this) {
17939            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
17940                allowed, canInteractAcrossUsers);
17941        }
17942    }
17943
17944    @Override
17945    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17946        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17947        synchronized (this) {
17948            return mServices.getRunningServiceControlPanelLocked(name);
17949        }
17950    }
17951
17952    @Override
17953    public ComponentName startService(IApplicationThread caller, Intent service,
17954            String resolvedType, boolean requireForeground, String callingPackage, int userId)
17955            throws TransactionTooLargeException {
17956        enforceNotIsolatedCaller("startService");
17957        // Refuse possible leaked file descriptors
17958        if (service != null && service.hasFileDescriptors() == true) {
17959            throw new IllegalArgumentException("File descriptors passed in Intent");
17960        }
17961
17962        if (callingPackage == null) {
17963            throw new IllegalArgumentException("callingPackage cannot be null");
17964        }
17965
17966        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17967                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
17968        synchronized(this) {
17969            final int callingPid = Binder.getCallingPid();
17970            final int callingUid = Binder.getCallingUid();
17971            final long origId = Binder.clearCallingIdentity();
17972            ComponentName res;
17973            try {
17974                res = mServices.startServiceLocked(caller, service,
17975                        resolvedType, callingPid, callingUid,
17976                        requireForeground, callingPackage, userId);
17977            } finally {
17978                Binder.restoreCallingIdentity(origId);
17979            }
17980            return res;
17981        }
17982    }
17983
17984    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17985            boolean fgRequired, String callingPackage, int userId)
17986            throws TransactionTooLargeException {
17987        synchronized(this) {
17988            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17989                    "startServiceInPackage: " + service + " type=" + resolvedType);
17990            final long origId = Binder.clearCallingIdentity();
17991            ComponentName res;
17992            try {
17993                res = mServices.startServiceLocked(null, service,
17994                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
17995            } finally {
17996                Binder.restoreCallingIdentity(origId);
17997            }
17998            return res;
17999        }
18000    }
18001
18002    @Override
18003    public int stopService(IApplicationThread caller, Intent service,
18004            String resolvedType, int userId) {
18005        enforceNotIsolatedCaller("stopService");
18006        // Refuse possible leaked file descriptors
18007        if (service != null && service.hasFileDescriptors() == true) {
18008            throw new IllegalArgumentException("File descriptors passed in Intent");
18009        }
18010
18011        synchronized(this) {
18012            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18013        }
18014    }
18015
18016    @Override
18017    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18018        enforceNotIsolatedCaller("peekService");
18019        // Refuse possible leaked file descriptors
18020        if (service != null && service.hasFileDescriptors() == true) {
18021            throw new IllegalArgumentException("File descriptors passed in Intent");
18022        }
18023
18024        if (callingPackage == null) {
18025            throw new IllegalArgumentException("callingPackage cannot be null");
18026        }
18027
18028        synchronized(this) {
18029            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18030        }
18031    }
18032
18033    @Override
18034    public boolean stopServiceToken(ComponentName className, IBinder token,
18035            int startId) {
18036        synchronized(this) {
18037            return mServices.stopServiceTokenLocked(className, token, startId);
18038        }
18039    }
18040
18041    @Override
18042    public void setServiceForeground(ComponentName className, IBinder token,
18043            int id, Notification notification, int flags) {
18044        synchronized(this) {
18045            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18046        }
18047    }
18048
18049    @Override
18050    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18051            boolean requireFull, String name, String callerPackage) {
18052        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18053                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18054    }
18055
18056    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18057            String className, int flags) {
18058        boolean result = false;
18059        // For apps that don't have pre-defined UIDs, check for permission
18060        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18061            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18062                if (ActivityManager.checkUidPermission(
18063                        INTERACT_ACROSS_USERS,
18064                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18065                    ComponentName comp = new ComponentName(aInfo.packageName, className);
18066                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
18067                            + " requests FLAG_SINGLE_USER, but app does not hold "
18068                            + INTERACT_ACROSS_USERS;
18069                    Slog.w(TAG, msg);
18070                    throw new SecurityException(msg);
18071                }
18072                // Permission passed
18073                result = true;
18074            }
18075        } else if ("system".equals(componentProcessName)) {
18076            result = true;
18077        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18078            // Phone app and persistent apps are allowed to export singleuser providers.
18079            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18080                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18081        }
18082        if (DEBUG_MU) Slog.v(TAG_MU,
18083                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18084                + Integer.toHexString(flags) + ") = " + result);
18085        return result;
18086    }
18087
18088    /**
18089     * Checks to see if the caller is in the same app as the singleton
18090     * component, or the component is in a special app. It allows special apps
18091     * to export singleton components but prevents exporting singleton
18092     * components for regular apps.
18093     */
18094    boolean isValidSingletonCall(int callingUid, int componentUid) {
18095        int componentAppId = UserHandle.getAppId(componentUid);
18096        return UserHandle.isSameApp(callingUid, componentUid)
18097                || componentAppId == SYSTEM_UID
18098                || componentAppId == PHONE_UID
18099                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18100                        == PackageManager.PERMISSION_GRANTED;
18101    }
18102
18103    public int bindService(IApplicationThread caller, IBinder token, Intent service,
18104            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18105            int userId) throws TransactionTooLargeException {
18106        enforceNotIsolatedCaller("bindService");
18107
18108        // Refuse possible leaked file descriptors
18109        if (service != null && service.hasFileDescriptors() == true) {
18110            throw new IllegalArgumentException("File descriptors passed in Intent");
18111        }
18112
18113        if (callingPackage == null) {
18114            throw new IllegalArgumentException("callingPackage cannot be null");
18115        }
18116
18117        synchronized(this) {
18118            return mServices.bindServiceLocked(caller, token, service,
18119                    resolvedType, connection, flags, callingPackage, userId);
18120        }
18121    }
18122
18123    public boolean unbindService(IServiceConnection connection) {
18124        synchronized (this) {
18125            return mServices.unbindServiceLocked(connection);
18126        }
18127    }
18128
18129    public void publishService(IBinder token, Intent intent, IBinder service) {
18130        // Refuse possible leaked file descriptors
18131        if (intent != null && intent.hasFileDescriptors() == true) {
18132            throw new IllegalArgumentException("File descriptors passed in Intent");
18133        }
18134
18135        synchronized(this) {
18136            if (!(token instanceof ServiceRecord)) {
18137                throw new IllegalArgumentException("Invalid service token");
18138            }
18139            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18140        }
18141    }
18142
18143    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18144        // Refuse possible leaked file descriptors
18145        if (intent != null && intent.hasFileDescriptors() == true) {
18146            throw new IllegalArgumentException("File descriptors passed in Intent");
18147        }
18148
18149        synchronized(this) {
18150            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18151        }
18152    }
18153
18154    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18155        synchronized(this) {
18156            if (!(token instanceof ServiceRecord)) {
18157                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18158                throw new IllegalArgumentException("Invalid service token");
18159            }
18160            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18161        }
18162    }
18163
18164    // =========================================================
18165    // BACKUP AND RESTORE
18166    // =========================================================
18167
18168    // Cause the target app to be launched if necessary and its backup agent
18169    // instantiated.  The backup agent will invoke backupAgentCreated() on the
18170    // activity manager to announce its creation.
18171    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18172        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18173        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18174
18175        IPackageManager pm = AppGlobals.getPackageManager();
18176        ApplicationInfo app = null;
18177        try {
18178            app = pm.getApplicationInfo(packageName, 0, userId);
18179        } catch (RemoteException e) {
18180            // can't happen; package manager is process-local
18181        }
18182        if (app == null) {
18183            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18184            return false;
18185        }
18186
18187        int oldBackupUid;
18188        int newBackupUid;
18189
18190        synchronized(this) {
18191            // !!! TODO: currently no check here that we're already bound
18192            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18193            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18194            synchronized (stats) {
18195                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18196            }
18197
18198            // Backup agent is now in use, its package can't be stopped.
18199            try {
18200                AppGlobals.getPackageManager().setPackageStoppedState(
18201                        app.packageName, false, UserHandle.getUserId(app.uid));
18202            } catch (RemoteException e) {
18203            } catch (IllegalArgumentException e) {
18204                Slog.w(TAG, "Failed trying to unstop package "
18205                        + app.packageName + ": " + e);
18206            }
18207
18208            BackupRecord r = new BackupRecord(ss, app, backupMode);
18209            ComponentName hostingName =
18210                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18211                            ? new ComponentName(app.packageName, app.backupAgentName)
18212                            : new ComponentName("android", "FullBackupAgent");
18213            // startProcessLocked() returns existing proc's record if it's already running
18214            ProcessRecord proc = startProcessLocked(app.processName, app,
18215                    false, 0, "backup", hostingName, false, false, false);
18216            if (proc == null) {
18217                Slog.e(TAG, "Unable to start backup agent process " + r);
18218                return false;
18219            }
18220
18221            // If the app is a regular app (uid >= 10000) and not the system server or phone
18222            // process, etc, then mark it as being in full backup so that certain calls to the
18223            // process can be blocked. This is not reset to false anywhere because we kill the
18224            // process after the full backup is done and the ProcessRecord will vaporize anyway.
18225            if (UserHandle.isApp(app.uid) &&
18226                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18227                proc.inFullBackup = true;
18228            }
18229            r.app = proc;
18230            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18231            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18232            mBackupTarget = r;
18233            mBackupAppName = app.packageName;
18234
18235            // Try not to kill the process during backup
18236            updateOomAdjLocked(proc);
18237
18238            // If the process is already attached, schedule the creation of the backup agent now.
18239            // If it is not yet live, this will be done when it attaches to the framework.
18240            if (proc.thread != null) {
18241                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18242                try {
18243                    proc.thread.scheduleCreateBackupAgent(app,
18244                            compatibilityInfoForPackageLocked(app), backupMode);
18245                } catch (RemoteException e) {
18246                    // Will time out on the backup manager side
18247                }
18248            } else {
18249                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18250            }
18251            // Invariants: at this point, the target app process exists and the application
18252            // is either already running or in the process of coming up.  mBackupTarget and
18253            // mBackupAppName describe the app, so that when it binds back to the AM we
18254            // know that it's scheduled for a backup-agent operation.
18255        }
18256
18257        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18258        if (oldBackupUid != -1) {
18259            js.removeBackingUpUid(oldBackupUid);
18260        }
18261        if (newBackupUid != -1) {
18262            js.addBackingUpUid(newBackupUid);
18263        }
18264
18265        return true;
18266    }
18267
18268    @Override
18269    public void clearPendingBackup() {
18270        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18271        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18272
18273        synchronized (this) {
18274            mBackupTarget = null;
18275            mBackupAppName = null;
18276        }
18277
18278        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18279        js.clearAllBackingUpUids();
18280    }
18281
18282    // A backup agent has just come up
18283    public void backupAgentCreated(String agentPackageName, IBinder agent) {
18284        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18285                + " = " + agent);
18286
18287        synchronized(this) {
18288            if (!agentPackageName.equals(mBackupAppName)) {
18289                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18290                return;
18291            }
18292        }
18293
18294        long oldIdent = Binder.clearCallingIdentity();
18295        try {
18296            IBackupManager bm = IBackupManager.Stub.asInterface(
18297                    ServiceManager.getService(Context.BACKUP_SERVICE));
18298            bm.agentConnected(agentPackageName, agent);
18299        } catch (RemoteException e) {
18300            // can't happen; the backup manager service is local
18301        } catch (Exception e) {
18302            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18303            e.printStackTrace();
18304        } finally {
18305            Binder.restoreCallingIdentity(oldIdent);
18306        }
18307    }
18308
18309    // done with this agent
18310    public void unbindBackupAgent(ApplicationInfo appInfo) {
18311        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18312        if (appInfo == null) {
18313            Slog.w(TAG, "unbind backup agent for null app");
18314            return;
18315        }
18316
18317        int oldBackupUid;
18318
18319        synchronized(this) {
18320            try {
18321                if (mBackupAppName == null) {
18322                    Slog.w(TAG, "Unbinding backup agent with no active backup");
18323                    return;
18324                }
18325
18326                if (!mBackupAppName.equals(appInfo.packageName)) {
18327                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18328                    return;
18329                }
18330
18331                // Not backing this app up any more; reset its OOM adjustment
18332                final ProcessRecord proc = mBackupTarget.app;
18333                updateOomAdjLocked(proc);
18334                proc.inFullBackup = false;
18335
18336                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18337
18338                // If the app crashed during backup, 'thread' will be null here
18339                if (proc.thread != null) {
18340                    try {
18341                        proc.thread.scheduleDestroyBackupAgent(appInfo,
18342                                compatibilityInfoForPackageLocked(appInfo));
18343                    } catch (Exception e) {
18344                        Slog.e(TAG, "Exception when unbinding backup agent:");
18345                        e.printStackTrace();
18346                    }
18347                }
18348            } finally {
18349                mBackupTarget = null;
18350                mBackupAppName = null;
18351            }
18352        }
18353
18354        if (oldBackupUid != -1) {
18355            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18356            js.removeBackingUpUid(oldBackupUid);
18357        }
18358    }
18359
18360    // =========================================================
18361    // BROADCASTS
18362    // =========================================================
18363
18364    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18365        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18366            return false;
18367        }
18368        // Easy case -- we have the app's ProcessRecord.
18369        if (record != null) {
18370            return record.info.isInstantApp();
18371        }
18372        // Otherwise check with PackageManager.
18373        if (callerPackage == null) {
18374            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18375            throw new IllegalArgumentException("Calling application did not provide package name");
18376        }
18377        mAppOpsService.checkPackage(uid, callerPackage);
18378        try {
18379            IPackageManager pm = AppGlobals.getPackageManager();
18380            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18381        } catch (RemoteException e) {
18382            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18383            return true;
18384        }
18385    }
18386
18387    boolean isPendingBroadcastProcessLocked(int pid) {
18388        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18389                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18390    }
18391
18392    void skipPendingBroadcastLocked(int pid) {
18393            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18394            for (BroadcastQueue queue : mBroadcastQueues) {
18395                queue.skipPendingBroadcastLocked(pid);
18396            }
18397    }
18398
18399    // The app just attached; send any pending broadcasts that it should receive
18400    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18401        boolean didSomething = false;
18402        for (BroadcastQueue queue : mBroadcastQueues) {
18403            didSomething |= queue.sendPendingBroadcastsLocked(app);
18404        }
18405        return didSomething;
18406    }
18407
18408    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18409            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18410            int flags) {
18411        enforceNotIsolatedCaller("registerReceiver");
18412        ArrayList<Intent> stickyIntents = null;
18413        ProcessRecord callerApp = null;
18414        final boolean visibleToInstantApps
18415                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18416        int callingUid;
18417        int callingPid;
18418        boolean instantApp;
18419        synchronized(this) {
18420            if (caller != null) {
18421                callerApp = getRecordForAppLocked(caller);
18422                if (callerApp == null) {
18423                    throw new SecurityException(
18424                            "Unable to find app for caller " + caller
18425                            + " (pid=" + Binder.getCallingPid()
18426                            + ") when registering receiver " + receiver);
18427                }
18428                if (callerApp.info.uid != SYSTEM_UID &&
18429                        !callerApp.pkgList.containsKey(callerPackage) &&
18430                        !"android".equals(callerPackage)) {
18431                    throw new SecurityException("Given caller package " + callerPackage
18432                            + " is not running in process " + callerApp);
18433                }
18434                callingUid = callerApp.info.uid;
18435                callingPid = callerApp.pid;
18436            } else {
18437                callerPackage = null;
18438                callingUid = Binder.getCallingUid();
18439                callingPid = Binder.getCallingPid();
18440            }
18441
18442            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18443            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18444                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18445
18446            Iterator<String> actions = filter.actionsIterator();
18447            if (actions == null) {
18448                ArrayList<String> noAction = new ArrayList<String>(1);
18449                noAction.add(null);
18450                actions = noAction.iterator();
18451            }
18452
18453            // Collect stickies of users
18454            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18455            while (actions.hasNext()) {
18456                String action = actions.next();
18457                for (int id : userIds) {
18458                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18459                    if (stickies != null) {
18460                        ArrayList<Intent> intents = stickies.get(action);
18461                        if (intents != null) {
18462                            if (stickyIntents == null) {
18463                                stickyIntents = new ArrayList<Intent>();
18464                            }
18465                            stickyIntents.addAll(intents);
18466                        }
18467                    }
18468                }
18469            }
18470        }
18471
18472        ArrayList<Intent> allSticky = null;
18473        if (stickyIntents != null) {
18474            final ContentResolver resolver = mContext.getContentResolver();
18475            // Look for any matching sticky broadcasts...
18476            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18477                Intent intent = stickyIntents.get(i);
18478                // Don't provided intents that aren't available to instant apps.
18479                if (instantApp &&
18480                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18481                    continue;
18482                }
18483                // If intent has scheme "content", it will need to acccess
18484                // provider that needs to lock mProviderMap in ActivityThread
18485                // and also it may need to wait application response, so we
18486                // cannot lock ActivityManagerService here.
18487                if (filter.match(resolver, intent, true, TAG) >= 0) {
18488                    if (allSticky == null) {
18489                        allSticky = new ArrayList<Intent>();
18490                    }
18491                    allSticky.add(intent);
18492                }
18493            }
18494        }
18495
18496        // The first sticky in the list is returned directly back to the client.
18497        Intent sticky = allSticky != null ? allSticky.get(0) : null;
18498        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18499        if (receiver == null) {
18500            return sticky;
18501        }
18502
18503        synchronized (this) {
18504            if (callerApp != null && (callerApp.thread == null
18505                    || callerApp.thread.asBinder() != caller.asBinder())) {
18506                // Original caller already died
18507                return null;
18508            }
18509            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18510            if (rl == null) {
18511                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18512                        userId, receiver);
18513                if (rl.app != null) {
18514                    rl.app.receivers.add(rl);
18515                } else {
18516                    try {
18517                        receiver.asBinder().linkToDeath(rl, 0);
18518                    } catch (RemoteException e) {
18519                        return sticky;
18520                    }
18521                    rl.linkedToDeath = true;
18522                }
18523                mRegisteredReceivers.put(receiver.asBinder(), rl);
18524            } else if (rl.uid != callingUid) {
18525                throw new IllegalArgumentException(
18526                        "Receiver requested to register for uid " + callingUid
18527                        + " was previously registered for uid " + rl.uid
18528                        + " callerPackage is " + callerPackage);
18529            } else if (rl.pid != callingPid) {
18530                throw new IllegalArgumentException(
18531                        "Receiver requested to register for pid " + callingPid
18532                        + " was previously registered for pid " + rl.pid
18533                        + " callerPackage is " + callerPackage);
18534            } else if (rl.userId != userId) {
18535                throw new IllegalArgumentException(
18536                        "Receiver requested to register for user " + userId
18537                        + " was previously registered for user " + rl.userId
18538                        + " callerPackage is " + callerPackage);
18539            }
18540            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18541                    permission, callingUid, userId, instantApp, visibleToInstantApps);
18542            rl.add(bf);
18543            if (!bf.debugCheck()) {
18544                Slog.w(TAG, "==> For Dynamic broadcast");
18545            }
18546            mReceiverResolver.addFilter(bf);
18547
18548            // Enqueue broadcasts for all existing stickies that match
18549            // this filter.
18550            if (allSticky != null) {
18551                ArrayList receivers = new ArrayList();
18552                receivers.add(bf);
18553
18554                final int stickyCount = allSticky.size();
18555                for (int i = 0; i < stickyCount; i++) {
18556                    Intent intent = allSticky.get(i);
18557                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18558                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18559                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18560                            null, 0, null, null, false, true, true, -1);
18561                    queue.enqueueParallelBroadcastLocked(r);
18562                    queue.scheduleBroadcastsLocked();
18563                }
18564            }
18565
18566            return sticky;
18567        }
18568    }
18569
18570    public void unregisterReceiver(IIntentReceiver receiver) {
18571        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18572
18573        final long origId = Binder.clearCallingIdentity();
18574        try {
18575            boolean doTrim = false;
18576
18577            synchronized(this) {
18578                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18579                if (rl != null) {
18580                    final BroadcastRecord r = rl.curBroadcast;
18581                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18582                        final boolean doNext = r.queue.finishReceiverLocked(
18583                                r, r.resultCode, r.resultData, r.resultExtras,
18584                                r.resultAbort, false);
18585                        if (doNext) {
18586                            doTrim = true;
18587                            r.queue.processNextBroadcast(false);
18588                        }
18589                    }
18590
18591                    if (rl.app != null) {
18592                        rl.app.receivers.remove(rl);
18593                    }
18594                    removeReceiverLocked(rl);
18595                    if (rl.linkedToDeath) {
18596                        rl.linkedToDeath = false;
18597                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18598                    }
18599                }
18600            }
18601
18602            // If we actually concluded any broadcasts, we might now be able
18603            // to trim the recipients' apps from our working set
18604            if (doTrim) {
18605                trimApplications();
18606                return;
18607            }
18608
18609        } finally {
18610            Binder.restoreCallingIdentity(origId);
18611        }
18612    }
18613
18614    void removeReceiverLocked(ReceiverList rl) {
18615        mRegisteredReceivers.remove(rl.receiver.asBinder());
18616        for (int i = rl.size() - 1; i >= 0; i--) {
18617            mReceiverResolver.removeFilter(rl.get(i));
18618        }
18619    }
18620
18621    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18622        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18623            ProcessRecord r = mLruProcesses.get(i);
18624            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18625                try {
18626                    r.thread.dispatchPackageBroadcast(cmd, packages);
18627                } catch (RemoteException ex) {
18628                }
18629            }
18630        }
18631    }
18632
18633    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18634            int callingUid, int[] users) {
18635        // TODO: come back and remove this assumption to triage all broadcasts
18636        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18637
18638        List<ResolveInfo> receivers = null;
18639        try {
18640            HashSet<ComponentName> singleUserReceivers = null;
18641            boolean scannedFirstReceivers = false;
18642            for (int user : users) {
18643                // Skip users that have Shell restrictions, with exception of always permitted
18644                // Shell broadcasts
18645                if (callingUid == SHELL_UID
18646                        && mUserController.hasUserRestriction(
18647                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18648                        && !isPermittedShellBroadcast(intent)) {
18649                    continue;
18650                }
18651                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18652                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18653                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18654                    // If this is not the system user, we need to check for
18655                    // any receivers that should be filtered out.
18656                    for (int i=0; i<newReceivers.size(); i++) {
18657                        ResolveInfo ri = newReceivers.get(i);
18658                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18659                            newReceivers.remove(i);
18660                            i--;
18661                        }
18662                    }
18663                }
18664                if (newReceivers != null && newReceivers.size() == 0) {
18665                    newReceivers = null;
18666                }
18667                if (receivers == null) {
18668                    receivers = newReceivers;
18669                } else if (newReceivers != null) {
18670                    // We need to concatenate the additional receivers
18671                    // found with what we have do far.  This would be easy,
18672                    // but we also need to de-dup any receivers that are
18673                    // singleUser.
18674                    if (!scannedFirstReceivers) {
18675                        // Collect any single user receivers we had already retrieved.
18676                        scannedFirstReceivers = true;
18677                        for (int i=0; i<receivers.size(); i++) {
18678                            ResolveInfo ri = receivers.get(i);
18679                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18680                                ComponentName cn = new ComponentName(
18681                                        ri.activityInfo.packageName, ri.activityInfo.name);
18682                                if (singleUserReceivers == null) {
18683                                    singleUserReceivers = new HashSet<ComponentName>();
18684                                }
18685                                singleUserReceivers.add(cn);
18686                            }
18687                        }
18688                    }
18689                    // Add the new results to the existing results, tracking
18690                    // and de-dupping single user receivers.
18691                    for (int i=0; i<newReceivers.size(); i++) {
18692                        ResolveInfo ri = newReceivers.get(i);
18693                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18694                            ComponentName cn = new ComponentName(
18695                                    ri.activityInfo.packageName, ri.activityInfo.name);
18696                            if (singleUserReceivers == null) {
18697                                singleUserReceivers = new HashSet<ComponentName>();
18698                            }
18699                            if (!singleUserReceivers.contains(cn)) {
18700                                singleUserReceivers.add(cn);
18701                                receivers.add(ri);
18702                            }
18703                        } else {
18704                            receivers.add(ri);
18705                        }
18706                    }
18707                }
18708            }
18709        } catch (RemoteException ex) {
18710            // pm is in same process, this will never happen.
18711        }
18712        return receivers;
18713    }
18714
18715    private boolean isPermittedShellBroadcast(Intent intent) {
18716        // remote bugreport should always be allowed to be taken
18717        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18718    }
18719
18720    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18721            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18722        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18723            // Don't yell about broadcasts sent via shell
18724            return;
18725        }
18726
18727        final String action = intent.getAction();
18728        if (isProtectedBroadcast
18729                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18730                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18731                || Intent.ACTION_MEDIA_BUTTON.equals(action)
18732                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18733                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18734                || Intent.ACTION_MASTER_CLEAR.equals(action)
18735                || Intent.ACTION_FACTORY_RESET.equals(action)
18736                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18737                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18738                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18739                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18740                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18741                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18742                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18743            // Broadcast is either protected, or it's a public action that
18744            // we've relaxed, so it's fine for system internals to send.
18745            return;
18746        }
18747
18748        // This broadcast may be a problem...  but there are often system components that
18749        // want to send an internal broadcast to themselves, which is annoying to have to
18750        // explicitly list each action as a protected broadcast, so we will check for that
18751        // one safe case and allow it: an explicit broadcast, only being received by something
18752        // that has protected itself.
18753        if (receivers != null && receivers.size() > 0
18754                && (intent.getPackage() != null || intent.getComponent() != null)) {
18755            boolean allProtected = true;
18756            for (int i = receivers.size()-1; i >= 0; i--) {
18757                Object target = receivers.get(i);
18758                if (target instanceof ResolveInfo) {
18759                    ResolveInfo ri = (ResolveInfo)target;
18760                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18761                        allProtected = false;
18762                        break;
18763                    }
18764                } else {
18765                    BroadcastFilter bf = (BroadcastFilter)target;
18766                    if (bf.requiredPermission == null) {
18767                        allProtected = false;
18768                        break;
18769                    }
18770                }
18771            }
18772            if (allProtected) {
18773                // All safe!
18774                return;
18775            }
18776        }
18777
18778        // The vast majority of broadcasts sent from system internals
18779        // should be protected to avoid security holes, so yell loudly
18780        // to ensure we examine these cases.
18781        if (callerApp != null) {
18782            Log.wtf(TAG, "Sending non-protected broadcast " + action
18783                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
18784                    new Throwable());
18785        } else {
18786            Log.wtf(TAG, "Sending non-protected broadcast " + action
18787                            + " from system uid " + UserHandle.formatUid(callingUid)
18788                            + " pkg " + callerPackage,
18789                    new Throwable());
18790        }
18791    }
18792
18793    final int broadcastIntentLocked(ProcessRecord callerApp,
18794            String callerPackage, Intent intent, String resolvedType,
18795            IIntentReceiver resultTo, int resultCode, String resultData,
18796            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
18797            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
18798        intent = new Intent(intent);
18799
18800        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
18801        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
18802        if (callerInstantApp) {
18803            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
18804        }
18805
18806        // By default broadcasts do not go to stopped apps.
18807        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
18808
18809        // If we have not finished booting, don't allow this to launch new processes.
18810        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
18811            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18812        }
18813
18814        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
18815                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
18816                + " ordered=" + ordered + " userid=" + userId);
18817        if ((resultTo != null) && !ordered) {
18818            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
18819        }
18820
18821        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18822                ALLOW_NON_FULL, "broadcast", callerPackage);
18823
18824        // Make sure that the user who is receiving this broadcast is running.
18825        // If not, we will just skip it. Make an exception for shutdown broadcasts
18826        // and upgrade steps.
18827
18828        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
18829            if ((callingUid != SYSTEM_UID
18830                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
18831                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
18832                Slog.w(TAG, "Skipping broadcast of " + intent
18833                        + ": user " + userId + " is stopped");
18834                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
18835            }
18836        }
18837
18838        BroadcastOptions brOptions = null;
18839        if (bOptions != null) {
18840            brOptions = new BroadcastOptions(bOptions);
18841            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
18842                // See if the caller is allowed to do this.  Note we are checking against
18843                // the actual real caller (not whoever provided the operation as say a
18844                // PendingIntent), because that who is actually supplied the arguments.
18845                if (checkComponentPermission(
18846                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
18847                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
18848                        != PackageManager.PERMISSION_GRANTED) {
18849                    String msg = "Permission Denial: " + intent.getAction()
18850                            + " broadcast from " + callerPackage + " (pid=" + callingPid
18851                            + ", uid=" + callingUid + ")"
18852                            + " requires "
18853                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
18854                    Slog.w(TAG, msg);
18855                    throw new SecurityException(msg);
18856                }
18857            }
18858        }
18859
18860        // Verify that protected broadcasts are only being sent by system code,
18861        // and that system code is only sending protected broadcasts.
18862        final String action = intent.getAction();
18863        final boolean isProtectedBroadcast;
18864        try {
18865            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18866        } catch (RemoteException e) {
18867            Slog.w(TAG, "Remote exception", e);
18868            return ActivityManager.BROADCAST_SUCCESS;
18869        }
18870
18871        final boolean isCallerSystem;
18872        switch (UserHandle.getAppId(callingUid)) {
18873            case ROOT_UID:
18874            case SYSTEM_UID:
18875            case PHONE_UID:
18876            case BLUETOOTH_UID:
18877            case NFC_UID:
18878                isCallerSystem = true;
18879                break;
18880            default:
18881                isCallerSystem = (callerApp != null) && callerApp.persistent;
18882                break;
18883        }
18884
18885        // First line security check before anything else: stop non-system apps from
18886        // sending protected broadcasts.
18887        if (!isCallerSystem) {
18888            if (isProtectedBroadcast) {
18889                String msg = "Permission Denial: not allowed to send broadcast "
18890                        + action + " from pid="
18891                        + callingPid + ", uid=" + callingUid;
18892                Slog.w(TAG, msg);
18893                throw new SecurityException(msg);
18894
18895            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18896                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18897                // Special case for compatibility: we don't want apps to send this,
18898                // but historically it has not been protected and apps may be using it
18899                // to poke their own app widget.  So, instead of making it protected,
18900                // just limit it to the caller.
18901                if (callerPackage == null) {
18902                    String msg = "Permission Denial: not allowed to send broadcast "
18903                            + action + " from unknown caller.";
18904                    Slog.w(TAG, msg);
18905                    throw new SecurityException(msg);
18906                } else if (intent.getComponent() != null) {
18907                    // They are good enough to send to an explicit component...  verify
18908                    // it is being sent to the calling app.
18909                    if (!intent.getComponent().getPackageName().equals(
18910                            callerPackage)) {
18911                        String msg = "Permission Denial: not allowed to send broadcast "
18912                                + action + " to "
18913                                + intent.getComponent().getPackageName() + " from "
18914                                + callerPackage;
18915                        Slog.w(TAG, msg);
18916                        throw new SecurityException(msg);
18917                    }
18918                } else {
18919                    // Limit broadcast to their own package.
18920                    intent.setPackage(callerPackage);
18921                }
18922            }
18923        }
18924
18925        if (action != null) {
18926            if (getBackgroundLaunchBroadcasts().contains(action)) {
18927                if (DEBUG_BACKGROUND_CHECK) {
18928                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
18929                }
18930                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
18931            }
18932
18933            switch (action) {
18934                case Intent.ACTION_UID_REMOVED:
18935                case Intent.ACTION_PACKAGE_REMOVED:
18936                case Intent.ACTION_PACKAGE_CHANGED:
18937                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18938                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18939                case Intent.ACTION_PACKAGES_SUSPENDED:
18940                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18941                    // Handle special intents: if this broadcast is from the package
18942                    // manager about a package being removed, we need to remove all of
18943                    // its activities from the history stack.
18944                    if (checkComponentPermission(
18945                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18946                            callingPid, callingUid, -1, true)
18947                            != PackageManager.PERMISSION_GRANTED) {
18948                        String msg = "Permission Denial: " + intent.getAction()
18949                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18950                                + ", uid=" + callingUid + ")"
18951                                + " requires "
18952                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18953                        Slog.w(TAG, msg);
18954                        throw new SecurityException(msg);
18955                    }
18956                    switch (action) {
18957                        case Intent.ACTION_UID_REMOVED:
18958                            final int uid = getUidFromIntent(intent);
18959                            if (uid >= 0) {
18960                                mBatteryStatsService.removeUid(uid);
18961                                mAppOpsService.uidRemoved(uid);
18962                            }
18963                            break;
18964                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18965                            // If resources are unavailable just force stop all those packages
18966                            // and flush the attribute cache as well.
18967                            String list[] =
18968                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18969                            if (list != null && list.length > 0) {
18970                                for (int i = 0; i < list.length; i++) {
18971                                    forceStopPackageLocked(list[i], -1, false, true, true,
18972                                            false, false, userId, "storage unmount");
18973                                }
18974                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18975                                sendPackageBroadcastLocked(
18976                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
18977                                        list, userId);
18978                            }
18979                            break;
18980                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18981                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18982                            break;
18983                        case Intent.ACTION_PACKAGE_REMOVED:
18984                        case Intent.ACTION_PACKAGE_CHANGED:
18985                            Uri data = intent.getData();
18986                            String ssp;
18987                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18988                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18989                                final boolean replacing =
18990                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18991                                final boolean killProcess =
18992                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18993                                final boolean fullUninstall = removed && !replacing;
18994                                if (removed) {
18995                                    if (killProcess) {
18996                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18997                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18998                                                false, true, true, false, fullUninstall, userId,
18999                                                removed ? "pkg removed" : "pkg changed");
19000                                    }
19001                                    final int cmd = killProcess
19002                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
19003                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19004                                    sendPackageBroadcastLocked(cmd,
19005                                            new String[] {ssp}, userId);
19006                                    if (fullUninstall) {
19007                                        mAppOpsService.packageRemoved(
19008                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19009
19010                                        // Remove all permissions granted from/to this package
19011                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
19012
19013                                        removeTasksByPackageNameLocked(ssp, userId);
19014
19015                                        // Hide the "unsupported display" dialog if necessary.
19016                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19017                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19018                                            mUnsupportedDisplaySizeDialog.dismiss();
19019                                            mUnsupportedDisplaySizeDialog = null;
19020                                        }
19021                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
19022                                        mBatteryStatsService.notePackageUninstalled(ssp);
19023                                    }
19024                                } else {
19025                                    if (killProcess) {
19026                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
19027                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19028                                                userId, ProcessList.INVALID_ADJ,
19029                                                false, true, true, false, "change " + ssp);
19030                                    }
19031                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19032                                            intent.getStringArrayExtra(
19033                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19034                                }
19035                            }
19036                            break;
19037                        case Intent.ACTION_PACKAGES_SUSPENDED:
19038                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
19039                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19040                                    intent.getAction());
19041                            final String[] packageNames = intent.getStringArrayExtra(
19042                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
19043                            final int userHandle = intent.getIntExtra(
19044                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19045
19046                            synchronized(ActivityManagerService.this) {
19047                                mRecentTasks.onPackagesSuspendedChanged(
19048                                        packageNames, suspended, userHandle);
19049                            }
19050                            break;
19051                    }
19052                    break;
19053                case Intent.ACTION_PACKAGE_REPLACED:
19054                {
19055                    final Uri data = intent.getData();
19056                    final String ssp;
19057                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19058                        final ApplicationInfo aInfo =
19059                                getPackageManagerInternalLocked().getApplicationInfo(
19060                                        ssp,
19061                                        userId);
19062                        if (aInfo == null) {
19063                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19064                                    + " ssp=" + ssp + " data=" + data);
19065                            return ActivityManager.BROADCAST_SUCCESS;
19066                        }
19067                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19068                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19069                                new String[] {ssp}, userId);
19070                    }
19071                    break;
19072                }
19073                case Intent.ACTION_PACKAGE_ADDED:
19074                {
19075                    // Special case for adding a package: by default turn on compatibility mode.
19076                    Uri data = intent.getData();
19077                    String ssp;
19078                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19079                        final boolean replacing =
19080                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19081                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19082
19083                        try {
19084                            ApplicationInfo ai = AppGlobals.getPackageManager().
19085                                    getApplicationInfo(ssp, 0, 0);
19086                            mBatteryStatsService.notePackageInstalled(ssp,
19087                                    ai != null ? ai.versionCode : 0);
19088                        } catch (RemoteException e) {
19089                        }
19090                    }
19091                    break;
19092                }
19093                case Intent.ACTION_PACKAGE_DATA_CLEARED:
19094                {
19095                    Uri data = intent.getData();
19096                    String ssp;
19097                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19098                        // Hide the "unsupported display" dialog if necessary.
19099                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19100                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19101                            mUnsupportedDisplaySizeDialog.dismiss();
19102                            mUnsupportedDisplaySizeDialog = null;
19103                        }
19104                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
19105                    }
19106                    break;
19107                }
19108                case Intent.ACTION_TIMEZONE_CHANGED:
19109                    // If this is the time zone changed action, queue up a message that will reset
19110                    // the timezone of all currently running processes. This message will get
19111                    // queued up before the broadcast happens.
19112                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19113                    break;
19114                case Intent.ACTION_TIME_CHANGED:
19115                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19116                    // the tri-state value it may contain and "unknown".
19117                    // For convenience we re-use the Intent extra values.
19118                    final int NO_EXTRA_VALUE_FOUND = -1;
19119                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19120                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19121                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
19122                    // Only send a message if the time preference is available.
19123                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19124                        Message updateTimePreferenceMsg =
19125                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19126                                        timeFormatPreferenceMsgValue, 0);
19127                        mHandler.sendMessage(updateTimePreferenceMsg);
19128                    }
19129                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19130                    synchronized (stats) {
19131                        stats.noteCurrentTimeChangedLocked();
19132                    }
19133                    break;
19134                case Intent.ACTION_CLEAR_DNS_CACHE:
19135                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19136                    break;
19137                case Proxy.PROXY_CHANGE_ACTION:
19138                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19139                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19140                    break;
19141                case android.hardware.Camera.ACTION_NEW_PICTURE:
19142                case android.hardware.Camera.ACTION_NEW_VIDEO:
19143                    // In N we just turned these off; in O we are turing them back on partly,
19144                    // only for registered receivers.  This will still address the main problem
19145                    // (a spam of apps waking up when a picture is taken putting significant
19146                    // memory pressure on the system at a bad point), while still allowing apps
19147                    // that are already actively running to know about this happening.
19148                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19149                    break;
19150                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19151                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19152                    break;
19153                case "com.android.launcher.action.INSTALL_SHORTCUT":
19154                    // As of O, we no longer support this broadcasts, even for pre-O apps.
19155                    // Apps should now be using ShortcutManager.pinRequestShortcut().
19156                    Log.w(TAG, "Broadcast " + action
19157                            + " no longer supported. It will not be delivered.");
19158                    return ActivityManager.BROADCAST_SUCCESS;
19159            }
19160
19161            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19162                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19163                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19164                final int uid = getUidFromIntent(intent);
19165                if (uid != -1) {
19166                    final UidRecord uidRec = mActiveUids.get(uid);
19167                    if (uidRec != null) {
19168                        uidRec.updateHasInternetPermission();
19169                    }
19170                }
19171            }
19172        }
19173
19174        // Add to the sticky list if requested.
19175        if (sticky) {
19176            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19177                    callingPid, callingUid)
19178                    != PackageManager.PERMISSION_GRANTED) {
19179                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19180                        + callingPid + ", uid=" + callingUid
19181                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19182                Slog.w(TAG, msg);
19183                throw new SecurityException(msg);
19184            }
19185            if (requiredPermissions != null && requiredPermissions.length > 0) {
19186                Slog.w(TAG, "Can't broadcast sticky intent " + intent
19187                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
19188                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19189            }
19190            if (intent.getComponent() != null) {
19191                throw new SecurityException(
19192                        "Sticky broadcasts can't target a specific component");
19193            }
19194            // We use userId directly here, since the "all" target is maintained
19195            // as a separate set of sticky broadcasts.
19196            if (userId != UserHandle.USER_ALL) {
19197                // But first, if this is not a broadcast to all users, then
19198                // make sure it doesn't conflict with an existing broadcast to
19199                // all users.
19200                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19201                        UserHandle.USER_ALL);
19202                if (stickies != null) {
19203                    ArrayList<Intent> list = stickies.get(intent.getAction());
19204                    if (list != null) {
19205                        int N = list.size();
19206                        int i;
19207                        for (i=0; i<N; i++) {
19208                            if (intent.filterEquals(list.get(i))) {
19209                                throw new IllegalArgumentException(
19210                                        "Sticky broadcast " + intent + " for user "
19211                                        + userId + " conflicts with existing global broadcast");
19212                            }
19213                        }
19214                    }
19215                }
19216            }
19217            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19218            if (stickies == null) {
19219                stickies = new ArrayMap<>();
19220                mStickyBroadcasts.put(userId, stickies);
19221            }
19222            ArrayList<Intent> list = stickies.get(intent.getAction());
19223            if (list == null) {
19224                list = new ArrayList<>();
19225                stickies.put(intent.getAction(), list);
19226            }
19227            final int stickiesCount = list.size();
19228            int i;
19229            for (i = 0; i < stickiesCount; i++) {
19230                if (intent.filterEquals(list.get(i))) {
19231                    // This sticky already exists, replace it.
19232                    list.set(i, new Intent(intent));
19233                    break;
19234                }
19235            }
19236            if (i >= stickiesCount) {
19237                list.add(new Intent(intent));
19238            }
19239        }
19240
19241        int[] users;
19242        if (userId == UserHandle.USER_ALL) {
19243            // Caller wants broadcast to go to all started users.
19244            users = mUserController.getStartedUserArrayLocked();
19245        } else {
19246            // Caller wants broadcast to go to one specific user.
19247            users = new int[] {userId};
19248        }
19249
19250        // Figure out who all will receive this broadcast.
19251        List receivers = null;
19252        List<BroadcastFilter> registeredReceivers = null;
19253        // Need to resolve the intent to interested receivers...
19254        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19255                 == 0) {
19256            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19257        }
19258        if (intent.getComponent() == null) {
19259            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19260                // Query one target user at a time, excluding shell-restricted users
19261                for (int i = 0; i < users.length; i++) {
19262                    if (mUserController.hasUserRestriction(
19263                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19264                        continue;
19265                    }
19266                    List<BroadcastFilter> registeredReceiversForUser =
19267                            mReceiverResolver.queryIntent(intent,
19268                                    resolvedType, false /*defaultOnly*/, users[i]);
19269                    if (registeredReceivers == null) {
19270                        registeredReceivers = registeredReceiversForUser;
19271                    } else if (registeredReceiversForUser != null) {
19272                        registeredReceivers.addAll(registeredReceiversForUser);
19273                    }
19274                }
19275            } else {
19276                registeredReceivers = mReceiverResolver.queryIntent(intent,
19277                        resolvedType, false /*defaultOnly*/, userId);
19278            }
19279        }
19280
19281        final boolean replacePending =
19282                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19283
19284        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19285                + " replacePending=" + replacePending);
19286
19287        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19288        if (!ordered && NR > 0) {
19289            // If we are not serializing this broadcast, then send the
19290            // registered receivers separately so they don't wait for the
19291            // components to be launched.
19292            if (isCallerSystem) {
19293                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19294                        isProtectedBroadcast, registeredReceivers);
19295            }
19296            final BroadcastQueue queue = broadcastQueueForIntent(intent);
19297            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19298                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19299                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19300                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19301            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19302            final boolean replaced = replacePending
19303                    && (queue.replaceParallelBroadcastLocked(r) != null);
19304            // Note: We assume resultTo is null for non-ordered broadcasts.
19305            if (!replaced) {
19306                queue.enqueueParallelBroadcastLocked(r);
19307                queue.scheduleBroadcastsLocked();
19308            }
19309            registeredReceivers = null;
19310            NR = 0;
19311        }
19312
19313        // Merge into one list.
19314        int ir = 0;
19315        if (receivers != null) {
19316            // A special case for PACKAGE_ADDED: do not allow the package
19317            // being added to see this broadcast.  This prevents them from
19318            // using this as a back door to get run as soon as they are
19319            // installed.  Maybe in the future we want to have a special install
19320            // broadcast or such for apps, but we'd like to deliberately make
19321            // this decision.
19322            String skipPackages[] = null;
19323            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19324                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19325                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19326                Uri data = intent.getData();
19327                if (data != null) {
19328                    String pkgName = data.getSchemeSpecificPart();
19329                    if (pkgName != null) {
19330                        skipPackages = new String[] { pkgName };
19331                    }
19332                }
19333            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19334                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19335            }
19336            if (skipPackages != null && (skipPackages.length > 0)) {
19337                for (String skipPackage : skipPackages) {
19338                    if (skipPackage != null) {
19339                        int NT = receivers.size();
19340                        for (int it=0; it<NT; it++) {
19341                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
19342                            if (curt.activityInfo.packageName.equals(skipPackage)) {
19343                                receivers.remove(it);
19344                                it--;
19345                                NT--;
19346                            }
19347                        }
19348                    }
19349                }
19350            }
19351
19352            int NT = receivers != null ? receivers.size() : 0;
19353            int it = 0;
19354            ResolveInfo curt = null;
19355            BroadcastFilter curr = null;
19356            while (it < NT && ir < NR) {
19357                if (curt == null) {
19358                    curt = (ResolveInfo)receivers.get(it);
19359                }
19360                if (curr == null) {
19361                    curr = registeredReceivers.get(ir);
19362                }
19363                if (curr.getPriority() >= curt.priority) {
19364                    // Insert this broadcast record into the final list.
19365                    receivers.add(it, curr);
19366                    ir++;
19367                    curr = null;
19368                    it++;
19369                    NT++;
19370                } else {
19371                    // Skip to the next ResolveInfo in the final list.
19372                    it++;
19373                    curt = null;
19374                }
19375            }
19376        }
19377        while (ir < NR) {
19378            if (receivers == null) {
19379                receivers = new ArrayList();
19380            }
19381            receivers.add(registeredReceivers.get(ir));
19382            ir++;
19383        }
19384
19385        if (isCallerSystem) {
19386            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19387                    isProtectedBroadcast, receivers);
19388        }
19389
19390        if ((receivers != null && receivers.size() > 0)
19391                || resultTo != null) {
19392            BroadcastQueue queue = broadcastQueueForIntent(intent);
19393            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19394                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19395                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19396                    resultData, resultExtras, ordered, sticky, false, userId);
19397
19398            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19399                    + ": prev had " + queue.mOrderedBroadcasts.size());
19400            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19401                    "Enqueueing broadcast " + r.intent.getAction());
19402
19403            final BroadcastRecord oldRecord =
19404                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19405            if (oldRecord != null) {
19406                // Replaced, fire the result-to receiver.
19407                if (oldRecord.resultTo != null) {
19408                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19409                    try {
19410                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19411                                oldRecord.intent,
19412                                Activity.RESULT_CANCELED, null, null,
19413                                false, false, oldRecord.userId);
19414                    } catch (RemoteException e) {
19415                        Slog.w(TAG, "Failure ["
19416                                + queue.mQueueName + "] sending broadcast result of "
19417                                + intent, e);
19418
19419                    }
19420                }
19421            } else {
19422                queue.enqueueOrderedBroadcastLocked(r);
19423                queue.scheduleBroadcastsLocked();
19424            }
19425        } else {
19426            // There was nobody interested in the broadcast, but we still want to record
19427            // that it happened.
19428            if (intent.getComponent() == null && intent.getPackage() == null
19429                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19430                // This was an implicit broadcast... let's record it for posterity.
19431                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19432            }
19433        }
19434
19435        return ActivityManager.BROADCAST_SUCCESS;
19436    }
19437
19438    /**
19439     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19440     */
19441    private int getUidFromIntent(Intent intent) {
19442        if (intent == null) {
19443            return -1;
19444        }
19445        final Bundle intentExtras = intent.getExtras();
19446        return intent.hasExtra(Intent.EXTRA_UID)
19447                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19448    }
19449
19450    final void rotateBroadcastStatsIfNeededLocked() {
19451        final long now = SystemClock.elapsedRealtime();
19452        if (mCurBroadcastStats == null ||
19453                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19454            mLastBroadcastStats = mCurBroadcastStats;
19455            if (mLastBroadcastStats != null) {
19456                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19457                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19458            }
19459            mCurBroadcastStats = new BroadcastStats();
19460        }
19461    }
19462
19463    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19464            int skipCount, long dispatchTime) {
19465        rotateBroadcastStatsIfNeededLocked();
19466        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19467    }
19468
19469    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19470        rotateBroadcastStatsIfNeededLocked();
19471        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19472    }
19473
19474    final Intent verifyBroadcastLocked(Intent intent) {
19475        // Refuse possible leaked file descriptors
19476        if (intent != null && intent.hasFileDescriptors() == true) {
19477            throw new IllegalArgumentException("File descriptors passed in Intent");
19478        }
19479
19480        int flags = intent.getFlags();
19481
19482        if (!mProcessesReady) {
19483            // if the caller really truly claims to know what they're doing, go
19484            // ahead and allow the broadcast without launching any receivers
19485            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19486                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19487            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19488                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19489                        + " before boot completion");
19490                throw new IllegalStateException("Cannot broadcast before boot completed");
19491            }
19492        }
19493
19494        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19495            throw new IllegalArgumentException(
19496                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19497        }
19498
19499        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19500            switch (Binder.getCallingUid()) {
19501                case ROOT_UID:
19502                case SHELL_UID:
19503                    break;
19504                default:
19505                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19506                            + Binder.getCallingUid());
19507                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19508                    break;
19509            }
19510        }
19511
19512        return intent;
19513    }
19514
19515    public final int broadcastIntent(IApplicationThread caller,
19516            Intent intent, String resolvedType, IIntentReceiver resultTo,
19517            int resultCode, String resultData, Bundle resultExtras,
19518            String[] requiredPermissions, int appOp, Bundle bOptions,
19519            boolean serialized, boolean sticky, int userId) {
19520        enforceNotIsolatedCaller("broadcastIntent");
19521        synchronized(this) {
19522            intent = verifyBroadcastLocked(intent);
19523
19524            final ProcessRecord callerApp = getRecordForAppLocked(caller);
19525            final int callingPid = Binder.getCallingPid();
19526            final int callingUid = Binder.getCallingUid();
19527            final long origId = Binder.clearCallingIdentity();
19528            int res = broadcastIntentLocked(callerApp,
19529                    callerApp != null ? callerApp.info.packageName : null,
19530                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19531                    requiredPermissions, appOp, bOptions, serialized, sticky,
19532                    callingPid, callingUid, userId);
19533            Binder.restoreCallingIdentity(origId);
19534            return res;
19535        }
19536    }
19537
19538
19539    int broadcastIntentInPackage(String packageName, int uid,
19540            Intent intent, String resolvedType, IIntentReceiver resultTo,
19541            int resultCode, String resultData, Bundle resultExtras,
19542            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19543            int userId) {
19544        synchronized(this) {
19545            intent = verifyBroadcastLocked(intent);
19546
19547            final long origId = Binder.clearCallingIdentity();
19548            String[] requiredPermissions = requiredPermission == null ? null
19549                    : new String[] {requiredPermission};
19550            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19551                    resultTo, resultCode, resultData, resultExtras,
19552                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19553                    sticky, -1, uid, userId);
19554            Binder.restoreCallingIdentity(origId);
19555            return res;
19556        }
19557    }
19558
19559    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19560        // Refuse possible leaked file descriptors
19561        if (intent != null && intent.hasFileDescriptors() == true) {
19562            throw new IllegalArgumentException("File descriptors passed in Intent");
19563        }
19564
19565        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19566                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19567
19568        synchronized(this) {
19569            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19570                    != PackageManager.PERMISSION_GRANTED) {
19571                String msg = "Permission Denial: unbroadcastIntent() from pid="
19572                        + Binder.getCallingPid()
19573                        + ", uid=" + Binder.getCallingUid()
19574                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19575                Slog.w(TAG, msg);
19576                throw new SecurityException(msg);
19577            }
19578            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19579            if (stickies != null) {
19580                ArrayList<Intent> list = stickies.get(intent.getAction());
19581                if (list != null) {
19582                    int N = list.size();
19583                    int i;
19584                    for (i=0; i<N; i++) {
19585                        if (intent.filterEquals(list.get(i))) {
19586                            list.remove(i);
19587                            break;
19588                        }
19589                    }
19590                    if (list.size() <= 0) {
19591                        stickies.remove(intent.getAction());
19592                    }
19593                }
19594                if (stickies.size() <= 0) {
19595                    mStickyBroadcasts.remove(userId);
19596                }
19597            }
19598        }
19599    }
19600
19601    void backgroundServicesFinishedLocked(int userId) {
19602        for (BroadcastQueue queue : mBroadcastQueues) {
19603            queue.backgroundServicesFinishedLocked(userId);
19604        }
19605    }
19606
19607    public void finishReceiver(IBinder who, int resultCode, String resultData,
19608            Bundle resultExtras, boolean resultAbort, int flags) {
19609        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19610
19611        // Refuse possible leaked file descriptors
19612        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19613            throw new IllegalArgumentException("File descriptors passed in Bundle");
19614        }
19615
19616        final long origId = Binder.clearCallingIdentity();
19617        try {
19618            boolean doNext = false;
19619            BroadcastRecord r;
19620
19621            synchronized(this) {
19622                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19623                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19624                r = queue.getMatchingOrderedReceiver(who);
19625                if (r != null) {
19626                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19627                        resultData, resultExtras, resultAbort, true);
19628                }
19629            }
19630
19631            if (doNext) {
19632                r.queue.processNextBroadcast(false);
19633            }
19634            trimApplications();
19635        } finally {
19636            Binder.restoreCallingIdentity(origId);
19637        }
19638    }
19639
19640    // =========================================================
19641    // INSTRUMENTATION
19642    // =========================================================
19643
19644    public boolean startInstrumentation(ComponentName className,
19645            String profileFile, int flags, Bundle arguments,
19646            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19647            int userId, String abiOverride) {
19648        enforceNotIsolatedCaller("startInstrumentation");
19649        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19650                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19651        // Refuse possible leaked file descriptors
19652        if (arguments != null && arguments.hasFileDescriptors()) {
19653            throw new IllegalArgumentException("File descriptors passed in Bundle");
19654        }
19655
19656        synchronized(this) {
19657            InstrumentationInfo ii = null;
19658            ApplicationInfo ai = null;
19659            try {
19660                ii = mContext.getPackageManager().getInstrumentationInfo(
19661                    className, STOCK_PM_FLAGS);
19662                ai = AppGlobals.getPackageManager().getApplicationInfo(
19663                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19664            } catch (PackageManager.NameNotFoundException e) {
19665            } catch (RemoteException e) {
19666            }
19667            if (ii == null) {
19668                reportStartInstrumentationFailureLocked(watcher, className,
19669                        "Unable to find instrumentation info for: " + className);
19670                return false;
19671            }
19672            if (ai == null) {
19673                reportStartInstrumentationFailureLocked(watcher, className,
19674                        "Unable to find instrumentation target package: " + ii.targetPackage);
19675                return false;
19676            }
19677            if (!ai.hasCode()) {
19678                reportStartInstrumentationFailureLocked(watcher, className,
19679                        "Instrumentation target has no code: " + ii.targetPackage);
19680                return false;
19681            }
19682
19683            int match = mContext.getPackageManager().checkSignatures(
19684                    ii.targetPackage, ii.packageName);
19685            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19686                String msg = "Permission Denial: starting instrumentation "
19687                        + className + " from pid="
19688                        + Binder.getCallingPid()
19689                        + ", uid=" + Binder.getCallingPid()
19690                        + " not allowed because package " + ii.packageName
19691                        + " does not have a signature matching the target "
19692                        + ii.targetPackage;
19693                reportStartInstrumentationFailureLocked(watcher, className, msg);
19694                throw new SecurityException(msg);
19695            }
19696
19697            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19698            activeInstr.mClass = className;
19699            String defProcess = ai.processName;;
19700            if (ii.targetProcess == null) {
19701                activeInstr.mTargetProcesses = new String[]{ai.processName};
19702            } else if (ii.targetProcess.equals("*")) {
19703                activeInstr.mTargetProcesses = new String[0];
19704            } else {
19705                activeInstr.mTargetProcesses = ii.targetProcess.split(",");
19706                defProcess = activeInstr.mTargetProcesses[0];
19707            }
19708            activeInstr.mTargetInfo = ai;
19709            activeInstr.mProfileFile = profileFile;
19710            activeInstr.mArguments = arguments;
19711            activeInstr.mWatcher = watcher;
19712            activeInstr.mUiAutomationConnection = uiAutomationConnection;
19713            activeInstr.mResultClass = className;
19714
19715            final long origId = Binder.clearCallingIdentity();
19716            // Instrumentation can kill and relaunch even persistent processes
19717            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19718                    "start instr");
19719            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19720            app.instr = activeInstr;
19721            activeInstr.mFinished = false;
19722            activeInstr.mRunningProcesses.add(app);
19723            if (!mActiveInstrumentation.contains(activeInstr)) {
19724                mActiveInstrumentation.add(activeInstr);
19725            }
19726            Binder.restoreCallingIdentity(origId);
19727        }
19728
19729        return true;
19730    }
19731
19732    /**
19733     * Report errors that occur while attempting to start Instrumentation.  Always writes the
19734     * error to the logs, but if somebody is watching, send the report there too.  This enables
19735     * the "am" command to report errors with more information.
19736     *
19737     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19738     * @param cn The component name of the instrumentation.
19739     * @param report The error report.
19740     */
19741    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19742            ComponentName cn, String report) {
19743        Slog.w(TAG, report);
19744        if (watcher != null) {
19745            Bundle results = new Bundle();
19746            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19747            results.putString("Error", report);
19748            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19749        }
19750    }
19751
19752    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19753        if (app.instr == null) {
19754            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19755            return;
19756        }
19757
19758        if (!app.instr.mFinished && results != null) {
19759            if (app.instr.mCurResults == null) {
19760                app.instr.mCurResults = new Bundle(results);
19761            } else {
19762                app.instr.mCurResults.putAll(results);
19763            }
19764        }
19765    }
19766
19767    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
19768        int userId = UserHandle.getCallingUserId();
19769        // Refuse possible leaked file descriptors
19770        if (results != null && results.hasFileDescriptors()) {
19771            throw new IllegalArgumentException("File descriptors passed in Intent");
19772        }
19773
19774        synchronized(this) {
19775            ProcessRecord app = getRecordForAppLocked(target);
19776            if (app == null) {
19777                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
19778                return;
19779            }
19780            final long origId = Binder.clearCallingIdentity();
19781            addInstrumentationResultsLocked(app, results);
19782            Binder.restoreCallingIdentity(origId);
19783        }
19784    }
19785
19786    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
19787        if (app.instr == null) {
19788            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19789            return;
19790        }
19791
19792        if (!app.instr.mFinished) {
19793            if (app.instr.mWatcher != null) {
19794                Bundle finalResults = app.instr.mCurResults;
19795                if (finalResults != null) {
19796                    if (app.instr.mCurResults != null && results != null) {
19797                        finalResults.putAll(results);
19798                    }
19799                } else {
19800                    finalResults = results;
19801                }
19802                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
19803                        app.instr.mClass, resultCode, finalResults);
19804            }
19805
19806            // Can't call out of the system process with a lock held, so post a message.
19807            if (app.instr.mUiAutomationConnection != null) {
19808                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
19809                        app.instr.mUiAutomationConnection).sendToTarget();
19810            }
19811            app.instr.mFinished = true;
19812        }
19813
19814        app.instr.removeProcess(app);
19815        app.instr = null;
19816
19817        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
19818                "finished inst");
19819    }
19820
19821    public void finishInstrumentation(IApplicationThread target,
19822            int resultCode, Bundle results) {
19823        int userId = UserHandle.getCallingUserId();
19824        // Refuse possible leaked file descriptors
19825        if (results != null && results.hasFileDescriptors()) {
19826            throw new IllegalArgumentException("File descriptors passed in Intent");
19827        }
19828
19829        synchronized(this) {
19830            ProcessRecord app = getRecordForAppLocked(target);
19831            if (app == null) {
19832                Slog.w(TAG, "finishInstrumentation: no app for " + target);
19833                return;
19834            }
19835            final long origId = Binder.clearCallingIdentity();
19836            finishInstrumentationLocked(app, resultCode, results);
19837            Binder.restoreCallingIdentity(origId);
19838        }
19839    }
19840
19841    // =========================================================
19842    // CONFIGURATION
19843    // =========================================================
19844
19845    public ConfigurationInfo getDeviceConfigurationInfo() {
19846        ConfigurationInfo config = new ConfigurationInfo();
19847        synchronized (this) {
19848            final Configuration globalConfig = getGlobalConfiguration();
19849            config.reqTouchScreen = globalConfig.touchscreen;
19850            config.reqKeyboardType = globalConfig.keyboard;
19851            config.reqNavigation = globalConfig.navigation;
19852            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
19853                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
19854                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
19855            }
19856            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
19857                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
19858                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
19859            }
19860            config.reqGlEsVersion = GL_ES_VERSION;
19861        }
19862        return config;
19863    }
19864
19865    ActivityStack getFocusedStack() {
19866        return mStackSupervisor.getFocusedStack();
19867    }
19868
19869    @Override
19870    public int getFocusedStackId() throws RemoteException {
19871        ActivityStack focusedStack = getFocusedStack();
19872        if (focusedStack != null) {
19873            return focusedStack.getStackId();
19874        }
19875        return -1;
19876    }
19877
19878    public Configuration getConfiguration() {
19879        Configuration ci;
19880        synchronized(this) {
19881            ci = new Configuration(getGlobalConfiguration());
19882            ci.userSetLocale = false;
19883        }
19884        return ci;
19885    }
19886
19887    @Override
19888    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
19889        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
19890        synchronized (this) {
19891            mSuppressResizeConfigChanges = suppress;
19892        }
19893    }
19894
19895    /**
19896     * NOTE: For the pinned stack, this method is only called after the bounds animation has
19897     *       animated the stack to the fullscreen.
19898     */
19899    @Override
19900    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
19901        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
19902        if (StackId.isHomeOrRecentsStack(fromStackId)) {
19903            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
19904        }
19905        synchronized (this) {
19906            final long origId = Binder.clearCallingIdentity();
19907            try {
19908                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
19909            } finally {
19910                Binder.restoreCallingIdentity(origId);
19911            }
19912        }
19913    }
19914
19915    @Override
19916    public void updatePersistentConfiguration(Configuration values) {
19917        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
19918        enforceWriteSettingsPermission("updatePersistentConfiguration()");
19919        if (values == null) {
19920            throw new NullPointerException("Configuration must not be null");
19921        }
19922
19923        int userId = UserHandle.getCallingUserId();
19924
19925        synchronized(this) {
19926            updatePersistentConfigurationLocked(values, userId);
19927        }
19928    }
19929
19930    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
19931        final long origId = Binder.clearCallingIdentity();
19932        try {
19933            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
19934        } finally {
19935            Binder.restoreCallingIdentity(origId);
19936        }
19937    }
19938
19939    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
19940        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
19941                FONT_SCALE, 1.0f, userId);
19942
19943        synchronized (this) {
19944            if (getGlobalConfiguration().fontScale == scaleFactor) {
19945                return;
19946            }
19947
19948            final Configuration configuration
19949                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19950            configuration.fontScale = scaleFactor;
19951            updatePersistentConfigurationLocked(configuration, userId);
19952        }
19953    }
19954
19955    private void enforceWriteSettingsPermission(String func) {
19956        int uid = Binder.getCallingUid();
19957        if (uid == ROOT_UID) {
19958            return;
19959        }
19960
19961        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
19962                Settings.getPackageNameForUid(mContext, uid), false)) {
19963            return;
19964        }
19965
19966        String msg = "Permission Denial: " + func + " from pid="
19967                + Binder.getCallingPid()
19968                + ", uid=" + uid
19969                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
19970        Slog.w(TAG, msg);
19971        throw new SecurityException(msg);
19972    }
19973
19974    @Override
19975    public boolean updateConfiguration(Configuration values) {
19976        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
19977
19978        synchronized(this) {
19979            if (values == null && mWindowManager != null) {
19980                // sentinel: fetch the current configuration from the window manager
19981                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19982            }
19983
19984            if (mWindowManager != null) {
19985                // Update OOM levels based on display size.
19986                mProcessList.applyDisplaySize(mWindowManager);
19987            }
19988
19989            final long origId = Binder.clearCallingIdentity();
19990            try {
19991                if (values != null) {
19992                    Settings.System.clearConfiguration(values);
19993                }
19994                updateConfigurationLocked(values, null, false, false /* persistent */,
19995                        UserHandle.USER_NULL, false /* deferResume */,
19996                        mTmpUpdateConfigurationResult);
19997                return mTmpUpdateConfigurationResult.changes != 0;
19998            } finally {
19999                Binder.restoreCallingIdentity(origId);
20000            }
20001        }
20002    }
20003
20004    void updateUserConfigurationLocked() {
20005        final Configuration configuration = new Configuration(getGlobalConfiguration());
20006        final int currentUserId = mUserController.getCurrentUserIdLocked();
20007        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20008                currentUserId, Settings.System.canWrite(mContext));
20009        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20010                false /* persistent */, currentUserId, false /* deferResume */);
20011    }
20012
20013    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20014            boolean initLocale) {
20015        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20016    }
20017
20018    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20019            boolean initLocale, boolean deferResume) {
20020        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20021        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20022                UserHandle.USER_NULL, deferResume);
20023    }
20024
20025    // To cache the list of supported system locales
20026    private String[] mSupportedSystemLocales = null;
20027
20028    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20029            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20030        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20031                deferResume, null /* result */);
20032    }
20033
20034    /**
20035     * Do either or both things: (1) change the current configuration, and (2)
20036     * make sure the given activity is running with the (now) current
20037     * configuration.  Returns true if the activity has been left running, or
20038     * false if <var>starting</var> is being destroyed to match the new
20039     * configuration.
20040     *
20041     * @param userId is only used when persistent parameter is set to true to persist configuration
20042     *               for that particular user
20043     */
20044    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20045            boolean initLocale, boolean persistent, int userId, boolean deferResume,
20046            UpdateConfigurationResult result) {
20047        int changes = 0;
20048        boolean kept = true;
20049
20050        if (mWindowManager != null) {
20051            mWindowManager.deferSurfaceLayout();
20052        }
20053        try {
20054            if (values != null) {
20055                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20056                        deferResume);
20057            }
20058
20059            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20060        } finally {
20061            if (mWindowManager != null) {
20062                mWindowManager.continueSurfaceLayout();
20063            }
20064        }
20065
20066        if (result != null) {
20067            result.changes = changes;
20068            result.activityRelaunched = !kept;
20069        }
20070        return kept;
20071    }
20072
20073    /** Update default (global) configuration and notify listeners about changes. */
20074    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20075            boolean persistent, int userId, boolean deferResume) {
20076        mTempConfig.setTo(getGlobalConfiguration());
20077        final int changes = mTempConfig.updateFrom(values);
20078        if (changes == 0) {
20079            return 0;
20080        }
20081
20082        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20083                "Updating global configuration to: " + values);
20084
20085        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20086
20087        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20088            final LocaleList locales = values.getLocales();
20089            int bestLocaleIndex = 0;
20090            if (locales.size() > 1) {
20091                if (mSupportedSystemLocales == null) {
20092                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20093                }
20094                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20095            }
20096            SystemProperties.set("persist.sys.locale",
20097                    locales.get(bestLocaleIndex).toLanguageTag());
20098            LocaleList.setDefault(locales, bestLocaleIndex);
20099            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20100                    locales.get(bestLocaleIndex)));
20101        }
20102
20103        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20104        mTempConfig.seq = mConfigurationSeq;
20105
20106        // Update stored global config and notify everyone about the change.
20107        mStackSupervisor.onConfigurationChanged(mTempConfig);
20108
20109        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20110        // TODO(multi-display): Update UsageEvents#Event to include displayId.
20111        mUsageStatsService.reportConfigurationChange(mTempConfig,
20112                mUserController.getCurrentUserIdLocked());
20113
20114        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20115        mShowDialogs = shouldShowDialogs(mTempConfig);
20116
20117        AttributeCache ac = AttributeCache.instance();
20118        if (ac != null) {
20119            ac.updateConfiguration(mTempConfig);
20120        }
20121
20122        // Make sure all resources in our process are updated right now, so that anyone who is going
20123        // to retrieve resource values after we return will be sure to get the new ones. This is
20124        // especially important during boot, where the first config change needs to guarantee all
20125        // resources have that config before following boot code is executed.
20126        mSystemThread.applyConfigurationToResources(mTempConfig);
20127
20128        // We need another copy of global config because we're scheduling some calls instead of
20129        // running them in place. We need to be sure that object we send will be handled unchanged.
20130        final Configuration configCopy = new Configuration(mTempConfig);
20131        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20132            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20133            msg.obj = configCopy;
20134            msg.arg1 = userId;
20135            mHandler.sendMessage(msg);
20136        }
20137
20138        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20139            ProcessRecord app = mLruProcesses.get(i);
20140            try {
20141                if (app.thread != null) {
20142                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20143                            + app.processName + " new config " + configCopy);
20144                    app.thread.scheduleConfigurationChanged(configCopy);
20145                }
20146            } catch (Exception e) {
20147            }
20148        }
20149
20150        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20151        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20152                | Intent.FLAG_RECEIVER_FOREGROUND
20153                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20154        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20155                AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20156                UserHandle.USER_ALL);
20157        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20158            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20159            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20160                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20161                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20162            if (initLocale || !mProcessesReady) {
20163                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20164            }
20165            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20166                    AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20167                    UserHandle.USER_ALL);
20168        }
20169
20170        // Override configuration of the default display duplicates global config, so we need to
20171        // update it also. This will also notify WindowManager about changes.
20172        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20173                DEFAULT_DISPLAY);
20174
20175        return changes;
20176    }
20177
20178    @Override
20179    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20180        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20181
20182        synchronized (this) {
20183            // Check if display is initialized in AM.
20184            if (!mStackSupervisor.isDisplayAdded(displayId)) {
20185                // Call might come when display is not yet added or has already been removed.
20186                if (DEBUG_CONFIGURATION) {
20187                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20188                            + displayId);
20189                }
20190                return false;
20191            }
20192
20193            if (values == null && mWindowManager != null) {
20194                // sentinel: fetch the current configuration from the window manager
20195                values = mWindowManager.computeNewConfiguration(displayId);
20196            }
20197
20198            if (mWindowManager != null) {
20199                // Update OOM levels based on display size.
20200                mProcessList.applyDisplaySize(mWindowManager);
20201            }
20202
20203            final long origId = Binder.clearCallingIdentity();
20204            try {
20205                if (values != null) {
20206                    Settings.System.clearConfiguration(values);
20207                }
20208                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20209                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20210                return mTmpUpdateConfigurationResult.changes != 0;
20211            } finally {
20212                Binder.restoreCallingIdentity(origId);
20213            }
20214        }
20215    }
20216
20217    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20218            boolean deferResume, int displayId) {
20219        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20220                displayId, null /* result */);
20221    }
20222
20223    /**
20224     * Updates override configuration specific for the selected display. If no config is provided,
20225     * new one will be computed in WM based on current display info.
20226     */
20227    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20228            ActivityRecord starting, boolean deferResume, int displayId,
20229            UpdateConfigurationResult result) {
20230        int changes = 0;
20231        boolean kept = true;
20232
20233        if (mWindowManager != null) {
20234            mWindowManager.deferSurfaceLayout();
20235        }
20236        try {
20237            if (values != null) {
20238                if (displayId == DEFAULT_DISPLAY) {
20239                    // Override configuration of the default display duplicates global config, so
20240                    // we're calling global config update instead for default display. It will also
20241                    // apply the correct override config.
20242                    changes = updateGlobalConfiguration(values, false /* initLocale */,
20243                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20244                } else {
20245                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20246                }
20247            }
20248
20249            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20250        } finally {
20251            if (mWindowManager != null) {
20252                mWindowManager.continueSurfaceLayout();
20253            }
20254        }
20255
20256        if (result != null) {
20257            result.changes = changes;
20258            result.activityRelaunched = !kept;
20259        }
20260        return kept;
20261    }
20262
20263    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20264            int displayId) {
20265        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20266        final int changes = mTempConfig.updateFrom(values);
20267        if (changes == 0) {
20268            return 0;
20269        }
20270
20271        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
20272                + " for displayId=" + displayId);
20273        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20274
20275        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20276        if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20277            // Reset the unsupported display size dialog.
20278            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20279
20280            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20281        }
20282
20283        // Update the configuration with WM first and check if any of the stacks need to be resized
20284        // due to the configuration change. If so, resize the stacks now and do any relaunches if
20285        // necessary. This way we don't need to relaunch again afterwards in
20286        // ensureActivityConfigurationLocked().
20287        if (mWindowManager != null) {
20288            final int[] resizedStacks =
20289                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20290            if (resizedStacks != null) {
20291                for (int stackId : resizedStacks) {
20292                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20293                }
20294            }
20295        }
20296
20297        return changes;
20298    }
20299
20300    /** Applies latest configuration and/or visibility updates if needed. */
20301    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20302        boolean kept = true;
20303        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20304        // mainStack is null during startup.
20305        if (mainStack != null) {
20306            if (changes != 0 && starting == null) {
20307                // If the configuration changed, and the caller is not already
20308                // in the process of starting an activity, then find the top
20309                // activity to check if its configuration needs to change.
20310                starting = mainStack.topRunningActivityLocked();
20311            }
20312
20313            if (starting != null) {
20314                kept = starting.ensureActivityConfigurationLocked(changes,
20315                        false /* preserveWindow */);
20316                // And we need to make sure at this point that all other activities
20317                // are made visible with the correct configuration.
20318                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20319                        !PRESERVE_WINDOWS);
20320            }
20321        }
20322
20323        return kept;
20324    }
20325
20326    /** Helper method that requests bounds from WM and applies them to stack. */
20327    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20328        final Rect newStackBounds = new Rect();
20329        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20330        mStackSupervisor.resizeStackLocked(
20331                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20332                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20333                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20334    }
20335
20336    /**
20337     * Decide based on the configuration whether we should show the ANR,
20338     * crash, etc dialogs.  The idea is that if there is no affordance to
20339     * press the on-screen buttons, or the user experience would be more
20340     * greatly impacted than the crash itself, we shouldn't show the dialog.
20341     *
20342     * A thought: SystemUI might also want to get told about this, the Power
20343     * dialog / global actions also might want different behaviors.
20344     */
20345    private static boolean shouldShowDialogs(Configuration config) {
20346        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20347                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20348                                   && config.navigation == Configuration.NAVIGATION_NONAV);
20349        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20350        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20351                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20352                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20353                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20354        return inputMethodExists && uiModeSupportsDialogs;
20355    }
20356
20357    @Override
20358    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20359        synchronized (this) {
20360            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20361            if (srec != null) {
20362                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20363            }
20364        }
20365        return false;
20366    }
20367
20368    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20369            Intent resultData) {
20370
20371        synchronized (this) {
20372            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20373            if (r != null) {
20374                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20375            }
20376            return false;
20377        }
20378    }
20379
20380    public int getLaunchedFromUid(IBinder activityToken) {
20381        ActivityRecord srec;
20382        synchronized (this) {
20383            srec = ActivityRecord.forTokenLocked(activityToken);
20384        }
20385        if (srec == null) {
20386            return -1;
20387        }
20388        return srec.launchedFromUid;
20389    }
20390
20391    public String getLaunchedFromPackage(IBinder activityToken) {
20392        ActivityRecord srec;
20393        synchronized (this) {
20394            srec = ActivityRecord.forTokenLocked(activityToken);
20395        }
20396        if (srec == null) {
20397            return null;
20398        }
20399        return srec.launchedFromPackage;
20400    }
20401
20402    // =========================================================
20403    // LIFETIME MANAGEMENT
20404    // =========================================================
20405
20406    // Returns whether the app is receiving broadcast.
20407    // If receiving, fetch all broadcast queues which the app is
20408    // the current [or imminent] receiver on.
20409    private boolean isReceivingBroadcastLocked(ProcessRecord app,
20410            ArraySet<BroadcastQueue> receivingQueues) {
20411        if (!app.curReceivers.isEmpty()) {
20412            for (BroadcastRecord r : app.curReceivers) {
20413                receivingQueues.add(r.queue);
20414            }
20415            return true;
20416        }
20417
20418        // It's not the current receiver, but it might be starting up to become one
20419        for (BroadcastQueue queue : mBroadcastQueues) {
20420            final BroadcastRecord r = queue.mPendingBroadcast;
20421            if (r != null && r.curApp == app) {
20422                // found it; report which queue it's in
20423                receivingQueues.add(queue);
20424            }
20425        }
20426
20427        return !receivingQueues.isEmpty();
20428    }
20429
20430    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20431            int targetUid, ComponentName targetComponent, String targetProcess) {
20432        if (!mTrackingAssociations) {
20433            return null;
20434        }
20435        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20436                = mAssociations.get(targetUid);
20437        if (components == null) {
20438            components = new ArrayMap<>();
20439            mAssociations.put(targetUid, components);
20440        }
20441        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20442        if (sourceUids == null) {
20443            sourceUids = new SparseArray<>();
20444            components.put(targetComponent, sourceUids);
20445        }
20446        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20447        if (sourceProcesses == null) {
20448            sourceProcesses = new ArrayMap<>();
20449            sourceUids.put(sourceUid, sourceProcesses);
20450        }
20451        Association ass = sourceProcesses.get(sourceProcess);
20452        if (ass == null) {
20453            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20454                    targetProcess);
20455            sourceProcesses.put(sourceProcess, ass);
20456        }
20457        ass.mCount++;
20458        ass.mNesting++;
20459        if (ass.mNesting == 1) {
20460            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20461            ass.mLastState = sourceState;
20462        }
20463        return ass;
20464    }
20465
20466    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20467            ComponentName targetComponent) {
20468        if (!mTrackingAssociations) {
20469            return;
20470        }
20471        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20472                = mAssociations.get(targetUid);
20473        if (components == null) {
20474            return;
20475        }
20476        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20477        if (sourceUids == null) {
20478            return;
20479        }
20480        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20481        if (sourceProcesses == null) {
20482            return;
20483        }
20484        Association ass = sourceProcesses.get(sourceProcess);
20485        if (ass == null || ass.mNesting <= 0) {
20486            return;
20487        }
20488        ass.mNesting--;
20489        if (ass.mNesting == 0) {
20490            long uptime = SystemClock.uptimeMillis();
20491            ass.mTime += uptime - ass.mStartTime;
20492            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20493                    += uptime - ass.mLastStateUptime;
20494            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20495        }
20496    }
20497
20498    private void noteUidProcessState(final int uid, final int state) {
20499        mBatteryStatsService.noteUidProcessState(uid, state);
20500        if (mTrackingAssociations) {
20501            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20502                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20503                        = mAssociations.valueAt(i1);
20504                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20505                    SparseArray<ArrayMap<String, Association>> sourceUids
20506                            = targetComponents.valueAt(i2);
20507                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20508                    if (sourceProcesses != null) {
20509                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20510                            Association ass = sourceProcesses.valueAt(i4);
20511                            if (ass.mNesting >= 1) {
20512                                // currently associated
20513                                long uptime = SystemClock.uptimeMillis();
20514                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20515                                        += uptime - ass.mLastStateUptime;
20516                                ass.mLastState = state;
20517                                ass.mLastStateUptime = uptime;
20518                            }
20519                        }
20520                    }
20521                }
20522            }
20523        }
20524    }
20525
20526    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20527            boolean doingAll, long now) {
20528        if (mAdjSeq == app.adjSeq) {
20529            // This adjustment has already been computed.
20530            return app.curRawAdj;
20531        }
20532
20533        if (app.thread == null) {
20534            app.adjSeq = mAdjSeq;
20535            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20536            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20537            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20538        }
20539
20540        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20541        app.adjSource = null;
20542        app.adjTarget = null;
20543        app.empty = false;
20544        app.cached = false;
20545
20546        final int activitiesSize = app.activities.size();
20547
20548        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20549            // The max adjustment doesn't allow this app to be anything
20550            // below foreground, so it is not worth doing work for it.
20551            app.adjType = "fixed";
20552            app.adjSeq = mAdjSeq;
20553            app.curRawAdj = app.maxAdj;
20554            app.foregroundActivities = false;
20555            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20556            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20557            // System processes can do UI, and when they do we want to have
20558            // them trim their memory after the user leaves the UI.  To
20559            // facilitate this, here we need to determine whether or not it
20560            // is currently showing UI.
20561            app.systemNoUi = true;
20562            if (app == TOP_APP) {
20563                app.systemNoUi = false;
20564                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20565                app.adjType = "pers-top-activity";
20566            } else if (app.hasTopUi) {
20567                app.systemNoUi = false;
20568                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20569                app.adjType = "pers-top-ui";
20570            } else if (activitiesSize > 0) {
20571                for (int j = 0; j < activitiesSize; j++) {
20572                    final ActivityRecord r = app.activities.get(j);
20573                    if (r.visible) {
20574                        app.systemNoUi = false;
20575                    }
20576                }
20577            }
20578            if (!app.systemNoUi) {
20579                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20580            }
20581            return (app.curAdj=app.maxAdj);
20582        }
20583
20584        app.systemNoUi = false;
20585
20586        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20587
20588        // Determine the importance of the process, starting with most
20589        // important to least, and assign an appropriate OOM adjustment.
20590        int adj;
20591        int schedGroup;
20592        int procState;
20593        boolean foregroundActivities = false;
20594        mTmpBroadcastQueue.clear();
20595        if (app == TOP_APP) {
20596            // The last app on the list is the foreground app.
20597            adj = ProcessList.FOREGROUND_APP_ADJ;
20598            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20599            app.adjType = "top-activity";
20600            foregroundActivities = true;
20601            procState = PROCESS_STATE_CUR_TOP;
20602        } else if (app.instr != null) {
20603            // Don't want to kill running instrumentation.
20604            adj = ProcessList.FOREGROUND_APP_ADJ;
20605            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20606            app.adjType = "instrumentation";
20607            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20608        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20609            // An app that is currently receiving a broadcast also
20610            // counts as being in the foreground for OOM killer purposes.
20611            // It's placed in a sched group based on the nature of the
20612            // broadcast as reflected by which queue it's active in.
20613            adj = ProcessList.FOREGROUND_APP_ADJ;
20614            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20615                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20616            app.adjType = "broadcast";
20617            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20618        } else if (app.executingServices.size() > 0) {
20619            // An app that is currently executing a service callback also
20620            // counts as being in the foreground.
20621            adj = ProcessList.FOREGROUND_APP_ADJ;
20622            schedGroup = app.execServicesFg ?
20623                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20624            app.adjType = "exec-service";
20625            procState = ActivityManager.PROCESS_STATE_SERVICE;
20626            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20627        } else {
20628            // As far as we know the process is empty.  We may change our mind later.
20629            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20630            // At this point we don't actually know the adjustment.  Use the cached adj
20631            // value that the caller wants us to.
20632            adj = cachedAdj;
20633            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20634            app.cached = true;
20635            app.empty = true;
20636            app.adjType = "cch-empty";
20637        }
20638
20639        // Examine all activities if not already foreground.
20640        if (!foregroundActivities && activitiesSize > 0) {
20641            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20642            for (int j = 0; j < activitiesSize; j++) {
20643                final ActivityRecord r = app.activities.get(j);
20644                if (r.app != app) {
20645                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20646                            + " instead of expected " + app);
20647                    if (r.app == null || (r.app.uid == app.uid)) {
20648                        // Only fix things up when they look sane
20649                        r.app = app;
20650                    } else {
20651                        continue;
20652                    }
20653                }
20654                if (r.visible) {
20655                    // App has a visible activity; only upgrade adjustment.
20656                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20657                        adj = ProcessList.VISIBLE_APP_ADJ;
20658                        app.adjType = "visible";
20659                    }
20660                    if (procState > PROCESS_STATE_CUR_TOP) {
20661                        procState = PROCESS_STATE_CUR_TOP;
20662                    }
20663                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20664                    app.cached = false;
20665                    app.empty = false;
20666                    foregroundActivities = true;
20667                    final TaskRecord task = r.getTask();
20668                    if (task != null && minLayer > 0) {
20669                        final int layer = task.mLayerRank;
20670                        if (layer >= 0 && minLayer > layer) {
20671                            minLayer = layer;
20672                        }
20673                    }
20674                    break;
20675                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20676                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20677                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20678                        app.adjType = "pausing";
20679                    }
20680                    if (procState > PROCESS_STATE_CUR_TOP) {
20681                        procState = PROCESS_STATE_CUR_TOP;
20682                    }
20683                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20684                    app.cached = false;
20685                    app.empty = false;
20686                    foregroundActivities = true;
20687                } else if (r.state == ActivityState.STOPPING) {
20688                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20689                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20690                        app.adjType = "stopping";
20691                    }
20692                    // For the process state, we will at this point consider the
20693                    // process to be cached.  It will be cached either as an activity
20694                    // or empty depending on whether the activity is finishing.  We do
20695                    // this so that we can treat the process as cached for purposes of
20696                    // memory trimming (determing current memory level, trim command to
20697                    // send to process) since there can be an arbitrary number of stopping
20698                    // processes and they should soon all go into the cached state.
20699                    if (!r.finishing) {
20700                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20701                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20702                        }
20703                    }
20704                    app.cached = false;
20705                    app.empty = false;
20706                    foregroundActivities = true;
20707                } else {
20708                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20709                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20710                        app.adjType = "cch-act";
20711                    }
20712                }
20713            }
20714            if (adj == ProcessList.VISIBLE_APP_ADJ) {
20715                adj += minLayer;
20716            }
20717        }
20718
20719        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20720                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20721            if (app.foregroundServices) {
20722                // The user is aware of this app, so make it visible.
20723                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20724                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20725                app.cached = false;
20726                app.adjType = "fg-service";
20727                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20728            } else if (app.forcingToForeground != null) {
20729                // The user is aware of this app, so make it visible.
20730                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20731                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20732                app.cached = false;
20733                app.adjType = "force-fg";
20734                app.adjSource = app.forcingToForeground;
20735                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20736            } else if (app.hasOverlayUi) {
20737                // The process is display an overlay UI.
20738                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20739                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20740                app.cached = false;
20741                app.adjType = "has-overlay-ui";
20742                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20743            }
20744        }
20745
20746        if (app == mHeavyWeightProcess) {
20747            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
20748                // We don't want to kill the current heavy-weight process.
20749                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
20750                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20751                app.cached = false;
20752                app.adjType = "heavy";
20753            }
20754            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20755                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
20756            }
20757        }
20758
20759        if (app == mHomeProcess) {
20760            if (adj > ProcessList.HOME_APP_ADJ) {
20761                // This process is hosting what we currently consider to be the
20762                // home app, so we don't want to let it go into the background.
20763                adj = ProcessList.HOME_APP_ADJ;
20764                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20765                app.cached = false;
20766                app.adjType = "home";
20767            }
20768            if (procState > ActivityManager.PROCESS_STATE_HOME) {
20769                procState = ActivityManager.PROCESS_STATE_HOME;
20770            }
20771        }
20772
20773        if (app == mPreviousProcess && app.activities.size() > 0) {
20774            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20775                // This was the previous process that showed UI to the user.
20776                // We want to try to keep it around more aggressively, to give
20777                // a good experience around switching between two apps.
20778                adj = ProcessList.PREVIOUS_APP_ADJ;
20779                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20780                app.cached = false;
20781                app.adjType = "previous";
20782            }
20783            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20784                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20785            }
20786        }
20787
20788        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
20789                + " reason=" + app.adjType);
20790
20791        // By default, we use the computed adjustment.  It may be changed if
20792        // there are applications dependent on our services or providers, but
20793        // this gives us a baseline and makes sure we don't get into an
20794        // infinite recursion.
20795        app.adjSeq = mAdjSeq;
20796        app.curRawAdj = adj;
20797        app.hasStartedServices = false;
20798
20799        if (mBackupTarget != null && app == mBackupTarget.app) {
20800            // If possible we want to avoid killing apps while they're being backed up
20801            if (adj > ProcessList.BACKUP_APP_ADJ) {
20802                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
20803                adj = ProcessList.BACKUP_APP_ADJ;
20804                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20805                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20806                }
20807                app.adjType = "backup";
20808                app.cached = false;
20809            }
20810            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
20811                procState = ActivityManager.PROCESS_STATE_BACKUP;
20812            }
20813        }
20814
20815        boolean mayBeTop = false;
20816
20817        for (int is = app.services.size()-1;
20818                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20819                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20820                        || procState > ActivityManager.PROCESS_STATE_TOP);
20821                is--) {
20822            ServiceRecord s = app.services.valueAt(is);
20823            if (s.startRequested) {
20824                app.hasStartedServices = true;
20825                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
20826                    procState = ActivityManager.PROCESS_STATE_SERVICE;
20827                }
20828                if (app.hasShownUi && app != mHomeProcess) {
20829                    // If this process has shown some UI, let it immediately
20830                    // go to the LRU list because it may be pretty heavy with
20831                    // UI stuff.  We'll tag it with a label just to help
20832                    // debug and understand what is going on.
20833                    if (adj > ProcessList.SERVICE_ADJ) {
20834                        app.adjType = "cch-started-ui-services";
20835                    }
20836                } else {
20837                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20838                        // This service has seen some activity within
20839                        // recent memory, so we will keep its process ahead
20840                        // of the background processes.
20841                        if (adj > ProcessList.SERVICE_ADJ) {
20842                            adj = ProcessList.SERVICE_ADJ;
20843                            app.adjType = "started-services";
20844                            app.cached = false;
20845                        }
20846                    }
20847                    // If we have let the service slide into the background
20848                    // state, still have some text describing what it is doing
20849                    // even though the service no longer has an impact.
20850                    if (adj > ProcessList.SERVICE_ADJ) {
20851                        app.adjType = "cch-started-services";
20852                    }
20853                }
20854            }
20855
20856            for (int conni = s.connections.size()-1;
20857                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20858                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20859                            || procState > ActivityManager.PROCESS_STATE_TOP);
20860                    conni--) {
20861                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
20862                for (int i = 0;
20863                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
20864                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20865                                || procState > ActivityManager.PROCESS_STATE_TOP);
20866                        i++) {
20867                    // XXX should compute this based on the max of
20868                    // all connected clients.
20869                    ConnectionRecord cr = clist.get(i);
20870                    if (cr.binding.client == app) {
20871                        // Binding to ourself is not interesting.
20872                        continue;
20873                    }
20874
20875                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
20876                        ProcessRecord client = cr.binding.client;
20877                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
20878                                TOP_APP, doingAll, now);
20879                        int clientProcState = client.curProcState;
20880                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20881                            // If the other app is cached for any reason, for purposes here
20882                            // we are going to consider it empty.  The specific cached state
20883                            // doesn't propagate except under certain conditions.
20884                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20885                        }
20886                        String adjType = null;
20887                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
20888                            // Not doing bind OOM management, so treat
20889                            // this guy more like a started service.
20890                            if (app.hasShownUi && app != mHomeProcess) {
20891                                // If this process has shown some UI, let it immediately
20892                                // go to the LRU list because it may be pretty heavy with
20893                                // UI stuff.  We'll tag it with a label just to help
20894                                // debug and understand what is going on.
20895                                if (adj > clientAdj) {
20896                                    adjType = "cch-bound-ui-services";
20897                                }
20898                                app.cached = false;
20899                                clientAdj = adj;
20900                                clientProcState = procState;
20901                            } else {
20902                                if (now >= (s.lastActivity
20903                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20904                                    // This service has not seen activity within
20905                                    // recent memory, so allow it to drop to the
20906                                    // LRU list if there is no other reason to keep
20907                                    // it around.  We'll also tag it with a label just
20908                                    // to help debug and undertand what is going on.
20909                                    if (adj > clientAdj) {
20910                                        adjType = "cch-bound-services";
20911                                    }
20912                                    clientAdj = adj;
20913                                }
20914                            }
20915                        }
20916                        if (adj > clientAdj) {
20917                            // If this process has recently shown UI, and
20918                            // the process that is binding to it is less
20919                            // important than being visible, then we don't
20920                            // care about the binding as much as we care
20921                            // about letting this process get into the LRU
20922                            // list to be killed and restarted if needed for
20923                            // memory.
20924                            if (app.hasShownUi && app != mHomeProcess
20925                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20926                                adjType = "cch-bound-ui-services";
20927                            } else {
20928                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
20929                                        |Context.BIND_IMPORTANT)) != 0) {
20930                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
20931                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
20932                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
20933                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
20934                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20935                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20936                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
20937                                    adj = clientAdj;
20938                                } else {
20939                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20940                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
20941                                    }
20942                                }
20943                                if (!client.cached) {
20944                                    app.cached = false;
20945                                }
20946                                adjType = "service";
20947                            }
20948                        }
20949                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20950                            // This will treat important bound services identically to
20951                            // the top app, which may behave differently than generic
20952                            // foreground work.
20953                            if (client.curSchedGroup > schedGroup) {
20954                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20955                                    schedGroup = client.curSchedGroup;
20956                                } else {
20957                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20958                                }
20959                            }
20960                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20961                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20962                                    // Special handling of clients who are in the top state.
20963                                    // We *may* want to consider this process to be in the
20964                                    // top state as well, but only if there is not another
20965                                    // reason for it to be running.  Being on the top is a
20966                                    // special state, meaning you are specifically running
20967                                    // for the current top app.  If the process is already
20968                                    // running in the background for some other reason, it
20969                                    // is more important to continue considering it to be
20970                                    // in the background state.
20971                                    mayBeTop = true;
20972                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20973                                } else {
20974                                    // Special handling for above-top states (persistent
20975                                    // processes).  These should not bring the current process
20976                                    // into the top state, since they are not on top.  Instead
20977                                    // give them the best state after that.
20978                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
20979                                        clientProcState =
20980                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20981                                    } else if (mWakefulness
20982                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
20983                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
20984                                                    != 0) {
20985                                        clientProcState =
20986                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20987                                    } else {
20988                                        clientProcState =
20989                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20990                                    }
20991                                }
20992                            }
20993                        } else {
20994                            if (clientProcState <
20995                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20996                                clientProcState =
20997                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20998                            }
20999                        }
21000                        if (procState > clientProcState) {
21001                            procState = clientProcState;
21002                        }
21003                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21004                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21005                            app.pendingUiClean = true;
21006                        }
21007                        if (adjType != null) {
21008                            app.adjType = adjType;
21009                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21010                                    .REASON_SERVICE_IN_USE;
21011                            app.adjSource = cr.binding.client;
21012                            app.adjSourceProcState = clientProcState;
21013                            app.adjTarget = s.name;
21014                        }
21015                    }
21016                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21017                        app.treatLikeActivity = true;
21018                    }
21019                    final ActivityRecord a = cr.activity;
21020                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21021                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21022                            (a.visible || a.state == ActivityState.RESUMED ||
21023                             a.state == ActivityState.PAUSING)) {
21024                            adj = ProcessList.FOREGROUND_APP_ADJ;
21025                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21026                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21027                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21028                                } else {
21029                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21030                                }
21031                            }
21032                            app.cached = false;
21033                            app.adjType = "service";
21034                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21035                                    .REASON_SERVICE_IN_USE;
21036                            app.adjSource = a;
21037                            app.adjSourceProcState = procState;
21038                            app.adjTarget = s.name;
21039                        }
21040                    }
21041                }
21042            }
21043        }
21044
21045        for (int provi = app.pubProviders.size()-1;
21046                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21047                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21048                        || procState > ActivityManager.PROCESS_STATE_TOP);
21049                provi--) {
21050            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21051            for (int i = cpr.connections.size()-1;
21052                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21053                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21054                            || procState > ActivityManager.PROCESS_STATE_TOP);
21055                    i--) {
21056                ContentProviderConnection conn = cpr.connections.get(i);
21057                ProcessRecord client = conn.client;
21058                if (client == app) {
21059                    // Being our own client is not interesting.
21060                    continue;
21061                }
21062                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21063                int clientProcState = client.curProcState;
21064                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21065                    // If the other app is cached for any reason, for purposes here
21066                    // we are going to consider it empty.
21067                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21068                }
21069                if (adj > clientAdj) {
21070                    if (app.hasShownUi && app != mHomeProcess
21071                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21072                        app.adjType = "cch-ui-provider";
21073                    } else {
21074                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21075                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21076                        app.adjType = "provider";
21077                    }
21078                    app.cached &= client.cached;
21079                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21080                            .REASON_PROVIDER_IN_USE;
21081                    app.adjSource = client;
21082                    app.adjSourceProcState = clientProcState;
21083                    app.adjTarget = cpr.name;
21084                }
21085                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21086                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21087                        // Special handling of clients who are in the top state.
21088                        // We *may* want to consider this process to be in the
21089                        // top state as well, but only if there is not another
21090                        // reason for it to be running.  Being on the top is a
21091                        // special state, meaning you are specifically running
21092                        // for the current top app.  If the process is already
21093                        // running in the background for some other reason, it
21094                        // is more important to continue considering it to be
21095                        // in the background state.
21096                        mayBeTop = true;
21097                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21098                    } else {
21099                        // Special handling for above-top states (persistent
21100                        // processes).  These should not bring the current process
21101                        // into the top state, since they are not on top.  Instead
21102                        // give them the best state after that.
21103                        clientProcState =
21104                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21105                    }
21106                }
21107                if (procState > clientProcState) {
21108                    procState = clientProcState;
21109                }
21110                if (client.curSchedGroup > schedGroup) {
21111                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21112                }
21113            }
21114            // If the provider has external (non-framework) process
21115            // dependencies, ensure that its adjustment is at least
21116            // FOREGROUND_APP_ADJ.
21117            if (cpr.hasExternalProcessHandles()) {
21118                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21119                    adj = ProcessList.FOREGROUND_APP_ADJ;
21120                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21121                    app.cached = false;
21122                    app.adjType = "provider";
21123                    app.adjTarget = cpr.name;
21124                }
21125                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21126                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21127                }
21128            }
21129        }
21130
21131        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
21132            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21133                adj = ProcessList.PREVIOUS_APP_ADJ;
21134                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21135                app.cached = false;
21136                app.adjType = "provider";
21137            }
21138            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21139                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21140            }
21141        }
21142
21143        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21144            // A client of one of our services or providers is in the top state.  We
21145            // *may* want to be in the top state, but not if we are already running in
21146            // the background for some other reason.  For the decision here, we are going
21147            // to pick out a few specific states that we want to remain in when a client
21148            // is top (states that tend to be longer-term) and otherwise allow it to go
21149            // to the top state.
21150            switch (procState) {
21151                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21152                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21153                case ActivityManager.PROCESS_STATE_SERVICE:
21154                    // These all are longer-term states, so pull them up to the top
21155                    // of the background states, but not all the way to the top state.
21156                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21157                    break;
21158                default:
21159                    // Otherwise, top is a better choice, so take it.
21160                    procState = ActivityManager.PROCESS_STATE_TOP;
21161                    break;
21162            }
21163        }
21164
21165        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21166            if (app.hasClientActivities) {
21167                // This is a cached process, but with client activities.  Mark it so.
21168                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21169                app.adjType = "cch-client-act";
21170            } else if (app.treatLikeActivity) {
21171                // This is a cached process, but somebody wants us to treat it like it has
21172                // an activity, okay!
21173                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21174                app.adjType = "cch-as-act";
21175            }
21176        }
21177
21178        if (adj == ProcessList.SERVICE_ADJ) {
21179            if (doingAll) {
21180                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21181                mNewNumServiceProcs++;
21182                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21183                if (!app.serviceb) {
21184                    // This service isn't far enough down on the LRU list to
21185                    // normally be a B service, but if we are low on RAM and it
21186                    // is large we want to force it down since we would prefer to
21187                    // keep launcher over it.
21188                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21189                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21190                        app.serviceHighRam = true;
21191                        app.serviceb = true;
21192                        //Slog.i(TAG, "ADJ " + app + " high ram!");
21193                    } else {
21194                        mNewNumAServiceProcs++;
21195                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
21196                    }
21197                } else {
21198                    app.serviceHighRam = false;
21199                }
21200            }
21201            if (app.serviceb) {
21202                adj = ProcessList.SERVICE_B_ADJ;
21203            }
21204        }
21205
21206        app.curRawAdj = adj;
21207
21208        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21209        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21210        if (adj > app.maxAdj) {
21211            adj = app.maxAdj;
21212            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21213                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21214            }
21215        }
21216
21217        // Do final modification to adj.  Everything we do between here and applying
21218        // the final setAdj must be done in this function, because we will also use
21219        // it when computing the final cached adj later.  Note that we don't need to
21220        // worry about this for max adj above, since max adj will always be used to
21221        // keep it out of the cached vaues.
21222        app.curAdj = app.modifyRawOomAdj(adj);
21223        app.curSchedGroup = schedGroup;
21224        app.curProcState = procState;
21225        app.foregroundActivities = foregroundActivities;
21226
21227        return app.curRawAdj;
21228    }
21229
21230    /**
21231     * Record new PSS sample for a process.
21232     */
21233    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21234            long now) {
21235        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21236                swapPss * 1024);
21237        proc.lastPssTime = now;
21238        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21239        if (DEBUG_PSS) Slog.d(TAG_PSS,
21240                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21241                + " state=" + ProcessList.makeProcStateString(procState));
21242        if (proc.initialIdlePss == 0) {
21243            proc.initialIdlePss = pss;
21244        }
21245        proc.lastPss = pss;
21246        proc.lastSwapPss = swapPss;
21247        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21248            proc.lastCachedPss = pss;
21249            proc.lastCachedSwapPss = swapPss;
21250        }
21251
21252        final SparseArray<Pair<Long, String>> watchUids
21253                = mMemWatchProcesses.getMap().get(proc.processName);
21254        Long check = null;
21255        if (watchUids != null) {
21256            Pair<Long, String> val = watchUids.get(proc.uid);
21257            if (val == null) {
21258                val = watchUids.get(0);
21259            }
21260            if (val != null) {
21261                check = val.first;
21262            }
21263        }
21264        if (check != null) {
21265            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21266                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21267                if (!isDebuggable) {
21268                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21269                        isDebuggable = true;
21270                    }
21271                }
21272                if (isDebuggable) {
21273                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21274                    final ProcessRecord myProc = proc;
21275                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
21276                    mMemWatchDumpProcName = proc.processName;
21277                    mMemWatchDumpFile = heapdumpFile.toString();
21278                    mMemWatchDumpPid = proc.pid;
21279                    mMemWatchDumpUid = proc.uid;
21280                    BackgroundThread.getHandler().post(new Runnable() {
21281                        @Override
21282                        public void run() {
21283                            revokeUriPermission(ActivityThread.currentActivityThread()
21284                                            .getApplicationThread(),
21285                                    null, DumpHeapActivity.JAVA_URI,
21286                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
21287                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21288                                    UserHandle.myUserId());
21289                            ParcelFileDescriptor fd = null;
21290                            try {
21291                                heapdumpFile.delete();
21292                                fd = ParcelFileDescriptor.open(heapdumpFile,
21293                                        ParcelFileDescriptor.MODE_CREATE |
21294                                                ParcelFileDescriptor.MODE_TRUNCATE |
21295                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
21296                                                ParcelFileDescriptor.MODE_APPEND);
21297                                IApplicationThread thread = myProc.thread;
21298                                if (thread != null) {
21299                                    try {
21300                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
21301                                                "Requesting dump heap from "
21302                                                + myProc + " to " + heapdumpFile);
21303                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
21304                                    } catch (RemoteException e) {
21305                                    }
21306                                }
21307                            } catch (FileNotFoundException e) {
21308                                e.printStackTrace();
21309                            } finally {
21310                                if (fd != null) {
21311                                    try {
21312                                        fd.close();
21313                                    } catch (IOException e) {
21314                                    }
21315                                }
21316                            }
21317                        }
21318                    });
21319                } else {
21320                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21321                            + ", but debugging not enabled");
21322                }
21323            }
21324        }
21325    }
21326
21327    /**
21328     * Schedule PSS collection of a process.
21329     */
21330    void requestPssLocked(ProcessRecord proc, int procState) {
21331        if (mPendingPssProcesses.contains(proc)) {
21332            return;
21333        }
21334        if (mPendingPssProcesses.size() == 0) {
21335            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21336        }
21337        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21338        proc.pssProcState = procState;
21339        mPendingPssProcesses.add(proc);
21340    }
21341
21342    /**
21343     * Schedule PSS collection of all processes.
21344     */
21345    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21346        if (!always) {
21347            if (now < (mLastFullPssTime +
21348                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
21349                return;
21350            }
21351        }
21352        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21353        mLastFullPssTime = now;
21354        mFullPssPending = true;
21355        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21356        mPendingPssProcesses.clear();
21357        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21358            ProcessRecord app = mLruProcesses.get(i);
21359            if (app.thread == null
21360                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21361                continue;
21362            }
21363            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21364                app.pssProcState = app.setProcState;
21365                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21366                        mTestPssMode, isSleepingLocked(), now);
21367                mPendingPssProcesses.add(app);
21368            }
21369        }
21370        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21371    }
21372
21373    public void setTestPssMode(boolean enabled) {
21374        synchronized (this) {
21375            mTestPssMode = enabled;
21376            if (enabled) {
21377                // Whenever we enable the mode, we want to take a snapshot all of current
21378                // process mem use.
21379                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21380            }
21381        }
21382    }
21383
21384    /**
21385     * Ask a given process to GC right now.
21386     */
21387    final void performAppGcLocked(ProcessRecord app) {
21388        try {
21389            app.lastRequestedGc = SystemClock.uptimeMillis();
21390            if (app.thread != null) {
21391                if (app.reportLowMemory) {
21392                    app.reportLowMemory = false;
21393                    app.thread.scheduleLowMemory();
21394                } else {
21395                    app.thread.processInBackground();
21396                }
21397            }
21398        } catch (Exception e) {
21399            // whatever.
21400        }
21401    }
21402
21403    /**
21404     * Returns true if things are idle enough to perform GCs.
21405     */
21406    private final boolean canGcNowLocked() {
21407        boolean processingBroadcasts = false;
21408        for (BroadcastQueue q : mBroadcastQueues) {
21409            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21410                processingBroadcasts = true;
21411            }
21412        }
21413        return !processingBroadcasts
21414                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21415    }
21416
21417    /**
21418     * Perform GCs on all processes that are waiting for it, but only
21419     * if things are idle.
21420     */
21421    final void performAppGcsLocked() {
21422        final int N = mProcessesToGc.size();
21423        if (N <= 0) {
21424            return;
21425        }
21426        if (canGcNowLocked()) {
21427            while (mProcessesToGc.size() > 0) {
21428                ProcessRecord proc = mProcessesToGc.remove(0);
21429                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21430                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
21431                            <= SystemClock.uptimeMillis()) {
21432                        // To avoid spamming the system, we will GC processes one
21433                        // at a time, waiting a few seconds between each.
21434                        performAppGcLocked(proc);
21435                        scheduleAppGcsLocked();
21436                        return;
21437                    } else {
21438                        // It hasn't been long enough since we last GCed this
21439                        // process...  put it in the list to wait for its time.
21440                        addProcessToGcListLocked(proc);
21441                        break;
21442                    }
21443                }
21444            }
21445
21446            scheduleAppGcsLocked();
21447        }
21448    }
21449
21450    /**
21451     * If all looks good, perform GCs on all processes waiting for them.
21452     */
21453    final void performAppGcsIfAppropriateLocked() {
21454        if (canGcNowLocked()) {
21455            performAppGcsLocked();
21456            return;
21457        }
21458        // Still not idle, wait some more.
21459        scheduleAppGcsLocked();
21460    }
21461
21462    /**
21463     * Schedule the execution of all pending app GCs.
21464     */
21465    final void scheduleAppGcsLocked() {
21466        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21467
21468        if (mProcessesToGc.size() > 0) {
21469            // Schedule a GC for the time to the next process.
21470            ProcessRecord proc = mProcessesToGc.get(0);
21471            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21472
21473            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
21474            long now = SystemClock.uptimeMillis();
21475            if (when < (now+GC_TIMEOUT)) {
21476                when = now + GC_TIMEOUT;
21477            }
21478            mHandler.sendMessageAtTime(msg, when);
21479        }
21480    }
21481
21482    /**
21483     * Add a process to the array of processes waiting to be GCed.  Keeps the
21484     * list in sorted order by the last GC time.  The process can't already be
21485     * on the list.
21486     */
21487    final void addProcessToGcListLocked(ProcessRecord proc) {
21488        boolean added = false;
21489        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21490            if (mProcessesToGc.get(i).lastRequestedGc <
21491                    proc.lastRequestedGc) {
21492                added = true;
21493                mProcessesToGc.add(i+1, proc);
21494                break;
21495            }
21496        }
21497        if (!added) {
21498            mProcessesToGc.add(0, proc);
21499        }
21500    }
21501
21502    /**
21503     * Set up to ask a process to GC itself.  This will either do it
21504     * immediately, or put it on the list of processes to gc the next
21505     * time things are idle.
21506     */
21507    final void scheduleAppGcLocked(ProcessRecord app) {
21508        long now = SystemClock.uptimeMillis();
21509        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
21510            return;
21511        }
21512        if (!mProcessesToGc.contains(app)) {
21513            addProcessToGcListLocked(app);
21514            scheduleAppGcsLocked();
21515        }
21516    }
21517
21518    final void checkExcessivePowerUsageLocked(boolean doKills) {
21519        updateCpuStatsNow();
21520
21521        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21522        boolean doWakeKills = doKills;
21523        boolean doCpuKills = doKills;
21524        if (mLastPowerCheckRealtime == 0) {
21525            doWakeKills = false;
21526        }
21527        if (mLastPowerCheckUptime == 0) {
21528            doCpuKills = false;
21529        }
21530        if (stats.isScreenOn()) {
21531            doWakeKills = false;
21532        }
21533        final long curRealtime = SystemClock.elapsedRealtime();
21534        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21535        final long curUptime = SystemClock.uptimeMillis();
21536        final long uptimeSince = curUptime - mLastPowerCheckUptime;
21537        mLastPowerCheckRealtime = curRealtime;
21538        mLastPowerCheckUptime = curUptime;
21539        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
21540            doWakeKills = false;
21541        }
21542        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
21543            doCpuKills = false;
21544        }
21545        int i = mLruProcesses.size();
21546        while (i > 0) {
21547            i--;
21548            ProcessRecord app = mLruProcesses.get(i);
21549            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21550                long wtime;
21551                synchronized (stats) {
21552                    wtime = stats.getProcessWakeTime(app.info.uid,
21553                            app.pid, curRealtime);
21554                }
21555                long wtimeUsed = wtime - app.lastWakeTime;
21556                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21557                if (DEBUG_POWER) {
21558                    StringBuilder sb = new StringBuilder(128);
21559                    sb.append("Wake for ");
21560                    app.toShortString(sb);
21561                    sb.append(": over ");
21562                    TimeUtils.formatDuration(realtimeSince, sb);
21563                    sb.append(" used ");
21564                    TimeUtils.formatDuration(wtimeUsed, sb);
21565                    sb.append(" (");
21566                    sb.append((wtimeUsed*100)/realtimeSince);
21567                    sb.append("%)");
21568                    Slog.i(TAG_POWER, sb.toString());
21569                    sb.setLength(0);
21570                    sb.append("CPU for ");
21571                    app.toShortString(sb);
21572                    sb.append(": over ");
21573                    TimeUtils.formatDuration(uptimeSince, sb);
21574                    sb.append(" used ");
21575                    TimeUtils.formatDuration(cputimeUsed, sb);
21576                    sb.append(" (");
21577                    sb.append((cputimeUsed*100)/uptimeSince);
21578                    sb.append("%)");
21579                    Slog.i(TAG_POWER, sb.toString());
21580                }
21581                // If a process has held a wake lock for more
21582                // than 50% of the time during this period,
21583                // that sounds bad.  Kill!
21584                if (doWakeKills && realtimeSince > 0
21585                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
21586                    synchronized (stats) {
21587                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21588                                realtimeSince, wtimeUsed);
21589                    }
21590                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21591                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21592                } else if (doCpuKills && uptimeSince > 0
21593                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
21594                    synchronized (stats) {
21595                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21596                                uptimeSince, cputimeUsed);
21597                    }
21598                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21599                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21600                } else {
21601                    app.lastWakeTime = wtime;
21602                    app.lastCpuTime = app.curCpuTime;
21603                }
21604            }
21605        }
21606    }
21607
21608    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21609            long nowElapsed) {
21610        boolean success = true;
21611
21612        if (app.curRawAdj != app.setRawAdj) {
21613            app.setRawAdj = app.curRawAdj;
21614        }
21615
21616        int changes = 0;
21617
21618        if (app.curAdj != app.setAdj) {
21619            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21620            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21621                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21622                    + app.adjType);
21623            app.setAdj = app.curAdj;
21624            app.verifiedAdj = ProcessList.INVALID_ADJ;
21625        }
21626
21627        if (app.setSchedGroup != app.curSchedGroup) {
21628            int oldSchedGroup = app.setSchedGroup;
21629            app.setSchedGroup = app.curSchedGroup;
21630            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21631                    "Setting sched group of " + app.processName
21632                    + " to " + app.curSchedGroup);
21633            if (app.waitingToKill != null && app.curReceivers.isEmpty()
21634                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21635                app.kill(app.waitingToKill, true);
21636                success = false;
21637            } else {
21638                int processGroup;
21639                switch (app.curSchedGroup) {
21640                    case ProcessList.SCHED_GROUP_BACKGROUND:
21641                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21642                        break;
21643                    case ProcessList.SCHED_GROUP_TOP_APP:
21644                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21645                        processGroup = THREAD_GROUP_TOP_APP;
21646                        break;
21647                    default:
21648                        processGroup = THREAD_GROUP_DEFAULT;
21649                        break;
21650                }
21651                long oldId = Binder.clearCallingIdentity();
21652                try {
21653                    setProcessGroup(app.pid, processGroup);
21654                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21655                        // do nothing if we already switched to RT
21656                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21657                            mVrController.onTopProcChangedLocked(app);
21658                            if (mUseFifoUiScheduling) {
21659                                // Switch UI pipeline for app to SCHED_FIFO
21660                                app.savedPriority = Process.getThreadPriority(app.pid);
21661                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
21662                                if (app.renderThreadTid != 0) {
21663                                    scheduleAsFifoPriority(app.renderThreadTid,
21664                                        /* suppressLogs */true);
21665                                    if (DEBUG_OOM_ADJ) {
21666                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
21667                                            app.renderThreadTid + ") to FIFO");
21668                                    }
21669                                } else {
21670                                    if (DEBUG_OOM_ADJ) {
21671                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
21672                                    }
21673                                }
21674                            } else {
21675                                // Boost priority for top app UI and render threads
21676                                setThreadPriority(app.pid, -10);
21677                                if (app.renderThreadTid != 0) {
21678                                    try {
21679                                        setThreadPriority(app.renderThreadTid, -10);
21680                                    } catch (IllegalArgumentException e) {
21681                                        // thread died, ignore
21682                                    }
21683                                }
21684                            }
21685                        }
21686                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
21687                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21688                        mVrController.onTopProcChangedLocked(app);
21689                        if (mUseFifoUiScheduling) {
21690                            // Reset UI pipeline to SCHED_OTHER
21691                            setThreadScheduler(app.pid, SCHED_OTHER, 0);
21692                            setThreadPriority(app.pid, app.savedPriority);
21693                            if (app.renderThreadTid != 0) {
21694                                setThreadScheduler(app.renderThreadTid,
21695                                    SCHED_OTHER, 0);
21696                                setThreadPriority(app.renderThreadTid, -4);
21697                            }
21698                        } else {
21699                            // Reset priority for top app UI and render threads
21700                            setThreadPriority(app.pid, 0);
21701                            if (app.renderThreadTid != 0) {
21702                                setThreadPriority(app.renderThreadTid, 0);
21703                            }
21704                        }
21705                    }
21706                } catch (Exception e) {
21707                    Slog.w(TAG, "Failed setting process group of " + app.pid
21708                            + " to " + app.curSchedGroup);
21709                    e.printStackTrace();
21710                } finally {
21711                    Binder.restoreCallingIdentity(oldId);
21712                }
21713            }
21714        }
21715        if (app.repForegroundActivities != app.foregroundActivities) {
21716            app.repForegroundActivities = app.foregroundActivities;
21717            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
21718        }
21719        if (app.repProcState != app.curProcState) {
21720            app.repProcState = app.curProcState;
21721            if (app.thread != null) {
21722                try {
21723                    if (false) {
21724                        //RuntimeException h = new RuntimeException("here");
21725                        Slog.i(TAG, "Sending new process state " + app.repProcState
21726                                + " to " + app /*, h*/);
21727                    }
21728                    app.thread.setProcessState(app.repProcState);
21729                } catch (RemoteException e) {
21730                }
21731            }
21732        }
21733        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
21734                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
21735            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
21736                // Experimental code to more aggressively collect pss while
21737                // running test...  the problem is that this tends to collect
21738                // the data right when a process is transitioning between process
21739                // states, which well tend to give noisy data.
21740                long start = SystemClock.uptimeMillis();
21741                long pss = Debug.getPss(app.pid, mTmpLong, null);
21742                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
21743                mPendingPssProcesses.remove(app);
21744                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
21745                        + " to " + app.curProcState + ": "
21746                        + (SystemClock.uptimeMillis()-start) + "ms");
21747            }
21748            app.lastStateTime = now;
21749            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21750                    mTestPssMode, isSleepingLocked(), now);
21751            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
21752                    + ProcessList.makeProcStateString(app.setProcState) + " to "
21753                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
21754                    + (app.nextPssTime-now) + ": " + app);
21755        } else {
21756            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
21757                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
21758                    mTestPssMode)))) {
21759                requestPssLocked(app, app.setProcState);
21760                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
21761                        mTestPssMode, isSleepingLocked(), now);
21762            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
21763                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
21764        }
21765        if (app.setProcState != app.curProcState) {
21766            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21767                    "Proc state change of " + app.processName
21768                            + " to " + app.curProcState);
21769            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
21770            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
21771            if (setImportant && !curImportant) {
21772                // This app is no longer something we consider important enough to allow to
21773                // use arbitrary amounts of battery power.  Note
21774                // its current wake lock time to later know to kill it if
21775                // it is not behaving well.
21776                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21777                synchronized (stats) {
21778                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
21779                            app.pid, nowElapsed);
21780                }
21781                app.lastCpuTime = app.curCpuTime;
21782
21783            }
21784            // Inform UsageStats of important process state change
21785            // Must be called before updating setProcState
21786            maybeUpdateUsageStatsLocked(app, nowElapsed);
21787
21788            app.setProcState = app.curProcState;
21789            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21790                app.notCachedSinceIdle = false;
21791            }
21792            if (!doingAll) {
21793                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
21794            } else {
21795                app.procStateChanged = true;
21796            }
21797        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
21798                > USAGE_STATS_INTERACTION_INTERVAL) {
21799            // For apps that sit around for a long time in the interactive state, we need
21800            // to report this at least once a day so they don't go idle.
21801            maybeUpdateUsageStatsLocked(app, nowElapsed);
21802        }
21803
21804        if (changes != 0) {
21805            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21806                    "Changes in " + app + ": " + changes);
21807            int i = mPendingProcessChanges.size()-1;
21808            ProcessChangeItem item = null;
21809            while (i >= 0) {
21810                item = mPendingProcessChanges.get(i);
21811                if (item.pid == app.pid) {
21812                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21813                            "Re-using existing item: " + item);
21814                    break;
21815                }
21816                i--;
21817            }
21818            if (i < 0) {
21819                // No existing item in pending changes; need a new one.
21820                final int NA = mAvailProcessChanges.size();
21821                if (NA > 0) {
21822                    item = mAvailProcessChanges.remove(NA-1);
21823                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21824                            "Retrieving available item: " + item);
21825                } else {
21826                    item = new ProcessChangeItem();
21827                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21828                            "Allocating new item: " + item);
21829                }
21830                item.changes = 0;
21831                item.pid = app.pid;
21832                item.uid = app.info.uid;
21833                if (mPendingProcessChanges.size() == 0) {
21834                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21835                            "*** Enqueueing dispatch processes changed!");
21836                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
21837                }
21838                mPendingProcessChanges.add(item);
21839            }
21840            item.changes |= changes;
21841            item.foregroundActivities = app.repForegroundActivities;
21842            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21843                    "Item " + Integer.toHexString(System.identityHashCode(item))
21844                    + " " + app.toShortString() + ": changes=" + item.changes
21845                    + " foreground=" + item.foregroundActivities
21846                    + " type=" + app.adjType + " source=" + app.adjSource
21847                    + " target=" + app.adjTarget);
21848        }
21849
21850        return success;
21851    }
21852
21853    private boolean isEphemeralLocked(int uid) {
21854        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
21855        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
21856            return false;
21857        }
21858        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
21859                packages[0]);
21860    }
21861
21862    @VisibleForTesting
21863    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
21864        final UidRecord.ChangeItem pendingChange;
21865        if (uidRec == null || uidRec.pendingChange == null) {
21866            if (mPendingUidChanges.size() == 0) {
21867                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21868                        "*** Enqueueing dispatch uid changed!");
21869                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
21870            }
21871            final int NA = mAvailUidChanges.size();
21872            if (NA > 0) {
21873                pendingChange = mAvailUidChanges.remove(NA-1);
21874                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21875                        "Retrieving available item: " + pendingChange);
21876            } else {
21877                pendingChange = new UidRecord.ChangeItem();
21878                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21879                        "Allocating new item: " + pendingChange);
21880            }
21881            if (uidRec != null) {
21882                uidRec.pendingChange = pendingChange;
21883                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
21884                    // If this uid is going away, and we haven't yet reported it is gone,
21885                    // then do so now.
21886                    change = UidRecord.CHANGE_GONE_IDLE;
21887                }
21888            } else if (uid < 0) {
21889                throw new IllegalArgumentException("No UidRecord or uid");
21890            }
21891            pendingChange.uidRecord = uidRec;
21892            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
21893            mPendingUidChanges.add(pendingChange);
21894        } else {
21895            pendingChange = uidRec.pendingChange;
21896            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
21897                change = UidRecord.CHANGE_GONE_IDLE;
21898            }
21899        }
21900        pendingChange.change = change;
21901        pendingChange.processState = uidRec != null
21902                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
21903        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
21904        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
21905        if (uidRec != null) {
21906            uidRec.updateLastDispatchedProcStateSeq(change);
21907        }
21908
21909        // Directly update the power manager, since we sit on top of it and it is critical
21910        // it be kept in sync (so wake locks will be held as soon as appropriate).
21911        if (mLocalPowerManager != null) {
21912            switch (change) {
21913                case UidRecord.CHANGE_GONE:
21914                case UidRecord.CHANGE_GONE_IDLE:
21915                    mLocalPowerManager.uidGone(pendingChange.uid);
21916                    break;
21917                case UidRecord.CHANGE_IDLE:
21918                    mLocalPowerManager.uidIdle(pendingChange.uid);
21919                    break;
21920                case UidRecord.CHANGE_ACTIVE:
21921                    mLocalPowerManager.uidActive(pendingChange.uid);
21922                    break;
21923                default:
21924                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
21925                            pendingChange.processState);
21926                    break;
21927            }
21928        }
21929    }
21930
21931    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
21932            String authority) {
21933        if (app == null) return;
21934        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21935            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
21936            if (userState == null) return;
21937            final long now = SystemClock.elapsedRealtime();
21938            Long lastReported = userState.mProviderLastReportedFg.get(authority);
21939            if (lastReported == null || lastReported < now - 60 * 1000L) {
21940                if (mSystemReady) {
21941                    // Cannot touch the user stats if not system ready
21942                    mUsageStatsService.reportContentProviderUsage(
21943                            authority, providerPkgName, app.userId);
21944                }
21945                userState.mProviderLastReportedFg.put(authority, now);
21946            }
21947        }
21948    }
21949
21950    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
21951        if (DEBUG_USAGE_STATS) {
21952            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
21953                    + "] state changes: old = " + app.setProcState + ", new = "
21954                    + app.curProcState);
21955        }
21956        if (mUsageStatsService == null) {
21957            return;
21958        }
21959        boolean isInteraction;
21960        // To avoid some abuse patterns, we are going to be careful about what we consider
21961        // to be an app interaction.  Being the top activity doesn't count while the display
21962        // is sleeping, nor do short foreground services.
21963        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
21964            isInteraction = true;
21965            app.fgInteractionTime = 0;
21966        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
21967            if (app.fgInteractionTime == 0) {
21968                app.fgInteractionTime = nowElapsed;
21969                isInteraction = false;
21970            } else {
21971                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
21972            }
21973        } else {
21974            // If the app was being forced to the foreground, by say a Toast, then
21975            // no need to treat it as an interaction
21976            isInteraction = app.forcingToForeground == null
21977                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21978            app.fgInteractionTime = 0;
21979        }
21980        if (isInteraction && (!app.reportedInteraction
21981                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
21982            app.interactionEventTime = nowElapsed;
21983            String[] packages = app.getPackageList();
21984            if (packages != null) {
21985                for (int i = 0; i < packages.length; i++) {
21986                    mUsageStatsService.reportEvent(packages[i], app.userId,
21987                            UsageEvents.Event.SYSTEM_INTERACTION);
21988                }
21989            }
21990        }
21991        app.reportedInteraction = isInteraction;
21992        if (!isInteraction) {
21993            app.interactionEventTime = 0;
21994        }
21995    }
21996
21997    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
21998        if (proc.thread != null) {
21999            if (proc.baseProcessTracker != null) {
22000                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22001            }
22002        }
22003    }
22004
22005    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22006            ProcessRecord TOP_APP, boolean doingAll, long now) {
22007        if (app.thread == null) {
22008            return false;
22009        }
22010
22011        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22012
22013        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22014    }
22015
22016    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22017            boolean oomAdj) {
22018        if (isForeground != proc.foregroundServices) {
22019            proc.foregroundServices = isForeground;
22020            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22021                    proc.info.uid);
22022            if (isForeground) {
22023                if (curProcs == null) {
22024                    curProcs = new ArrayList<ProcessRecord>();
22025                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22026                }
22027                if (!curProcs.contains(proc)) {
22028                    curProcs.add(proc);
22029                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22030                            proc.info.packageName, proc.info.uid);
22031                }
22032            } else {
22033                if (curProcs != null) {
22034                    if (curProcs.remove(proc)) {
22035                        mBatteryStatsService.noteEvent(
22036                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22037                                proc.info.packageName, proc.info.uid);
22038                        if (curProcs.size() <= 0) {
22039                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22040                        }
22041                    }
22042                }
22043            }
22044            if (oomAdj) {
22045                updateOomAdjLocked();
22046            }
22047        }
22048    }
22049
22050    private final ActivityRecord resumedAppLocked() {
22051        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22052        String pkg;
22053        int uid;
22054        if (act != null) {
22055            pkg = act.packageName;
22056            uid = act.info.applicationInfo.uid;
22057        } else {
22058            pkg = null;
22059            uid = -1;
22060        }
22061        // Has the UID or resumed package name changed?
22062        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22063                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22064            if (mCurResumedPackage != null) {
22065                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22066                        mCurResumedPackage, mCurResumedUid);
22067            }
22068            mCurResumedPackage = pkg;
22069            mCurResumedUid = uid;
22070            if (mCurResumedPackage != null) {
22071                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22072                        mCurResumedPackage, mCurResumedUid);
22073            }
22074        }
22075        return act;
22076    }
22077
22078    final boolean updateOomAdjLocked(ProcessRecord app) {
22079        final ActivityRecord TOP_ACT = resumedAppLocked();
22080        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22081        final boolean wasCached = app.cached;
22082
22083        mAdjSeq++;
22084
22085        // This is the desired cached adjusment we want to tell it to use.
22086        // If our app is currently cached, we know it, and that is it.  Otherwise,
22087        // we don't know it yet, and it needs to now be cached we will then
22088        // need to do a complete oom adj.
22089        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22090                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22091        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22092                SystemClock.uptimeMillis());
22093        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
22094            // Changed to/from cached state, so apps after it in the LRU
22095            // list may also be changed.
22096            updateOomAdjLocked();
22097        }
22098        return success;
22099    }
22100
22101    final void updateOomAdjLocked() {
22102        final ActivityRecord TOP_ACT = resumedAppLocked();
22103        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22104        final long now = SystemClock.uptimeMillis();
22105        final long nowElapsed = SystemClock.elapsedRealtime();
22106        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22107        final int N = mLruProcesses.size();
22108
22109        if (false) {
22110            RuntimeException e = new RuntimeException();
22111            e.fillInStackTrace();
22112            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22113        }
22114
22115        // Reset state in all uid records.
22116        for (int i=mActiveUids.size()-1; i>=0; i--) {
22117            final UidRecord uidRec = mActiveUids.valueAt(i);
22118            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22119                    "Starting update of " + uidRec);
22120            uidRec.reset();
22121        }
22122
22123        mStackSupervisor.rankTaskLayersIfNeeded();
22124
22125        mAdjSeq++;
22126        mNewNumServiceProcs = 0;
22127        mNewNumAServiceProcs = 0;
22128
22129        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22130        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22131
22132        // Let's determine how many processes we have running vs.
22133        // how many slots we have for background processes; we may want
22134        // to put multiple processes in a slot of there are enough of
22135        // them.
22136        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22137                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22138        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22139        if (numEmptyProcs > cachedProcessLimit) {
22140            // If there are more empty processes than our limit on cached
22141            // processes, then use the cached process limit for the factor.
22142            // This ensures that the really old empty processes get pushed
22143            // down to the bottom, so if we are running low on memory we will
22144            // have a better chance at keeping around more cached processes
22145            // instead of a gazillion empty processes.
22146            numEmptyProcs = cachedProcessLimit;
22147        }
22148        int emptyFactor = numEmptyProcs/numSlots;
22149        if (emptyFactor < 1) emptyFactor = 1;
22150        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22151        if (cachedFactor < 1) cachedFactor = 1;
22152        int stepCached = 0;
22153        int stepEmpty = 0;
22154        int numCached = 0;
22155        int numEmpty = 0;
22156        int numTrimming = 0;
22157
22158        mNumNonCachedProcs = 0;
22159        mNumCachedHiddenProcs = 0;
22160
22161        // First update the OOM adjustment for each of the
22162        // application processes based on their current state.
22163        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22164        int nextCachedAdj = curCachedAdj+1;
22165        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22166        int nextEmptyAdj = curEmptyAdj+2;
22167        for (int i=N-1; i>=0; i--) {
22168            ProcessRecord app = mLruProcesses.get(i);
22169            if (!app.killedByAm && app.thread != null) {
22170                app.procStateChanged = false;
22171                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22172
22173                // If we haven't yet assigned the final cached adj
22174                // to the process, do that now.
22175                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22176                    switch (app.curProcState) {
22177                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22178                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22179                            // This process is a cached process holding activities...
22180                            // assign it the next cached value for that type, and then
22181                            // step that cached level.
22182                            app.curRawAdj = curCachedAdj;
22183                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22184                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22185                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22186                                    + ")");
22187                            if (curCachedAdj != nextCachedAdj) {
22188                                stepCached++;
22189                                if (stepCached >= cachedFactor) {
22190                                    stepCached = 0;
22191                                    curCachedAdj = nextCachedAdj;
22192                                    nextCachedAdj += 2;
22193                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22194                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22195                                    }
22196                                }
22197                            }
22198                            break;
22199                        default:
22200                            // For everything else, assign next empty cached process
22201                            // level and bump that up.  Note that this means that
22202                            // long-running services that have dropped down to the
22203                            // cached level will be treated as empty (since their process
22204                            // state is still as a service), which is what we want.
22205                            app.curRawAdj = curEmptyAdj;
22206                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22207                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22208                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22209                                    + ")");
22210                            if (curEmptyAdj != nextEmptyAdj) {
22211                                stepEmpty++;
22212                                if (stepEmpty >= emptyFactor) {
22213                                    stepEmpty = 0;
22214                                    curEmptyAdj = nextEmptyAdj;
22215                                    nextEmptyAdj += 2;
22216                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22217                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22218                                    }
22219                                }
22220                            }
22221                            break;
22222                    }
22223                }
22224
22225                applyOomAdjLocked(app, true, now, nowElapsed);
22226
22227                // Count the number of process types.
22228                switch (app.curProcState) {
22229                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22230                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22231                        mNumCachedHiddenProcs++;
22232                        numCached++;
22233                        if (numCached > cachedProcessLimit) {
22234                            app.kill("cached #" + numCached, true);
22235                        }
22236                        break;
22237                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22238                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22239                                && app.lastActivityTime < oldTime) {
22240                            app.kill("empty for "
22241                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22242                                    / 1000) + "s", true);
22243                        } else {
22244                            numEmpty++;
22245                            if (numEmpty > emptyProcessLimit) {
22246                                app.kill("empty #" + numEmpty, true);
22247                            }
22248                        }
22249                        break;
22250                    default:
22251                        mNumNonCachedProcs++;
22252                        break;
22253                }
22254
22255                if (app.isolated && app.services.size() <= 0) {
22256                    // If this is an isolated process, and there are no
22257                    // services running in it, then the process is no longer
22258                    // needed.  We agressively kill these because we can by
22259                    // definition not re-use the same process again, and it is
22260                    // good to avoid having whatever code was running in them
22261                    // left sitting around after no longer needed.
22262                    app.kill("isolated not needed", true);
22263                } else {
22264                    // Keeping this process, update its uid.
22265                    final UidRecord uidRec = app.uidRecord;
22266                    if (uidRec != null) {
22267                        uidRec.ephemeral = app.info.isInstantApp();
22268                        if (uidRec.curProcState > app.curProcState) {
22269                            uidRec.curProcState = app.curProcState;
22270                        }
22271                    }
22272                }
22273
22274                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22275                        && !app.killedByAm) {
22276                    numTrimming++;
22277                }
22278            }
22279        }
22280
22281        incrementProcStateSeqAndNotifyAppsLocked();
22282
22283        mNumServiceProcs = mNewNumServiceProcs;
22284
22285        // Now determine the memory trimming level of background processes.
22286        // Unfortunately we need to start at the back of the list to do this
22287        // properly.  We only do this if the number of background apps we
22288        // are managing to keep around is less than half the maximum we desire;
22289        // if we are keeping a good number around, we'll let them use whatever
22290        // memory they want.
22291        final int numCachedAndEmpty = numCached + numEmpty;
22292        int memFactor;
22293        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22294                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22295            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22296                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22297            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22298                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22299            } else {
22300                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22301            }
22302        } else {
22303            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22304        }
22305        // We always allow the memory level to go up (better).  We only allow it to go
22306        // down if we are in a state where that is allowed, *and* the total number of processes
22307        // has gone down since last time.
22308        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22309                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22310                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22311        if (memFactor > mLastMemoryLevel) {
22312            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22313                memFactor = mLastMemoryLevel;
22314                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22315            }
22316        }
22317        if (memFactor != mLastMemoryLevel) {
22318            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22319        }
22320        mLastMemoryLevel = memFactor;
22321        mLastNumProcesses = mLruProcesses.size();
22322        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22323        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22324        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22325            if (mLowRamStartTime == 0) {
22326                mLowRamStartTime = now;
22327            }
22328            int step = 0;
22329            int fgTrimLevel;
22330            switch (memFactor) {
22331                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22332                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22333                    break;
22334                case ProcessStats.ADJ_MEM_FACTOR_LOW:
22335                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22336                    break;
22337                default:
22338                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22339                    break;
22340            }
22341            int factor = numTrimming/3;
22342            int minFactor = 2;
22343            if (mHomeProcess != null) minFactor++;
22344            if (mPreviousProcess != null) minFactor++;
22345            if (factor < minFactor) factor = minFactor;
22346            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22347            for (int i=N-1; i>=0; i--) {
22348                ProcessRecord app = mLruProcesses.get(i);
22349                if (allChanged || app.procStateChanged) {
22350                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22351                    app.procStateChanged = false;
22352                }
22353                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22354                        && !app.killedByAm) {
22355                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
22356                        try {
22357                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22358                                    "Trimming memory of " + app.processName + " to " + curLevel);
22359                            app.thread.scheduleTrimMemory(curLevel);
22360                        } catch (RemoteException e) {
22361                        }
22362                        if (false) {
22363                            // For now we won't do this; our memory trimming seems
22364                            // to be good enough at this point that destroying
22365                            // activities causes more harm than good.
22366                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22367                                    && app != mHomeProcess && app != mPreviousProcess) {
22368                                // Need to do this on its own message because the stack may not
22369                                // be in a consistent state at this point.
22370                                // For these apps we will also finish their activities
22371                                // to help them free memory.
22372                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22373                            }
22374                        }
22375                    }
22376                    app.trimMemoryLevel = curLevel;
22377                    step++;
22378                    if (step >= factor) {
22379                        step = 0;
22380                        switch (curLevel) {
22381                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22382                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22383                                break;
22384                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22385                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22386                                break;
22387                        }
22388                    }
22389                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22390                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22391                            && app.thread != null) {
22392                        try {
22393                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22394                                    "Trimming memory of heavy-weight " + app.processName
22395                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22396                            app.thread.scheduleTrimMemory(
22397                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22398                        } catch (RemoteException e) {
22399                        }
22400                    }
22401                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22402                } else {
22403                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22404                            || app.systemNoUi) && app.pendingUiClean) {
22405                        // If this application is now in the background and it
22406                        // had done UI, then give it the special trim level to
22407                        // have it free UI resources.
22408                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22409                        if (app.trimMemoryLevel < level && app.thread != null) {
22410                            try {
22411                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22412                                        "Trimming memory of bg-ui " + app.processName
22413                                        + " to " + level);
22414                                app.thread.scheduleTrimMemory(level);
22415                            } catch (RemoteException e) {
22416                            }
22417                        }
22418                        app.pendingUiClean = false;
22419                    }
22420                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22421                        try {
22422                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22423                                    "Trimming memory of fg " + app.processName
22424                                    + " to " + fgTrimLevel);
22425                            app.thread.scheduleTrimMemory(fgTrimLevel);
22426                        } catch (RemoteException e) {
22427                        }
22428                    }
22429                    app.trimMemoryLevel = fgTrimLevel;
22430                }
22431            }
22432        } else {
22433            if (mLowRamStartTime != 0) {
22434                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22435                mLowRamStartTime = 0;
22436            }
22437            for (int i=N-1; i>=0; i--) {
22438                ProcessRecord app = mLruProcesses.get(i);
22439                if (allChanged || app.procStateChanged) {
22440                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22441                    app.procStateChanged = false;
22442                }
22443                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22444                        || app.systemNoUi) && app.pendingUiClean) {
22445                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22446                            && app.thread != null) {
22447                        try {
22448                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22449                                    "Trimming memory of ui hidden " + app.processName
22450                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22451                            app.thread.scheduleTrimMemory(
22452                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22453                        } catch (RemoteException e) {
22454                        }
22455                    }
22456                    app.pendingUiClean = false;
22457                }
22458                app.trimMemoryLevel = 0;
22459            }
22460        }
22461
22462        if (mAlwaysFinishActivities) {
22463            // Need to do this on its own message because the stack may not
22464            // be in a consistent state at this point.
22465            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22466        }
22467
22468        if (allChanged) {
22469            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22470        }
22471
22472        // Update from any uid changes.
22473        if (mLocalPowerManager != null) {
22474            mLocalPowerManager.startUidChanges();
22475        }
22476        for (int i=mActiveUids.size()-1; i>=0; i--) {
22477            final UidRecord uidRec = mActiveUids.valueAt(i);
22478            int uidChange = UidRecord.CHANGE_PROCSTATE;
22479            if (uidRec.setProcState != uidRec.curProcState
22480                    || uidRec.setWhitelist != uidRec.curWhitelist) {
22481                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22482                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22483                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22484                        + " to " + uidRec.curWhitelist);
22485                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22486                        && !uidRec.curWhitelist) {
22487                    // UID is now in the background (and not on the temp whitelist).  Was it
22488                    // previously in the foreground (or on the temp whitelist)?
22489                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22490                            || uidRec.setWhitelist) {
22491                        uidRec.lastBackgroundTime = nowElapsed;
22492                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22493                            // Note: the background settle time is in elapsed realtime, while
22494                            // the handler time base is uptime.  All this means is that we may
22495                            // stop background uids later than we had intended, but that only
22496                            // happens because the device was sleeping so we are okay anyway.
22497                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
22498                        }
22499                    }
22500                } else {
22501                    if (uidRec.idle) {
22502                        uidChange = UidRecord.CHANGE_ACTIVE;
22503                        uidRec.idle = false;
22504                    }
22505                    uidRec.lastBackgroundTime = 0;
22506                }
22507                uidRec.setProcState = uidRec.curProcState;
22508                uidRec.setWhitelist = uidRec.curWhitelist;
22509                enqueueUidChangeLocked(uidRec, -1, uidChange);
22510                noteUidProcessState(uidRec.uid, uidRec.curProcState);
22511            }
22512        }
22513        if (mLocalPowerManager != null) {
22514            mLocalPowerManager.finishUidChanges();
22515        }
22516
22517        if (mProcessStats.shouldWriteNowLocked(now)) {
22518            mHandler.post(new Runnable() {
22519                @Override public void run() {
22520                    synchronized (ActivityManagerService.this) {
22521                        mProcessStats.writeStateAsyncLocked();
22522                    }
22523                }
22524            });
22525        }
22526
22527        if (DEBUG_OOM_ADJ) {
22528            final long duration = SystemClock.uptimeMillis() - now;
22529            if (false) {
22530                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22531                        new RuntimeException("here").fillInStackTrace());
22532            } else {
22533                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22534            }
22535        }
22536    }
22537
22538    @Override
22539    public void makePackageIdle(String packageName, int userId) {
22540        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22541                != PackageManager.PERMISSION_GRANTED) {
22542            String msg = "Permission Denial: makePackageIdle() from pid="
22543                    + Binder.getCallingPid()
22544                    + ", uid=" + Binder.getCallingUid()
22545                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22546            Slog.w(TAG, msg);
22547            throw new SecurityException(msg);
22548        }
22549        final int callingPid = Binder.getCallingPid();
22550        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22551                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22552        long callingId = Binder.clearCallingIdentity();
22553        synchronized(this) {
22554            try {
22555                IPackageManager pm = AppGlobals.getPackageManager();
22556                int pkgUid = -1;
22557                try {
22558                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22559                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22560                } catch (RemoteException e) {
22561                }
22562                if (pkgUid == -1) {
22563                    throw new IllegalArgumentException("Unknown package name " + packageName);
22564                }
22565
22566                if (mLocalPowerManager != null) {
22567                    mLocalPowerManager.startUidChanges();
22568                }
22569                final int appId = UserHandle.getAppId(pkgUid);
22570                final int N = mActiveUids.size();
22571                for (int i=N-1; i>=0; i--) {
22572                    final UidRecord uidRec = mActiveUids.valueAt(i);
22573                    final long bgTime = uidRec.lastBackgroundTime;
22574                    if (bgTime > 0 && !uidRec.idle) {
22575                        if (UserHandle.getAppId(uidRec.uid) == appId) {
22576                            if (userId == UserHandle.USER_ALL ||
22577                                    userId == UserHandle.getUserId(uidRec.uid)) {
22578                                uidRec.idle = true;
22579                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22580                                        + " from package " + packageName + " user " + userId);
22581                                doStopUidLocked(uidRec.uid, uidRec);
22582                            }
22583                        }
22584                    }
22585                }
22586            } finally {
22587                if (mLocalPowerManager != null) {
22588                    mLocalPowerManager.finishUidChanges();
22589                }
22590                Binder.restoreCallingIdentity(callingId);
22591            }
22592        }
22593    }
22594
22595    final void idleUids() {
22596        synchronized (this) {
22597            final int N = mActiveUids.size();
22598            if (N <= 0) {
22599                return;
22600            }
22601            final long nowElapsed = SystemClock.elapsedRealtime();
22602            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
22603            long nextTime = 0;
22604            if (mLocalPowerManager != null) {
22605                mLocalPowerManager.startUidChanges();
22606            }
22607            for (int i=N-1; i>=0; i--) {
22608                final UidRecord uidRec = mActiveUids.valueAt(i);
22609                final long bgTime = uidRec.lastBackgroundTime;
22610                if (bgTime > 0 && !uidRec.idle) {
22611                    if (bgTime <= maxBgTime) {
22612                        uidRec.idle = true;
22613                        doStopUidLocked(uidRec.uid, uidRec);
22614                    } else {
22615                        if (nextTime == 0 || nextTime > bgTime) {
22616                            nextTime = bgTime;
22617                        }
22618                    }
22619                }
22620            }
22621            if (mLocalPowerManager != null) {
22622                mLocalPowerManager.finishUidChanges();
22623            }
22624            if (nextTime > 0) {
22625                mHandler.removeMessages(IDLE_UIDS_MSG);
22626                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22627                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
22628            }
22629        }
22630    }
22631
22632    /**
22633     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
22634     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
22635     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
22636     */
22637    @VisibleForTesting
22638    @GuardedBy("this")
22639    void incrementProcStateSeqAndNotifyAppsLocked() {
22640        if (mWaitForNetworkTimeoutMs <= 0) {
22641            return;
22642        }
22643        // Used for identifying which uids need to block for network.
22644        ArrayList<Integer> blockingUids = null;
22645        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
22646            final UidRecord uidRec = mActiveUids.valueAt(i);
22647            // If the network is not restricted for uid, then nothing to do here.
22648            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
22649                continue;
22650            }
22651            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
22652                continue;
22653            }
22654            // If process state is not changed, then there's nothing to do.
22655            if (uidRec.setProcState == uidRec.curProcState) {
22656                continue;
22657            }
22658            final int blockState = getBlockStateForUid(uidRec);
22659            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
22660            // there's nothing the app needs to do in this scenario.
22661            if (blockState == NETWORK_STATE_NO_CHANGE) {
22662                continue;
22663            }
22664            synchronized (uidRec.networkStateLock) {
22665                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
22666                if (blockState == NETWORK_STATE_BLOCK) {
22667                    if (blockingUids == null) {
22668                        blockingUids = new ArrayList<>();
22669                    }
22670                    blockingUids.add(uidRec.uid);
22671                } else {
22672                    if (DEBUG_NETWORK) {
22673                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
22674                                + " threads for uid: " + uidRec);
22675                    }
22676                    if (uidRec.waitingForNetwork) {
22677                        uidRec.networkStateLock.notifyAll();
22678                    }
22679                }
22680            }
22681        }
22682
22683        // There are no uids that need to block, so nothing more to do.
22684        if (blockingUids == null) {
22685            return;
22686        }
22687
22688        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
22689            final ProcessRecord app = mLruProcesses.get(i);
22690            if (!blockingUids.contains(app.uid)) {
22691                continue;
22692            }
22693            if (!app.killedByAm && app.thread != null) {
22694                final UidRecord uidRec = mActiveUids.get(app.uid);
22695                try {
22696                    if (DEBUG_NETWORK) {
22697                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
22698                                + uidRec);
22699                    }
22700                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
22701                } catch (RemoteException ignored) {
22702                }
22703            }
22704        }
22705    }
22706
22707    /**
22708     * Checks if the uid is coming from background to foreground or vice versa and returns
22709     * appropriate block state based on this.
22710     *
22711     * @return blockState based on whether the uid is coming from background to foreground or
22712     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
22713     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
22714     *         {@link #NETWORK_STATE_NO_CHANGE}.
22715     */
22716    @VisibleForTesting
22717    int getBlockStateForUid(UidRecord uidRec) {
22718        // Denotes whether uid's process state is currently allowed network access.
22719        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
22720                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
22721        // Denotes whether uid's process state was previously allowed network access.
22722        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
22723                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
22724
22725        // When the uid is coming to foreground, AMS should inform the app thread that it should
22726        // block for the network rules to get updated before launching an activity.
22727        if (!wasAllowed && isAllowed) {
22728            return NETWORK_STATE_BLOCK;
22729        }
22730        // When the uid is going to background, AMS should inform the app thread that if an
22731        // activity launch is blocked for the network rules to get updated, it should be unblocked.
22732        if (wasAllowed && !isAllowed) {
22733            return NETWORK_STATE_UNBLOCK;
22734        }
22735        return NETWORK_STATE_NO_CHANGE;
22736    }
22737
22738    final void runInBackgroundDisabled(int uid) {
22739        synchronized (this) {
22740            UidRecord uidRec = mActiveUids.get(uid);
22741            if (uidRec != null) {
22742                // This uid is actually running...  should it be considered background now?
22743                if (uidRec.idle) {
22744                    doStopUidLocked(uidRec.uid, uidRec);
22745                }
22746            } else {
22747                // This uid isn't actually running...  still send a report about it being "stopped".
22748                doStopUidLocked(uid, null);
22749            }
22750        }
22751    }
22752
22753    final void doStopUidLocked(int uid, final UidRecord uidRec) {
22754        mServices.stopInBackgroundLocked(uid);
22755        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
22756    }
22757
22758    /**
22759     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
22760     */
22761    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
22762            long duration, String tag) {
22763        if (DEBUG_WHITELISTS) {
22764            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
22765                    + targetUid + ", " + duration + ")");
22766        }
22767
22768        synchronized (mPidsSelfLocked) {
22769            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
22770            if (pr == null) {
22771                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
22772                        + callerPid);
22773                return;
22774            }
22775            if (!pr.whitelistManager) {
22776                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
22777                        != PackageManager.PERMISSION_GRANTED) {
22778                    if (DEBUG_WHITELISTS) {
22779                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
22780                                + ": pid " + callerPid + " is not allowed");
22781                    }
22782                    return;
22783                }
22784            }
22785        }
22786
22787        tempWhitelistUidLocked(targetUid, duration, tag);
22788    }
22789
22790    /**
22791     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
22792     */
22793    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
22794        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
22795        setUidTempWhitelistStateLocked(targetUid, true);
22796        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
22797    }
22798
22799    void pushTempWhitelist() {
22800        final int N;
22801        final PendingTempWhitelist[] list;
22802
22803        // First copy out the pending changes...  we need to leave them in the map for now,
22804        // in case someone needs to check what is coming up while we don't have the lock held.
22805        synchronized(this) {
22806            N = mPendingTempWhitelist.size();
22807            list = new PendingTempWhitelist[N];
22808            for (int i = 0; i < N; i++) {
22809                list[i] = mPendingTempWhitelist.valueAt(i);
22810            }
22811        }
22812
22813        // Now safely dispatch changes to device idle controller.
22814        for (int i = 0; i < N; i++) {
22815            PendingTempWhitelist ptw = list[i];
22816            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
22817                    ptw.duration, true, ptw.tag);
22818        }
22819
22820        // And now we can safely remove them from the map.
22821        synchronized(this) {
22822            for (int i = 0; i < N; i++) {
22823                PendingTempWhitelist ptw = list[i];
22824                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
22825                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
22826                    mPendingTempWhitelist.removeAt(index);
22827                }
22828            }
22829        }
22830    }
22831
22832    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
22833        boolean changed = false;
22834        for (int i=mActiveUids.size()-1; i>=0; i--) {
22835            final UidRecord uidRec = mActiveUids.valueAt(i);
22836            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
22837                uidRec.curWhitelist = onWhitelist;
22838                changed = true;
22839            }
22840        }
22841        if (changed) {
22842            updateOomAdjLocked();
22843        }
22844    }
22845
22846    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
22847        boolean changed = false;
22848        final UidRecord uidRec = mActiveUids.get(uid);
22849        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
22850            uidRec.curWhitelist = onWhitelist;
22851            updateOomAdjLocked();
22852        }
22853    }
22854
22855    final void trimApplications() {
22856        synchronized (this) {
22857            int i;
22858
22859            // First remove any unused application processes whose package
22860            // has been removed.
22861            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
22862                final ProcessRecord app = mRemovedProcesses.get(i);
22863                if (app.activities.size() == 0
22864                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
22865                    Slog.i(
22866                        TAG, "Exiting empty application process "
22867                        + app.toShortString() + " ("
22868                        + (app.thread != null ? app.thread.asBinder() : null)
22869                        + ")\n");
22870                    if (app.pid > 0 && app.pid != MY_PID) {
22871                        app.kill("empty", false);
22872                    } else {
22873                        try {
22874                            app.thread.scheduleExit();
22875                        } catch (Exception e) {
22876                            // Ignore exceptions.
22877                        }
22878                    }
22879                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
22880                    mRemovedProcesses.remove(i);
22881
22882                    if (app.persistent) {
22883                        addAppLocked(app.info, null, false, null /* ABI override */);
22884                    }
22885                }
22886            }
22887
22888            // Now update the oom adj for all processes.
22889            updateOomAdjLocked();
22890        }
22891    }
22892
22893    /** This method sends the specified signal to each of the persistent apps */
22894    public void signalPersistentProcesses(int sig) throws RemoteException {
22895        if (sig != SIGNAL_USR1) {
22896            throw new SecurityException("Only SIGNAL_USR1 is allowed");
22897        }
22898
22899        synchronized (this) {
22900            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
22901                    != PackageManager.PERMISSION_GRANTED) {
22902                throw new SecurityException("Requires permission "
22903                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
22904            }
22905
22906            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
22907                ProcessRecord r = mLruProcesses.get(i);
22908                if (r.thread != null && r.persistent) {
22909                    sendSignal(r.pid, sig);
22910                }
22911            }
22912        }
22913    }
22914
22915    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
22916        if (proc == null || proc == mProfileProc) {
22917            proc = mProfileProc;
22918            profileType = mProfileType;
22919            clearProfilerLocked();
22920        }
22921        if (proc == null) {
22922            return;
22923        }
22924        try {
22925            proc.thread.profilerControl(false, null, profileType);
22926        } catch (RemoteException e) {
22927            throw new IllegalStateException("Process disappeared");
22928        }
22929    }
22930
22931    private void clearProfilerLocked() {
22932        if (mProfileFd != null) {
22933            try {
22934                mProfileFd.close();
22935            } catch (IOException e) {
22936            }
22937        }
22938        mProfileApp = null;
22939        mProfileProc = null;
22940        mProfileFile = null;
22941        mProfileType = 0;
22942        mAutoStopProfiler = false;
22943        mStreamingOutput = false;
22944        mSamplingInterval = 0;
22945    }
22946
22947    public boolean profileControl(String process, int userId, boolean start,
22948            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
22949
22950        try {
22951            synchronized (this) {
22952                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
22953                // its own permission.
22954                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22955                        != PackageManager.PERMISSION_GRANTED) {
22956                    throw new SecurityException("Requires permission "
22957                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22958                }
22959
22960                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
22961                    throw new IllegalArgumentException("null profile info or fd");
22962                }
22963
22964                ProcessRecord proc = null;
22965                if (process != null) {
22966                    proc = findProcessLocked(process, userId, "profileControl");
22967                }
22968
22969                if (start && (proc == null || proc.thread == null)) {
22970                    throw new IllegalArgumentException("Unknown process: " + process);
22971                }
22972
22973                if (start) {
22974                    stopProfilerLocked(null, 0);
22975                    setProfileApp(proc.info, proc.processName, profilerInfo);
22976                    mProfileProc = proc;
22977                    mProfileType = profileType;
22978                    ParcelFileDescriptor fd = profilerInfo.profileFd;
22979                    try {
22980                        fd = fd.dup();
22981                    } catch (IOException e) {
22982                        fd = null;
22983                    }
22984                    profilerInfo.profileFd = fd;
22985                    proc.thread.profilerControl(start, profilerInfo, profileType);
22986                    fd = null;
22987                    try {
22988                        mProfileFd.close();
22989                    } catch (IOException e) {
22990                    }
22991                    mProfileFd = null;
22992                } else {
22993                    stopProfilerLocked(proc, profileType);
22994                    if (profilerInfo != null && profilerInfo.profileFd != null) {
22995                        try {
22996                            profilerInfo.profileFd.close();
22997                        } catch (IOException e) {
22998                        }
22999                    }
23000                }
23001
23002                return true;
23003            }
23004        } catch (RemoteException e) {
23005            throw new IllegalStateException("Process disappeared");
23006        } finally {
23007            if (profilerInfo != null && profilerInfo.profileFd != null) {
23008                try {
23009                    profilerInfo.profileFd.close();
23010                } catch (IOException e) {
23011                }
23012            }
23013        }
23014    }
23015
23016    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23017        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23018                userId, true, ALLOW_FULL_ONLY, callName, null);
23019        ProcessRecord proc = null;
23020        try {
23021            int pid = Integer.parseInt(process);
23022            synchronized (mPidsSelfLocked) {
23023                proc = mPidsSelfLocked.get(pid);
23024            }
23025        } catch (NumberFormatException e) {
23026        }
23027
23028        if (proc == null) {
23029            ArrayMap<String, SparseArray<ProcessRecord>> all
23030                    = mProcessNames.getMap();
23031            SparseArray<ProcessRecord> procs = all.get(process);
23032            if (procs != null && procs.size() > 0) {
23033                proc = procs.valueAt(0);
23034                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23035                    for (int i=1; i<procs.size(); i++) {
23036                        ProcessRecord thisProc = procs.valueAt(i);
23037                        if (thisProc.userId == userId) {
23038                            proc = thisProc;
23039                            break;
23040                        }
23041                    }
23042                }
23043            }
23044        }
23045
23046        return proc;
23047    }
23048
23049    public boolean dumpHeap(String process, int userId, boolean managed,
23050            String path, ParcelFileDescriptor fd) throws RemoteException {
23051
23052        try {
23053            synchronized (this) {
23054                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23055                // its own permission (same as profileControl).
23056                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23057                        != PackageManager.PERMISSION_GRANTED) {
23058                    throw new SecurityException("Requires permission "
23059                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23060                }
23061
23062                if (fd == null) {
23063                    throw new IllegalArgumentException("null fd");
23064                }
23065
23066                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23067                if (proc == null || proc.thread == null) {
23068                    throw new IllegalArgumentException("Unknown process: " + process);
23069                }
23070
23071                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23072                if (!isDebuggable) {
23073                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23074                        throw new SecurityException("Process not debuggable: " + proc);
23075                    }
23076                }
23077
23078                proc.thread.dumpHeap(managed, path, fd);
23079                fd = null;
23080                return true;
23081            }
23082        } catch (RemoteException e) {
23083            throw new IllegalStateException("Process disappeared");
23084        } finally {
23085            if (fd != null) {
23086                try {
23087                    fd.close();
23088                } catch (IOException e) {
23089                }
23090            }
23091        }
23092    }
23093
23094    @Override
23095    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23096            String reportPackage) {
23097        if (processName != null) {
23098            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23099                    "setDumpHeapDebugLimit()");
23100        } else {
23101            synchronized (mPidsSelfLocked) {
23102                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23103                if (proc == null) {
23104                    throw new SecurityException("No process found for calling pid "
23105                            + Binder.getCallingPid());
23106                }
23107                if (!Build.IS_DEBUGGABLE
23108                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23109                    throw new SecurityException("Not running a debuggable build");
23110                }
23111                processName = proc.processName;
23112                uid = proc.uid;
23113                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23114                    throw new SecurityException("Package " + reportPackage + " is not running in "
23115                            + proc);
23116                }
23117            }
23118        }
23119        synchronized (this) {
23120            if (maxMemSize > 0) {
23121                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23122            } else {
23123                if (uid != 0) {
23124                    mMemWatchProcesses.remove(processName, uid);
23125                } else {
23126                    mMemWatchProcesses.getMap().remove(processName);
23127                }
23128            }
23129        }
23130    }
23131
23132    @Override
23133    public void dumpHeapFinished(String path) {
23134        synchronized (this) {
23135            if (Binder.getCallingPid() != mMemWatchDumpPid) {
23136                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23137                        + " does not match last pid " + mMemWatchDumpPid);
23138                return;
23139            }
23140            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23141                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23142                        + " does not match last path " + mMemWatchDumpFile);
23143                return;
23144            }
23145            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23146            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23147        }
23148    }
23149
23150    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23151    public void monitor() {
23152        synchronized (this) { }
23153    }
23154
23155    void onCoreSettingsChange(Bundle settings) {
23156        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23157            ProcessRecord processRecord = mLruProcesses.get(i);
23158            try {
23159                if (processRecord.thread != null) {
23160                    processRecord.thread.setCoreSettings(settings);
23161                }
23162            } catch (RemoteException re) {
23163                /* ignore */
23164            }
23165        }
23166    }
23167
23168    // Multi-user methods
23169
23170    /**
23171     * Start user, if its not already running, but don't bring it to foreground.
23172     */
23173    @Override
23174    public boolean startUserInBackground(final int userId) {
23175        return mUserController.startUser(userId, /* foreground */ false);
23176    }
23177
23178    @Override
23179    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23180        return mUserController.unlockUser(userId, token, secret, listener);
23181    }
23182
23183    @Override
23184    public boolean switchUser(final int targetUserId) {
23185        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23186        int currentUserId;
23187        UserInfo targetUserInfo;
23188        synchronized (this) {
23189            currentUserId = mUserController.getCurrentUserIdLocked();
23190            targetUserInfo = mUserController.getUserInfo(targetUserId);
23191            if (targetUserId == currentUserId) {
23192                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23193                return true;
23194            }
23195            if (targetUserInfo == null) {
23196                Slog.w(TAG, "No user info for user #" + targetUserId);
23197                return false;
23198            }
23199            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23200                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23201                        + " when device is in demo mode");
23202                return false;
23203            }
23204            if (!targetUserInfo.supportsSwitchTo()) {
23205                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23206                return false;
23207            }
23208            if (targetUserInfo.isManagedProfile()) {
23209                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23210                return false;
23211            }
23212            mUserController.setTargetUserIdLocked(targetUserId);
23213        }
23214        if (mUserController.mUserSwitchUiEnabled) {
23215            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23216            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23217            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23218            mUiHandler.sendMessage(mHandler.obtainMessage(
23219                    START_USER_SWITCH_UI_MSG, userNames));
23220        } else {
23221            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23222            mHandler.sendMessage(mHandler.obtainMessage(
23223                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
23224        }
23225        return true;
23226    }
23227
23228    void scheduleStartProfilesLocked() {
23229        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23230            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23231                    DateUtils.SECOND_IN_MILLIS);
23232        }
23233    }
23234
23235    @Override
23236    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23237        return mUserController.stopUser(userId, force, callback);
23238    }
23239
23240    @Override
23241    public UserInfo getCurrentUser() {
23242        return mUserController.getCurrentUser();
23243    }
23244
23245    String getStartedUserState(int userId) {
23246        synchronized (this) {
23247            final UserState userState = mUserController.getStartedUserStateLocked(userId);
23248            return UserState.stateToString(userState.state);
23249        }
23250    }
23251
23252    @Override
23253    public boolean isUserRunning(int userId, int flags) {
23254        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23255                && checkCallingPermission(INTERACT_ACROSS_USERS)
23256                    != PackageManager.PERMISSION_GRANTED) {
23257            String msg = "Permission Denial: isUserRunning() from pid="
23258                    + Binder.getCallingPid()
23259                    + ", uid=" + Binder.getCallingUid()
23260                    + " requires " + INTERACT_ACROSS_USERS;
23261            Slog.w(TAG, msg);
23262            throw new SecurityException(msg);
23263        }
23264        synchronized (this) {
23265            return mUserController.isUserRunningLocked(userId, flags);
23266        }
23267    }
23268
23269    @Override
23270    public int[] getRunningUserIds() {
23271        if (checkCallingPermission(INTERACT_ACROSS_USERS)
23272                != PackageManager.PERMISSION_GRANTED) {
23273            String msg = "Permission Denial: isUserRunning() from pid="
23274                    + Binder.getCallingPid()
23275                    + ", uid=" + Binder.getCallingUid()
23276                    + " requires " + INTERACT_ACROSS_USERS;
23277            Slog.w(TAG, msg);
23278            throw new SecurityException(msg);
23279        }
23280        synchronized (this) {
23281            return mUserController.getStartedUserArrayLocked();
23282        }
23283    }
23284
23285    @Override
23286    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23287        mUserController.registerUserSwitchObserver(observer, name);
23288    }
23289
23290    @Override
23291    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23292        mUserController.unregisterUserSwitchObserver(observer);
23293    }
23294
23295    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23296        if (info == null) return null;
23297        ApplicationInfo newInfo = new ApplicationInfo(info);
23298        newInfo.initForUser(userId);
23299        return newInfo;
23300    }
23301
23302    public boolean isUserStopped(int userId) {
23303        synchronized (this) {
23304            return mUserController.getStartedUserStateLocked(userId) == null;
23305        }
23306    }
23307
23308    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23309        if (aInfo == null
23310                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23311            return aInfo;
23312        }
23313
23314        ActivityInfo info = new ActivityInfo(aInfo);
23315        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23316        return info;
23317    }
23318
23319    private boolean processSanityChecksLocked(ProcessRecord process) {
23320        if (process == null || process.thread == null) {
23321            return false;
23322        }
23323
23324        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23325        if (!isDebuggable) {
23326            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23327                return false;
23328            }
23329        }
23330
23331        return true;
23332    }
23333
23334    public boolean startBinderTracking() throws RemoteException {
23335        synchronized (this) {
23336            mBinderTransactionTrackingEnabled = true;
23337            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23338            // permission (same as profileControl).
23339            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23340                    != PackageManager.PERMISSION_GRANTED) {
23341                throw new SecurityException("Requires permission "
23342                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23343            }
23344
23345            for (int i = 0; i < mLruProcesses.size(); i++) {
23346                ProcessRecord process = mLruProcesses.get(i);
23347                if (!processSanityChecksLocked(process)) {
23348                    continue;
23349                }
23350                try {
23351                    process.thread.startBinderTracking();
23352                } catch (RemoteException e) {
23353                    Log.v(TAG, "Process disappared");
23354                }
23355            }
23356            return true;
23357        }
23358    }
23359
23360    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23361        try {
23362            synchronized (this) {
23363                mBinderTransactionTrackingEnabled = false;
23364                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23365                // permission (same as profileControl).
23366                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23367                        != PackageManager.PERMISSION_GRANTED) {
23368                    throw new SecurityException("Requires permission "
23369                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23370                }
23371
23372                if (fd == null) {
23373                    throw new IllegalArgumentException("null fd");
23374                }
23375
23376                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23377                pw.println("Binder transaction traces for all processes.\n");
23378                for (ProcessRecord process : mLruProcesses) {
23379                    if (!processSanityChecksLocked(process)) {
23380                        continue;
23381                    }
23382
23383                    pw.println("Traces for process: " + process.processName);
23384                    pw.flush();
23385                    try {
23386                        TransferPipe tp = new TransferPipe();
23387                        try {
23388                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23389                            tp.go(fd.getFileDescriptor());
23390                        } finally {
23391                            tp.kill();
23392                        }
23393                    } catch (IOException e) {
23394                        pw.println("Failure while dumping IPC traces from " + process +
23395                                ".  Exception: " + e);
23396                        pw.flush();
23397                    } catch (RemoteException e) {
23398                        pw.println("Got a RemoteException while dumping IPC traces from " +
23399                                process + ".  Exception: " + e);
23400                        pw.flush();
23401                    }
23402                }
23403                fd = null;
23404                return true;
23405            }
23406        } finally {
23407            if (fd != null) {
23408                try {
23409                    fd.close();
23410                } catch (IOException e) {
23411                }
23412            }
23413        }
23414    }
23415
23416    @VisibleForTesting
23417    final class LocalService extends ActivityManagerInternal {
23418        @Override
23419        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23420                int targetUserId) {
23421            synchronized (ActivityManagerService.this) {
23422                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23423                        targetPkg, intent, null, targetUserId);
23424            }
23425        }
23426
23427        @Override
23428        public String checkContentProviderAccess(String authority, int userId) {
23429            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23430        }
23431
23432        @Override
23433        public void onWakefulnessChanged(int wakefulness) {
23434            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23435        }
23436
23437        @Override
23438        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23439                String processName, String abiOverride, int uid, Runnable crashHandler) {
23440            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23441                    processName, abiOverride, uid, crashHandler);
23442        }
23443
23444        @Override
23445        public SleepToken acquireSleepToken(String tag) {
23446            Preconditions.checkNotNull(tag);
23447
23448            synchronized (ActivityManagerService.this) {
23449                SleepTokenImpl token = new SleepTokenImpl(tag);
23450                mSleepTokens.add(token);
23451                updateSleepIfNeededLocked();
23452                return token;
23453            }
23454        }
23455
23456        @Override
23457        public ComponentName getHomeActivityForUser(int userId) {
23458            synchronized (ActivityManagerService.this) {
23459                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23460                return homeActivity == null ? null : homeActivity.realActivity;
23461            }
23462        }
23463
23464        @Override
23465        public void onUserRemoved(int userId) {
23466            synchronized (ActivityManagerService.this) {
23467                ActivityManagerService.this.onUserStoppedLocked(userId);
23468            }
23469        }
23470
23471        @Override
23472        public void onLocalVoiceInteractionStarted(IBinder activity,
23473                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23474            synchronized (ActivityManagerService.this) {
23475                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23476                        voiceSession, voiceInteractor);
23477            }
23478        }
23479
23480        @Override
23481        public void notifyAppTransitionStarting(SparseIntArray reasons) {
23482            synchronized (ActivityManagerService.this) {
23483                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reasons);
23484            }
23485        }
23486
23487        @Override
23488        public void notifyAppTransitionFinished() {
23489            synchronized (ActivityManagerService.this) {
23490                mStackSupervisor.notifyAppTransitionDone();
23491            }
23492        }
23493
23494        @Override
23495        public void notifyAppTransitionCancelled() {
23496            synchronized (ActivityManagerService.this) {
23497                mStackSupervisor.notifyAppTransitionDone();
23498            }
23499        }
23500
23501        @Override
23502        public List<IBinder> getTopVisibleActivities() {
23503            synchronized (ActivityManagerService.this) {
23504                return mStackSupervisor.getTopVisibleActivities();
23505            }
23506        }
23507
23508        @Override
23509        public void notifyDockedStackMinimizedChanged(boolean minimized) {
23510            synchronized (ActivityManagerService.this) {
23511                mStackSupervisor.setDockedStackMinimized(minimized);
23512            }
23513        }
23514
23515        @Override
23516        public void killForegroundAppsForUser(int userHandle) {
23517            synchronized (ActivityManagerService.this) {
23518                final ArrayList<ProcessRecord> procs = new ArrayList<>();
23519                final int NP = mProcessNames.getMap().size();
23520                for (int ip = 0; ip < NP; ip++) {
23521                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23522                    final int NA = apps.size();
23523                    for (int ia = 0; ia < NA; ia++) {
23524                        final ProcessRecord app = apps.valueAt(ia);
23525                        if (app.persistent) {
23526                            // We don't kill persistent processes.
23527                            continue;
23528                        }
23529                        if (app.removed) {
23530                            procs.add(app);
23531                        } else if (app.userId == userHandle && app.foregroundActivities) {
23532                            app.removed = true;
23533                            procs.add(app);
23534                        }
23535                    }
23536                }
23537
23538                final int N = procs.size();
23539                for (int i = 0; i < N; i++) {
23540                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
23541                }
23542            }
23543        }
23544
23545        @Override
23546        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
23547            if (!(target instanceof PendingIntentRecord)) {
23548                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23549                return;
23550            }
23551            ((PendingIntentRecord) target).setWhitelistDurationLocked(duration);
23552        }
23553
23554        @Override
23555        public void setDeviceIdleWhitelist(int[] appids) {
23556            synchronized (ActivityManagerService.this) {
23557                mDeviceIdleWhitelist = appids;
23558            }
23559        }
23560
23561        @Override
23562        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23563            synchronized (ActivityManagerService.this) {
23564                mDeviceIdleTempWhitelist = appids;
23565                setAppIdTempWhitelistStateLocked(changingAppId, adding);
23566            }
23567        }
23568
23569        @Override
23570        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23571                int userId) {
23572            Preconditions.checkNotNull(values, "Configuration must not be null");
23573            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23574            synchronized (ActivityManagerService.this) {
23575                updateConfigurationLocked(values, null, false, true, userId,
23576                        false /* deferResume */);
23577            }
23578        }
23579
23580        @Override
23581        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23582                Bundle bOptions) {
23583            Preconditions.checkNotNull(intents, "intents");
23584            final String[] resolvedTypes = new String[intents.length];
23585            for (int i = 0; i < intents.length; i++) {
23586                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23587            }
23588
23589            // UID of the package on user userId.
23590            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23591            // packageUid may not be initialized.
23592            int packageUid = 0;
23593            try {
23594                packageUid = AppGlobals.getPackageManager().getPackageUid(
23595                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23596            } catch (RemoteException e) {
23597                // Shouldn't happen.
23598            }
23599
23600            synchronized (ActivityManagerService.this) {
23601                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23602                        /*resultTo*/ null, bOptions, userId);
23603            }
23604        }
23605
23606        @Override
23607        public int getUidProcessState(int uid) {
23608            return getUidState(uid);
23609        }
23610
23611        @Override
23612        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23613            synchronized (ActivityManagerService.this) {
23614
23615                // We might change the visibilities here, so prepare an empty app transition which
23616                // might be overridden later if we actually change visibilities.
23617                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
23618                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23619                mWindowManager.executeAppTransition();
23620            }
23621            if (callback != null) {
23622                callback.run();
23623            }
23624        }
23625
23626        @Override
23627        public boolean isSystemReady() {
23628            // no need to synchronize(this) just to read & return the value
23629            return mSystemReady;
23630        }
23631
23632        @Override
23633        public void notifyKeyguardTrustedChanged() {
23634            synchronized (ActivityManagerService.this) {
23635                if (mKeyguardController.isKeyguardShowing()) {
23636                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23637                }
23638            }
23639        }
23640
23641        /**
23642         * Sets if the given pid has an overlay UI or not.
23643         *
23644         * @param pid The pid we are setting overlay UI for.
23645         * @param hasOverlayUi True if the process has overlay UI.
23646         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
23647         */
23648        @Override
23649        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
23650            synchronized (ActivityManagerService.this) {
23651                final ProcessRecord pr;
23652                synchronized (mPidsSelfLocked) {
23653                    pr = mPidsSelfLocked.get(pid);
23654                    if (pr == null) {
23655                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
23656                        return;
23657                    }
23658                }
23659                if (pr.hasOverlayUi == hasOverlayUi) {
23660                    return;
23661                }
23662                pr.hasOverlayUi = hasOverlayUi;
23663                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
23664                updateOomAdjLocked(pr);
23665            }
23666        }
23667
23668        /**
23669         * Called after the network policy rules are updated by
23670         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
23671         * and {@param procStateSeq}.
23672         */
23673        @Override
23674        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
23675            if (DEBUG_NETWORK) {
23676                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
23677                        + uid + " seq: " + procStateSeq);
23678            }
23679            UidRecord record;
23680            synchronized (ActivityManagerService.this) {
23681                record = mActiveUids.get(uid);
23682                if (record == null) {
23683                    if (DEBUG_NETWORK) {
23684                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
23685                                + " procStateSeq: " + procStateSeq);
23686                    }
23687                    return;
23688                }
23689            }
23690            synchronized (record.networkStateLock) {
23691                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23692                    if (DEBUG_NETWORK) {
23693                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
23694                                + " been handled for uid: " + uid);
23695                    }
23696                    return;
23697                }
23698                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
23699                if (record.curProcStateSeq > procStateSeq) {
23700                    if (DEBUG_NETWORK) {
23701                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
23702                                + ", curProcstateSeq: " + record.curProcStateSeq
23703                                + ", procStateSeq: " + procStateSeq);
23704                    }
23705                    return;
23706                }
23707                if (record.waitingForNetwork) {
23708                    if (DEBUG_NETWORK) {
23709                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
23710                                + ", procStateSeq: " + procStateSeq);
23711                    }
23712                    record.networkStateLock.notifyAll();
23713                }
23714            }
23715        }
23716
23717        /**
23718         * Called after virtual display Id is updated by
23719         * {@link com.android.server.vr.CompatibilityDisplay} with a specific
23720         * {@param vrCompatibilityDisplayId}.
23721         */
23722        @Override
23723        public void setVrCompatibilityDisplayId(int vrCompatibilityDisplayId) {
23724            if (DEBUG_STACK) {
23725                Slog.d(TAG, "setVrCompatibilityDisplayId called for: " +
23726                        vrCompatibilityDisplayId);
23727            }
23728            synchronized (ActivityManagerService.this) {
23729                mVrCompatibilityDisplayId = vrCompatibilityDisplayId;
23730            }
23731        }
23732    }
23733
23734    /**
23735     * Called by app main thread to wait for the network policy rules to get udpated.
23736     *
23737     * @param procStateSeq The sequence number indicating the process state change that the main
23738     *                     thread is interested in.
23739     */
23740    @Override
23741    public void waitForNetworkStateUpdate(long procStateSeq) {
23742        final int callingUid = Binder.getCallingUid();
23743        if (DEBUG_NETWORK) {
23744            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
23745        }
23746        UidRecord record;
23747        synchronized (this) {
23748            record = mActiveUids.get(callingUid);
23749            if (record == null) {
23750                return;
23751            }
23752        }
23753        synchronized (record.networkStateLock) {
23754            if (record.lastDispatchedProcStateSeq < procStateSeq) {
23755                if (DEBUG_NETWORK) {
23756                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
23757                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
23758                            + " lastProcStateSeqDispatchedToObservers: "
23759                            + record.lastDispatchedProcStateSeq);
23760                }
23761                return;
23762            }
23763            if (record.curProcStateSeq > procStateSeq) {
23764                if (DEBUG_NETWORK) {
23765                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
23766                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
23767                            + ", procStateSeq: " + procStateSeq);
23768                }
23769                return;
23770            }
23771            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23772                if (DEBUG_NETWORK) {
23773                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
23774                            + procStateSeq + ", so no need to wait. Uid: "
23775                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
23776                            + record.lastNetworkUpdatedProcStateSeq);
23777                }
23778                return;
23779            }
23780            try {
23781                if (DEBUG_NETWORK) {
23782                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
23783                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
23784                }
23785                final long startTime = SystemClock.uptimeMillis();
23786                record.waitingForNetwork = true;
23787                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
23788                record.waitingForNetwork = false;
23789                final long totalTime = SystemClock.uptimeMillis() - startTime;
23790                if (totalTime >= mWaitForNetworkTimeoutMs) {
23791                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
23792                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
23793                            + procStateSeq);
23794                } else if (DEBUG_NETWORK ||  totalTime >= mWaitForNetworkTimeoutMs / 2) {
23795                    Slog.d(TAG_NETWORK, "Total time waited for network rules to get updated: "
23796                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
23797                            + procStateSeq);
23798                }
23799            } catch (InterruptedException e) {
23800                Thread.currentThread().interrupt();
23801            }
23802        }
23803    }
23804
23805    /**
23806     * Return the user id of the last resumed activity.
23807     */
23808    @Override
23809    public @UserIdInt int getLastResumedActivityUserId() {
23810        enforceCallingPermission(
23811                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
23812        synchronized (this) {
23813            if (mLastResumedActivity == null) {
23814                return mUserController.getCurrentUserIdLocked();
23815            }
23816            return mLastResumedActivity.userId;
23817        }
23818    }
23819
23820    private final class SleepTokenImpl extends SleepToken {
23821        private final String mTag;
23822        private final long mAcquireTime;
23823
23824        public SleepTokenImpl(String tag) {
23825            mTag = tag;
23826            mAcquireTime = SystemClock.uptimeMillis();
23827        }
23828
23829        @Override
23830        public void release() {
23831            synchronized (ActivityManagerService.this) {
23832                if (mSleepTokens.remove(this)) {
23833                    updateSleepIfNeededLocked();
23834                }
23835            }
23836        }
23837
23838        @Override
23839        public String toString() {
23840            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
23841        }
23842    }
23843
23844    /**
23845     * An implementation of IAppTask, that allows an app to manage its own tasks via
23846     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
23847     * only the process that calls getAppTasks() can call the AppTask methods.
23848     */
23849    class AppTaskImpl extends IAppTask.Stub {
23850        private int mTaskId;
23851        private int mCallingUid;
23852
23853        public AppTaskImpl(int taskId, int callingUid) {
23854            mTaskId = taskId;
23855            mCallingUid = callingUid;
23856        }
23857
23858        private void checkCaller() {
23859            if (mCallingUid != Binder.getCallingUid()) {
23860                throw new SecurityException("Caller " + mCallingUid
23861                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
23862            }
23863        }
23864
23865        @Override
23866        public void finishAndRemoveTask() {
23867            checkCaller();
23868
23869            synchronized (ActivityManagerService.this) {
23870                long origId = Binder.clearCallingIdentity();
23871                try {
23872                    // We remove the task from recents to preserve backwards
23873                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
23874                            REMOVE_FROM_RECENTS)) {
23875                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23876                    }
23877                } finally {
23878                    Binder.restoreCallingIdentity(origId);
23879                }
23880            }
23881        }
23882
23883        @Override
23884        public ActivityManager.RecentTaskInfo getTaskInfo() {
23885            checkCaller();
23886
23887            synchronized (ActivityManagerService.this) {
23888                long origId = Binder.clearCallingIdentity();
23889                try {
23890                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23891                    if (tr == null) {
23892                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23893                    }
23894                    return createRecentTaskInfoFromTaskRecord(tr);
23895                } finally {
23896                    Binder.restoreCallingIdentity(origId);
23897                }
23898            }
23899        }
23900
23901        @Override
23902        public void moveToFront() {
23903            checkCaller();
23904            // Will bring task to front if it already has a root activity.
23905            final long origId = Binder.clearCallingIdentity();
23906            try {
23907                synchronized (this) {
23908                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
23909                }
23910            } finally {
23911                Binder.restoreCallingIdentity(origId);
23912            }
23913        }
23914
23915        @Override
23916        public int startActivity(IBinder whoThread, String callingPackage,
23917                Intent intent, String resolvedType, Bundle bOptions) {
23918            checkCaller();
23919
23920            int callingUser = UserHandle.getCallingUserId();
23921            TaskRecord tr;
23922            IApplicationThread appThread;
23923            synchronized (ActivityManagerService.this) {
23924                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23925                if (tr == null) {
23926                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23927                }
23928                appThread = IApplicationThread.Stub.asInterface(whoThread);
23929                if (appThread == null) {
23930                    throw new IllegalArgumentException("Bad app thread " + appThread);
23931                }
23932            }
23933            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
23934                    resolvedType, null, null, null, null, 0, 0, null, null,
23935                    null, bOptions, false, callingUser, null, tr);
23936        }
23937
23938        @Override
23939        public void setExcludeFromRecents(boolean exclude) {
23940            checkCaller();
23941
23942            synchronized (ActivityManagerService.this) {
23943                long origId = Binder.clearCallingIdentity();
23944                try {
23945                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23946                    if (tr == null) {
23947                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23948                    }
23949                    Intent intent = tr.getBaseIntent();
23950                    if (exclude) {
23951                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23952                    } else {
23953                        intent.setFlags(intent.getFlags()
23954                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23955                    }
23956                } finally {
23957                    Binder.restoreCallingIdentity(origId);
23958                }
23959            }
23960        }
23961    }
23962
23963    /**
23964     * Kill processes for the user with id userId and that depend on the package named packageName
23965     */
23966    @Override
23967    public void killPackageDependents(String packageName, int userId) {
23968        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
23969        if (packageName == null) {
23970            throw new NullPointerException(
23971                    "Cannot kill the dependents of a package without its name.");
23972        }
23973
23974        long callingId = Binder.clearCallingIdentity();
23975        IPackageManager pm = AppGlobals.getPackageManager();
23976        int pkgUid = -1;
23977        try {
23978            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
23979        } catch (RemoteException e) {
23980        }
23981        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
23982            throw new IllegalArgumentException(
23983                    "Cannot kill dependents of non-existing package " + packageName);
23984        }
23985        try {
23986            synchronized(this) {
23987                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
23988                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
23989                        "dep: " + packageName);
23990            }
23991        } finally {
23992            Binder.restoreCallingIdentity(callingId);
23993        }
23994    }
23995
23996    @Override
23997    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
23998            throws RemoteException {
23999        final long callingId = Binder.clearCallingIdentity();
24000        try {
24001            mKeyguardController.dismissKeyguard(token, callback);
24002        } finally {
24003            Binder.restoreCallingIdentity(callingId);
24004        }
24005    }
24006
24007    @Override
24008    public int restartUserInBackground(final int userId) {
24009        return mUserController.restartUser(userId, /* foreground */ false);
24010    }
24011
24012    @Override
24013    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24014        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24015                "scheduleApplicationInfoChanged()");
24016
24017        synchronized (this) {
24018            final long origId = Binder.clearCallingIdentity();
24019            try {
24020                updateApplicationInfoLocked(packageNames, userId);
24021            } finally {
24022                Binder.restoreCallingIdentity(origId);
24023            }
24024        }
24025    }
24026
24027    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24028        final PackageManagerInternal packageManager = getPackageManagerInternalLocked();
24029        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24030        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24031            final ProcessRecord app = mLruProcesses.get(i);
24032            if (app.thread == null) {
24033                continue;
24034            }
24035
24036            if (userId != UserHandle.USER_ALL && app.userId != userId) {
24037                continue;
24038            }
24039
24040            final int packageCount = app.pkgList.size();
24041            for (int j = 0; j < packageCount; j++) {
24042                final String packageName = app.pkgList.keyAt(j);
24043                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24044                    try {
24045                        final ApplicationInfo ai = packageManager.getApplicationInfo(
24046                                packageName, app.userId);
24047                        if (ai != null) {
24048                            app.thread.scheduleApplicationInfoChanged(ai);
24049                        }
24050                    } catch (RemoteException e) {
24051                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24052                                    packageName, app));
24053                    }
24054                }
24055            }
24056        }
24057    }
24058
24059    /**
24060     * Attach an agent to the specified process (proces name or PID)
24061     */
24062    public void attachAgent(String process, String path) {
24063        try {
24064            synchronized (this) {
24065                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24066                if (proc == null || proc.thread == null) {
24067                    throw new IllegalArgumentException("Unknown process: " + process);
24068                }
24069
24070                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24071                if (!isDebuggable) {
24072                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24073                        throw new SecurityException("Process not debuggable: " + proc);
24074                    }
24075                }
24076
24077                proc.thread.attachAgent(path);
24078            }
24079        } catch (RemoteException e) {
24080            throw new IllegalStateException("Process disappeared");
24081        }
24082    }
24083
24084    @VisibleForTesting
24085    public static class Injector {
24086        private NetworkManagementInternal mNmi;
24087
24088        public Context getContext() {
24089            return null;
24090        }
24091
24092        public AppOpsService getAppOpsService(File file, Handler handler) {
24093            return new AppOpsService(file, handler);
24094        }
24095
24096        public Handler getUiHandler(ActivityManagerService service) {
24097            return service.new UiHandler();
24098        }
24099
24100        public boolean isNetworkRestrictedForUid(int uid) {
24101            if (ensureHasNetworkManagementInternal()) {
24102                return mNmi.isNetworkRestrictedForUid(uid);
24103            }
24104            return false;
24105        }
24106
24107        private boolean ensureHasNetworkManagementInternal() {
24108            if (mNmi == null) {
24109                mNmi = LocalServices.getService(NetworkManagementInternal.class);
24110            }
24111            return mNmi != null;
24112        }
24113    }
24114}
24115