ActivityManagerService.java revision c4d7248cdd84eab690e69cf2f2b56d399144dab8
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.PictureInPictureParams;
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.PinnedStackWindowController;
415import com.android.server.wm.WindowManagerService;
416
417import org.xmlpull.v1.XmlPullParser;
418import org.xmlpull.v1.XmlPullParserException;
419import org.xmlpull.v1.XmlSerializer;
420
421import java.io.File;
422import java.io.FileDescriptor;
423import java.io.FileInputStream;
424import java.io.FileNotFoundException;
425import java.io.FileOutputStream;
426import java.io.IOException;
427import java.io.InputStreamReader;
428import java.io.PrintWriter;
429import java.io.StringWriter;
430import java.io.UnsupportedEncodingException;
431import java.lang.ref.WeakReference;
432import java.nio.charset.StandardCharsets;
433import java.util.ArrayList;
434import java.util.Arrays;
435import java.util.Collections;
436import java.util.Comparator;
437import java.util.HashMap;
438import java.util.HashSet;
439import java.util.Iterator;
440import java.util.List;
441import java.util.Locale;
442import java.util.Map;
443import java.util.Objects;
444import java.util.Set;
445import java.util.concurrent.CountDownLatch;
446import java.util.concurrent.atomic.AtomicBoolean;
447import java.util.concurrent.atomic.AtomicLong;
448
449import dalvik.system.VMRuntime;
450import libcore.io.IoUtils;
451import libcore.util.EmptyArray;
452
453public class ActivityManagerService extends IActivityManager.Stub
454        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
455
456    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
457    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
458    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
459    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
460    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
461    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
462    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
463    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
464    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
465    private static final String TAG_LRU = TAG + POSTFIX_LRU;
466    private static final String TAG_MU = TAG + POSTFIX_MU;
467    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
468    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
469    private static final String TAG_POWER = TAG + POSTFIX_POWER;
470    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
471    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
472    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
473    private static final String TAG_PSS = TAG + POSTFIX_PSS;
474    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
475    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
476    private static final String TAG_STACK = TAG + POSTFIX_STACK;
477    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
478    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
479    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
480    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
481    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
482
483    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
484    // here so that while the job scheduler can depend on AMS, the other way around
485    // need not be the case.
486    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
487
488    /** Control over CPU and battery monitoring */
489    // write battery stats every 30 minutes.
490    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
491    static final boolean MONITOR_CPU_USAGE = true;
492    // don't sample cpu less than every 5 seconds.
493    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
494    // wait possibly forever for next cpu sample.
495    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
496    static final boolean MONITOR_THREAD_CPU_USAGE = false;
497
498    // The flags that are set for all calls we make to the package manager.
499    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
500
501    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
502
503    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
504
505    // Amount of time after a call to stopAppSwitches() during which we will
506    // prevent further untrusted switches from happening.
507    static final long APP_SWITCH_DELAY_TIME = 5*1000;
508
509    // How long we wait for a launched process to attach to the activity manager
510    // before we decide it's never going to come up for real.
511    static final int PROC_START_TIMEOUT = 10*1000;
512    // How long we wait for an attached process to publish its content providers
513    // before we decide it must be hung.
514    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
515
516    // How long we wait for a launched process to attach to the activity manager
517    // before we decide it's never going to come up for real, when the process was
518    // started with a wrapper for instrumentation (such as Valgrind) because it
519    // could take much longer than usual.
520    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
521
522    // How long we allow a receiver to run before giving up on it.
523    static final int BROADCAST_FG_TIMEOUT = 10*1000;
524    static final int BROADCAST_BG_TIMEOUT = 60*1000;
525
526    // How long we wait until we timeout on key dispatching.
527    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
528
529    // How long we wait until we timeout on key dispatching during instrumentation.
530    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
531
532    // How long to wait in getAssistContextExtras for the activity and foreground services
533    // to respond with the result.
534    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
535
536    // How long top wait when going through the modern assist (which doesn't need to block
537    // on getting this result before starting to launch its UI).
538    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
539
540    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
541    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
542
543    // Maximum number of persisted Uri grants a package is allowed
544    static final int MAX_PERSISTED_URI_GRANTS = 128;
545
546    static final int MY_PID = myPid();
547
548    static final String[] EMPTY_STRING_ARRAY = new String[0];
549
550    // How many bytes to write into the dropbox log before truncating
551    static final int DROPBOX_MAX_SIZE = 192 * 1024;
552    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
553    // as one line, but close enough for now.
554    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
555
556    // Access modes for handleIncomingUser.
557    static final int ALLOW_NON_FULL = 0;
558    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
559    static final int ALLOW_FULL_ONLY = 2;
560
561    // Necessary ApplicationInfo flags to mark an app as persistent
562    private static final int PERSISTENT_MASK =
563            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
564
565    // Intent sent when remote bugreport collection has been completed
566    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
567            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
568
569    // Used to indicate that an app transition should be animated.
570    static final boolean ANIMATE = true;
571
572    // Determines whether to take full screen screenshots
573    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
574
575    /**
576     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
577     */
578    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
579
580    /**
581     * State indicating that there is no need for any blocking for network.
582     */
583    @VisibleForTesting
584    static final int NETWORK_STATE_NO_CHANGE = 0;
585
586    /**
587     * State indicating that the main thread needs to be informed about the network wait.
588     */
589    @VisibleForTesting
590    static final int NETWORK_STATE_BLOCK = 1;
591
592    /**
593     * State indicating that any threads waiting for network state to get updated can be unblocked.
594     */
595    @VisibleForTesting
596    static final int NETWORK_STATE_UNBLOCK = 2;
597
598    // Max character limit for a notification title. If the notification title is larger than this
599    // the notification will not be legible to the user.
600    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
601
602    /** All system services */
603    SystemServiceManager mSystemServiceManager;
604    AssistUtils mAssistUtils;
605
606    private Installer mInstaller;
607
608    /** Run all ActivityStacks through this */
609    final ActivityStackSupervisor mStackSupervisor;
610    private final KeyguardController mKeyguardController;
611
612    final ActivityStarter mActivityStarter;
613
614    final TaskChangeNotificationController mTaskChangeNotificationController;
615
616    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
617
618    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
619
620    public final IntentFirewall mIntentFirewall;
621
622    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
623    // default action automatically.  Important for devices without direct input
624    // devices.
625    private boolean mShowDialogs = true;
626
627    private final VrController mVrController;
628
629    // VR Vr2d Display Id.
630    int mVr2dDisplayId = INVALID_DISPLAY;
631
632    // Whether we should use SCHED_FIFO for UI and RenderThreads.
633    private boolean mUseFifoUiScheduling = false;
634
635    BroadcastQueue mFgBroadcastQueue;
636    BroadcastQueue mBgBroadcastQueue;
637    // Convenient for easy iteration over the queues. Foreground is first
638    // so that dispatch of foreground broadcasts gets precedence.
639    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
640
641    BroadcastStats mLastBroadcastStats;
642    BroadcastStats mCurBroadcastStats;
643
644    BroadcastQueue broadcastQueueForIntent(Intent intent) {
645        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
646        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
647                "Broadcast intent " + intent + " on "
648                + (isFg ? "foreground" : "background") + " queue");
649        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
650    }
651
652    /**
653     * The last resumed activity. This is identical to the current resumed activity most
654     * of the time but could be different when we're pausing one activity before we resume
655     * another activity.
656     */
657    private ActivityRecord mLastResumedActivity;
658
659    /**
660     * If non-null, we are tracking the time the user spends in the currently focused app.
661     */
662    private AppTimeTracker mCurAppTimeTracker;
663
664    /**
665     * List of intents that were used to start the most recent tasks.
666     */
667    final RecentTasks mRecentTasks;
668
669    /**
670     * For addAppTask: cached of the last activity component that was added.
671     */
672    ComponentName mLastAddedTaskComponent;
673
674    /**
675     * For addAppTask: cached of the last activity uid that was added.
676     */
677    int mLastAddedTaskUid;
678
679    /**
680     * For addAppTask: cached of the last ActivityInfo that was added.
681     */
682    ActivityInfo mLastAddedTaskActivity;
683
684    /**
685     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
686     */
687    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
688
689    /**
690     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
691     */
692    String mDeviceOwnerName;
693
694    final UserController mUserController;
695
696    final AppErrors mAppErrors;
697
698    /**
699     * Indicates the maximum time spent waiting for the network rules to get updated.
700     */
701    @VisibleForTesting
702    long mWaitForNetworkTimeoutMs;
703
704    public boolean canShowErrorDialogs() {
705        return mShowDialogs && !mSleeping && !mShuttingDown
706                && !mKeyguardController.isKeyguardShowing();
707    }
708
709    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
710            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
711
712    static void boostPriorityForLockedSection() {
713        sThreadPriorityBooster.boost();
714    }
715
716    static void resetPriorityAfterLockedSection() {
717        sThreadPriorityBooster.reset();
718    }
719
720    public class PendingAssistExtras extends Binder implements Runnable {
721        public final ActivityRecord activity;
722        public boolean isHome;
723        public final Bundle extras;
724        public final Intent intent;
725        public final String hint;
726        public final IResultReceiver receiver;
727        public final int userHandle;
728        public boolean haveResult = false;
729        public Bundle result = null;
730        public AssistStructure structure = null;
731        public AssistContent content = null;
732        public Bundle receiverExtras;
733
734        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
735                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
736            activity = _activity;
737            extras = _extras;
738            intent = _intent;
739            hint = _hint;
740            receiver = _receiver;
741            receiverExtras = _receiverExtras;
742            userHandle = _userHandle;
743        }
744
745        @Override
746        public void run() {
747            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
748            synchronized (this) {
749                haveResult = true;
750                notifyAll();
751            }
752            pendingAssistExtrasTimedOut(this);
753        }
754    }
755
756    final ArrayList<PendingAssistExtras> mPendingAssistExtras
757            = new ArrayList<PendingAssistExtras>();
758
759    /**
760     * Process management.
761     */
762    final ProcessList mProcessList = new ProcessList();
763
764    /**
765     * All of the applications we currently have running organized by name.
766     * The keys are strings of the application package name (as
767     * returned by the package manager), and the keys are ApplicationRecord
768     * objects.
769     */
770    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
771
772    /**
773     * Tracking long-term execution of processes to look for abuse and other
774     * bad app behavior.
775     */
776    final ProcessStatsService mProcessStats;
777
778    /**
779     * The currently running isolated processes.
780     */
781    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
782
783    /**
784     * Counter for assigning isolated process uids, to avoid frequently reusing the
785     * same ones.
786     */
787    int mNextIsolatedProcessUid = 0;
788
789    /**
790     * The currently running heavy-weight process, if any.
791     */
792    ProcessRecord mHeavyWeightProcess = null;
793
794    /**
795     * Non-persistent appId whitelist for background restrictions
796     */
797    int[] mBackgroundAppIdWhitelist = new int[] {
798            BLUETOOTH_UID
799    };
800
801    /**
802     * Broadcast actions that will always be deliverable to unlaunched/background apps
803     */
804    ArraySet<String> mBackgroundLaunchBroadcasts;
805
806    /**
807     * All of the processes we currently have running organized by pid.
808     * The keys are the pid running the application.
809     *
810     * <p>NOTE: This object is protected by its own lock, NOT the global
811     * activity manager lock!
812     */
813    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
814
815    /**
816     * All of the processes that have been forced to be foreground.  The key
817     * is the pid of the caller who requested it (we hold a death
818     * link on it).
819     */
820    abstract class ForegroundToken implements IBinder.DeathRecipient {
821        int pid;
822        IBinder token;
823    }
824    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
825
826    /**
827     * List of records for processes that someone had tried to start before the
828     * system was ready.  We don't start them at that point, but ensure they
829     * are started by the time booting is complete.
830     */
831    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
832
833    /**
834     * List of persistent applications that are in the process
835     * of being started.
836     */
837    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
838
839    /**
840     * Processes that are being forcibly torn down.
841     */
842    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
843
844    /**
845     * List of running applications, sorted by recent usage.
846     * The first entry in the list is the least recently used.
847     */
848    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
849
850    /**
851     * Where in mLruProcesses that the processes hosting activities start.
852     */
853    int mLruProcessActivityStart = 0;
854
855    /**
856     * Where in mLruProcesses that the processes hosting services start.
857     * This is after (lower index) than mLruProcessesActivityStart.
858     */
859    int mLruProcessServiceStart = 0;
860
861    /**
862     * List of processes that should gc as soon as things are idle.
863     */
864    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
865
866    /**
867     * Processes we want to collect PSS data from.
868     */
869    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
870
871    private boolean mBinderTransactionTrackingEnabled = false;
872
873    /**
874     * Last time we requested PSS data of all processes.
875     */
876    long mLastFullPssTime = SystemClock.uptimeMillis();
877
878    /**
879     * If set, the next time we collect PSS data we should do a full collection
880     * with data from native processes and the kernel.
881     */
882    boolean mFullPssPending = false;
883
884    /**
885     * This is the process holding what we currently consider to be
886     * the "home" activity.
887     */
888    ProcessRecord mHomeProcess;
889
890    /**
891     * This is the process holding the activity the user last visited that
892     * is in a different process from the one they are currently in.
893     */
894    ProcessRecord mPreviousProcess;
895
896    /**
897     * The time at which the previous process was last visible.
898     */
899    long mPreviousProcessVisibleTime;
900
901    /**
902     * Track all uids that have actively running processes.
903     */
904    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
905
906    /**
907     * This is for verifying the UID report flow.
908     */
909    static final boolean VALIDATE_UID_STATES = true;
910    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
911
912    /**
913     * Packages that the user has asked to have run in screen size
914     * compatibility mode instead of filling the screen.
915     */
916    final CompatModePackages mCompatModePackages;
917
918    /**
919     * Set of IntentSenderRecord objects that are currently active.
920     */
921    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
922            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
923
924    /**
925     * Fingerprints (hashCode()) of stack traces that we've
926     * already logged DropBox entries for.  Guarded by itself.  If
927     * something (rogue user app) forces this over
928     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
929     */
930    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
931    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
932
933    /**
934     * Strict Mode background batched logging state.
935     *
936     * The string buffer is guarded by itself, and its lock is also
937     * used to determine if another batched write is already
938     * in-flight.
939     */
940    private final StringBuilder mStrictModeBuffer = new StringBuilder();
941
942    /**
943     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
944     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
945     */
946    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
947
948    /**
949     * Resolver for broadcast intents to registered receivers.
950     * Holds BroadcastFilter (subclass of IntentFilter).
951     */
952    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
953            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
954        @Override
955        protected boolean allowFilterResult(
956                BroadcastFilter filter, List<BroadcastFilter> dest) {
957            IBinder target = filter.receiverList.receiver.asBinder();
958            for (int i = dest.size() - 1; i >= 0; i--) {
959                if (dest.get(i).receiverList.receiver.asBinder() == target) {
960                    return false;
961                }
962            }
963            return true;
964        }
965
966        @Override
967        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
968            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
969                    || userId == filter.owningUserId) {
970                return super.newResult(filter, match, userId);
971            }
972            return null;
973        }
974
975        @Override
976        protected BroadcastFilter[] newArray(int size) {
977            return new BroadcastFilter[size];
978        }
979
980        @Override
981        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
982            return packageName.equals(filter.packageName);
983        }
984    };
985
986    /**
987     * State of all active sticky broadcasts per user.  Keys are the action of the
988     * sticky Intent, values are an ArrayList of all broadcasted intents with
989     * that action (which should usually be one).  The SparseArray is keyed
990     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
991     * for stickies that are sent to all users.
992     */
993    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
994            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
995
996    final ActiveServices mServices;
997
998    final static class Association {
999        final int mSourceUid;
1000        final String mSourceProcess;
1001        final int mTargetUid;
1002        final ComponentName mTargetComponent;
1003        final String mTargetProcess;
1004
1005        int mCount;
1006        long mTime;
1007
1008        int mNesting;
1009        long mStartTime;
1010
1011        // states of the source process when the bind occurred.
1012        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1013        long mLastStateUptime;
1014        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1015                - ActivityManager.MIN_PROCESS_STATE+1];
1016
1017        Association(int sourceUid, String sourceProcess, int targetUid,
1018                ComponentName targetComponent, String targetProcess) {
1019            mSourceUid = sourceUid;
1020            mSourceProcess = sourceProcess;
1021            mTargetUid = targetUid;
1022            mTargetComponent = targetComponent;
1023            mTargetProcess = targetProcess;
1024        }
1025    }
1026
1027    /**
1028     * When service association tracking is enabled, this is all of the associations we
1029     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1030     * -> association data.
1031     */
1032    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1033            mAssociations = new SparseArray<>();
1034    boolean mTrackingAssociations;
1035
1036    /**
1037     * Backup/restore process management
1038     */
1039    String mBackupAppName = null;
1040    BackupRecord mBackupTarget = null;
1041
1042    final ProviderMap mProviderMap;
1043
1044    /**
1045     * List of content providers who have clients waiting for them.  The
1046     * application is currently being launched and the provider will be
1047     * removed from this list once it is published.
1048     */
1049    final ArrayList<ContentProviderRecord> mLaunchingProviders
1050            = new ArrayList<ContentProviderRecord>();
1051
1052    /**
1053     * File storing persisted {@link #mGrantedUriPermissions}.
1054     */
1055    private final AtomicFile mGrantFile;
1056
1057    /** XML constants used in {@link #mGrantFile} */
1058    private static final String TAG_URI_GRANTS = "uri-grants";
1059    private static final String TAG_URI_GRANT = "uri-grant";
1060    private static final String ATTR_USER_HANDLE = "userHandle";
1061    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1062    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1063    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1064    private static final String ATTR_TARGET_PKG = "targetPkg";
1065    private static final String ATTR_URI = "uri";
1066    private static final String ATTR_MODE_FLAGS = "modeFlags";
1067    private static final String ATTR_CREATED_TIME = "createdTime";
1068    private static final String ATTR_PREFIX = "prefix";
1069
1070    /**
1071     * Global set of specific {@link Uri} permissions that have been granted.
1072     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1073     * to {@link UriPermission#uri} to {@link UriPermission}.
1074     */
1075    @GuardedBy("this")
1076    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1077            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1078
1079    public static class GrantUri {
1080        public final int sourceUserId;
1081        public final Uri uri;
1082        public boolean prefix;
1083
1084        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1085            this.sourceUserId = sourceUserId;
1086            this.uri = uri;
1087            this.prefix = prefix;
1088        }
1089
1090        @Override
1091        public int hashCode() {
1092            int hashCode = 1;
1093            hashCode = 31 * hashCode + sourceUserId;
1094            hashCode = 31 * hashCode + uri.hashCode();
1095            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1096            return hashCode;
1097        }
1098
1099        @Override
1100        public boolean equals(Object o) {
1101            if (o instanceof GrantUri) {
1102                GrantUri other = (GrantUri) o;
1103                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1104                        && prefix == other.prefix;
1105            }
1106            return false;
1107        }
1108
1109        @Override
1110        public String toString() {
1111            String result = uri.toString() + " [user " + sourceUserId + "]";
1112            if (prefix) result += " [prefix]";
1113            return result;
1114        }
1115
1116        public String toSafeString() {
1117            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1118            if (prefix) result += " [prefix]";
1119            return result;
1120        }
1121
1122        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1123            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1124                    ContentProvider.getUriWithoutUserId(uri), false);
1125        }
1126    }
1127
1128    CoreSettingsObserver mCoreSettingsObserver;
1129
1130    FontScaleSettingObserver mFontScaleSettingObserver;
1131
1132    private final class FontScaleSettingObserver extends ContentObserver {
1133        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1134
1135        public FontScaleSettingObserver() {
1136            super(mHandler);
1137            ContentResolver resolver = mContext.getContentResolver();
1138            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1139        }
1140
1141        @Override
1142        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1143            if (mFontScaleUri.equals(uri)) {
1144                updateFontScaleIfNeeded(userId);
1145            }
1146        }
1147    }
1148
1149    /**
1150     * Thread-local storage used to carry caller permissions over through
1151     * indirect content-provider access.
1152     */
1153    private class Identity {
1154        public final IBinder token;
1155        public final int pid;
1156        public final int uid;
1157
1158        Identity(IBinder _token, int _pid, int _uid) {
1159            token = _token;
1160            pid = _pid;
1161            uid = _uid;
1162        }
1163    }
1164
1165    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1166
1167    /**
1168     * All information we have collected about the runtime performance of
1169     * any user id that can impact battery performance.
1170     */
1171    final BatteryStatsService mBatteryStatsService;
1172
1173    /**
1174     * Information about component usage
1175     */
1176    UsageStatsManagerInternal mUsageStatsService;
1177
1178    /**
1179     * Access to DeviceIdleController service.
1180     */
1181    DeviceIdleController.LocalService mLocalDeviceIdleController;
1182
1183    /**
1184     * Set of app ids that are whitelisted for device idle and thus background check.
1185     */
1186    int[] mDeviceIdleWhitelist = new int[0];
1187
1188    /**
1189     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1190     */
1191    int[] mDeviceIdleTempWhitelist = new int[0];
1192
1193    static final class PendingTempWhitelist {
1194        final int targetUid;
1195        final long duration;
1196        final String tag;
1197
1198        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1199            targetUid = _targetUid;
1200            duration = _duration;
1201            tag = _tag;
1202        }
1203    }
1204
1205    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1206
1207    /**
1208     * Information about and control over application operations
1209     */
1210    final AppOpsService mAppOpsService;
1211
1212    /** Current sequencing integer of the configuration, for skipping old configurations. */
1213    private int mConfigurationSeq;
1214
1215    /**
1216     * Temp object used when global and/or display override configuration is updated. It is also
1217     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1218     * anyone...
1219     */
1220    private Configuration mTempConfig = new Configuration();
1221
1222    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1223            new UpdateConfigurationResult();
1224    private static final class UpdateConfigurationResult {
1225        // Configuration changes that were updated.
1226        int changes;
1227        // If the activity was relaunched to match the new configuration.
1228        boolean activityRelaunched;
1229
1230        void reset() {
1231            changes = 0;
1232            activityRelaunched = false;
1233        }
1234    }
1235
1236    boolean mSuppressResizeConfigChanges;
1237
1238    /**
1239     * Hardware-reported OpenGLES version.
1240     */
1241    final int GL_ES_VERSION;
1242
1243    /**
1244     * List of initialization arguments to pass to all processes when binding applications to them.
1245     * For example, references to the commonly used services.
1246     */
1247    HashMap<String, IBinder> mAppBindArgs;
1248    HashMap<String, IBinder> mIsolatedAppBindArgs;
1249
1250    /**
1251     * Temporary to avoid allocations.  Protected by main lock.
1252     */
1253    final StringBuilder mStringBuilder = new StringBuilder(256);
1254
1255    /**
1256     * Used to control how we initialize the service.
1257     */
1258    ComponentName mTopComponent;
1259    String mTopAction = Intent.ACTION_MAIN;
1260    String mTopData;
1261
1262    volatile boolean mProcessesReady = false;
1263    volatile boolean mSystemReady = false;
1264    volatile boolean mOnBattery = false;
1265    volatile int mFactoryTest;
1266
1267    @GuardedBy("this") boolean mBooting = false;
1268    @GuardedBy("this") boolean mCallFinishBooting = false;
1269    @GuardedBy("this") boolean mBootAnimationComplete = false;
1270    @GuardedBy("this") boolean mLaunchWarningShown = false;
1271    @GuardedBy("this") boolean mCheckedForSetup = false;
1272
1273    final Context mContext;
1274
1275    /**
1276     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1277     * change at runtime. Use mContext for non-UI purposes.
1278     */
1279    final Context mUiContext;
1280
1281    /**
1282     * The time at which we will allow normal application switches again,
1283     * after a call to {@link #stopAppSwitches()}.
1284     */
1285    long mAppSwitchesAllowedTime;
1286
1287    /**
1288     * This is set to true after the first switch after mAppSwitchesAllowedTime
1289     * is set; any switches after that will clear the time.
1290     */
1291    boolean mDidAppSwitch;
1292
1293    /**
1294     * Last time (in realtime) at which we checked for power usage.
1295     */
1296    long mLastPowerCheckRealtime;
1297
1298    /**
1299     * Last time (in uptime) at which we checked for power usage.
1300     */
1301    long mLastPowerCheckUptime;
1302
1303    /**
1304     * Set while we are wanting to sleep, to prevent any
1305     * activities from being started/resumed.
1306     *
1307     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1308     *
1309     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1310     * while in the sleep state until there is a pending transition out of sleep, in which case
1311     * mSleeping is set to false, and remains false while awake.
1312     *
1313     * Whether mSleeping can quickly toggled between true/false without the device actually
1314     * display changing states is undefined.
1315     */
1316    private boolean mSleeping = false;
1317
1318    /**
1319     * The process state used for processes that are running the top activities.
1320     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1321     */
1322    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1323
1324    /**
1325     * Set while we are running a voice interaction.  This overrides
1326     * sleeping while it is active.
1327     */
1328    private IVoiceInteractionSession mRunningVoice;
1329
1330    /**
1331     * For some direct access we need to power manager.
1332     */
1333    PowerManagerInternal mLocalPowerManager;
1334
1335    /**
1336     * We want to hold a wake lock while running a voice interaction session, since
1337     * this may happen with the screen off and we need to keep the CPU running to
1338     * be able to continue to interact with the user.
1339     */
1340    PowerManager.WakeLock mVoiceWakeLock;
1341
1342    /**
1343     * State of external calls telling us if the device is awake or asleep.
1344     */
1345    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1346
1347    /**
1348     * A list of tokens that cause the top activity to be put to sleep.
1349     * They are used by components that may hide and block interaction with underlying
1350     * activities.
1351     */
1352    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1353
1354    /**
1355     * Set if we are shutting down the system, similar to sleeping.
1356     */
1357    boolean mShuttingDown = false;
1358
1359    /**
1360     * Current sequence id for oom_adj computation traversal.
1361     */
1362    int mAdjSeq = 0;
1363
1364    /**
1365     * Current sequence id for process LRU updating.
1366     */
1367    int mLruSeq = 0;
1368
1369    /**
1370     * Keep track of the non-cached/empty process we last found, to help
1371     * determine how to distribute cached/empty processes next time.
1372     */
1373    int mNumNonCachedProcs = 0;
1374
1375    /**
1376     * Keep track of the number of cached hidden procs, to balance oom adj
1377     * distribution between those and empty procs.
1378     */
1379    int mNumCachedHiddenProcs = 0;
1380
1381    /**
1382     * Keep track of the number of service processes we last found, to
1383     * determine on the next iteration which should be B services.
1384     */
1385    int mNumServiceProcs = 0;
1386    int mNewNumAServiceProcs = 0;
1387    int mNewNumServiceProcs = 0;
1388
1389    /**
1390     * Allow the current computed overall memory level of the system to go down?
1391     * This is set to false when we are killing processes for reasons other than
1392     * memory management, so that the now smaller process list will not be taken as
1393     * an indication that memory is tighter.
1394     */
1395    boolean mAllowLowerMemLevel = false;
1396
1397    /**
1398     * The last computed memory level, for holding when we are in a state that
1399     * processes are going away for other reasons.
1400     */
1401    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1402
1403    /**
1404     * The last total number of process we have, to determine if changes actually look
1405     * like a shrinking number of process due to lower RAM.
1406     */
1407    int mLastNumProcesses;
1408
1409    /**
1410     * The uptime of the last time we performed idle maintenance.
1411     */
1412    long mLastIdleTime = SystemClock.uptimeMillis();
1413
1414    /**
1415     * Total time spent with RAM that has been added in the past since the last idle time.
1416     */
1417    long mLowRamTimeSinceLastIdle = 0;
1418
1419    /**
1420     * If RAM is currently low, when that horrible situation started.
1421     */
1422    long mLowRamStartTime = 0;
1423
1424    /**
1425     * For reporting to battery stats the current top application.
1426     */
1427    private String mCurResumedPackage = null;
1428    private int mCurResumedUid = -1;
1429
1430    /**
1431     * For reporting to battery stats the apps currently running foreground
1432     * service.  The ProcessMap is package/uid tuples; each of these contain
1433     * an array of the currently foreground processes.
1434     */
1435    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1436            = new ProcessMap<ArrayList<ProcessRecord>>();
1437
1438    /**
1439     * This is set if we had to do a delayed dexopt of an app before launching
1440     * it, to increase the ANR timeouts in that case.
1441     */
1442    boolean mDidDexOpt;
1443
1444    /**
1445     * Set if the systemServer made a call to enterSafeMode.
1446     */
1447    boolean mSafeMode;
1448
1449    /**
1450     * If true, we are running under a test environment so will sample PSS from processes
1451     * much more rapidly to try to collect better data when the tests are rapidly
1452     * running through apps.
1453     */
1454    boolean mTestPssMode = false;
1455
1456    String mDebugApp = null;
1457    boolean mWaitForDebugger = false;
1458    boolean mDebugTransient = false;
1459    String mOrigDebugApp = null;
1460    boolean mOrigWaitForDebugger = false;
1461    boolean mAlwaysFinishActivities = false;
1462    boolean mForceResizableActivities;
1463    boolean mSupportsMultiWindow;
1464    boolean mSupportsSplitScreenMultiWindow;
1465    boolean mSupportsFreeformWindowManagement;
1466    boolean mSupportsPictureInPicture;
1467    boolean mSupportsMultiDisplay;
1468    boolean mSupportsLeanbackOnly;
1469    IActivityController mController = null;
1470    boolean mControllerIsAMonkey = false;
1471    String mProfileApp = null;
1472    ProcessRecord mProfileProc = null;
1473    String mProfileFile;
1474    ParcelFileDescriptor mProfileFd;
1475    int mSamplingInterval = 0;
1476    boolean mAutoStopProfiler = false;
1477    boolean mStreamingOutput = false;
1478    int mProfileType = 0;
1479    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1480    String mMemWatchDumpProcName;
1481    String mMemWatchDumpFile;
1482    int mMemWatchDumpPid;
1483    int mMemWatchDumpUid;
1484    String mTrackAllocationApp = null;
1485    String mNativeDebuggingApp = null;
1486
1487    final long[] mTmpLong = new long[2];
1488
1489    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1490
1491    /**
1492     * A global counter for generating sequence numbers.
1493     * This value will be used when incrementing sequence numbers in individual uidRecords.
1494     *
1495     * Having a global counter ensures that seq numbers are monotonically increasing for a
1496     * particular uid even when the uidRecord is re-created.
1497     */
1498    @GuardedBy("this")
1499    @VisibleForTesting
1500    long mProcStateSeqCounter = 0;
1501
1502    private final Injector mInjector;
1503
1504    static final class ProcessChangeItem {
1505        static final int CHANGE_ACTIVITIES = 1<<0;
1506        int changes;
1507        int uid;
1508        int pid;
1509        int processState;
1510        boolean foregroundActivities;
1511    }
1512
1513    static final class UidObserverRegistration {
1514        final int uid;
1515        final String pkg;
1516        final int which;
1517        final int cutpoint;
1518
1519        final SparseIntArray lastProcStates;
1520
1521        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1522            uid = _uid;
1523            pkg = _pkg;
1524            which = _which;
1525            cutpoint = _cutpoint;
1526            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1527                lastProcStates = new SparseIntArray();
1528            } else {
1529                lastProcStates = null;
1530            }
1531        }
1532    }
1533
1534    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1535    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1536
1537    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1538    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1539
1540    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1541    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1542
1543    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1544    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1545
1546    /**
1547     * Runtime CPU use collection thread.  This object's lock is used to
1548     * perform synchronization with the thread (notifying it to run).
1549     */
1550    final Thread mProcessCpuThread;
1551
1552    /**
1553     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1554     * Must acquire this object's lock when accessing it.
1555     * NOTE: this lock will be held while doing long operations (trawling
1556     * through all processes in /proc), so it should never be acquired by
1557     * any critical paths such as when holding the main activity manager lock.
1558     */
1559    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1560            MONITOR_THREAD_CPU_USAGE);
1561    final AtomicLong mLastCpuTime = new AtomicLong(0);
1562    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1563    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1564
1565    long mLastWriteTime = 0;
1566
1567    /**
1568     * Used to retain an update lock when the foreground activity is in
1569     * immersive mode.
1570     */
1571    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1572
1573    /**
1574     * Set to true after the system has finished booting.
1575     */
1576    boolean mBooted = false;
1577
1578    WindowManagerService mWindowManager;
1579    final ActivityThread mSystemThread;
1580
1581    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1582        final ProcessRecord mApp;
1583        final int mPid;
1584        final IApplicationThread mAppThread;
1585
1586        AppDeathRecipient(ProcessRecord app, int pid,
1587                IApplicationThread thread) {
1588            if (DEBUG_ALL) Slog.v(
1589                TAG, "New death recipient " + this
1590                + " for thread " + thread.asBinder());
1591            mApp = app;
1592            mPid = pid;
1593            mAppThread = thread;
1594        }
1595
1596        @Override
1597        public void binderDied() {
1598            if (DEBUG_ALL) Slog.v(
1599                TAG, "Death received in " + this
1600                + " for thread " + mAppThread.asBinder());
1601            synchronized(ActivityManagerService.this) {
1602                appDiedLocked(mApp, mPid, mAppThread, true);
1603            }
1604        }
1605    }
1606
1607    static final int SHOW_ERROR_UI_MSG = 1;
1608    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1609    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1610    static final int UPDATE_CONFIGURATION_MSG = 4;
1611    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1612    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1613    static final int SERVICE_TIMEOUT_MSG = 12;
1614    static final int UPDATE_TIME_ZONE = 13;
1615    static final int SHOW_UID_ERROR_UI_MSG = 14;
1616    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1617    static final int PROC_START_TIMEOUT_MSG = 20;
1618    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1619    static final int KILL_APPLICATION_MSG = 22;
1620    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1621    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1622    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1623    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1624    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1625    static final int CLEAR_DNS_CACHE_MSG = 28;
1626    static final int UPDATE_HTTP_PROXY_MSG = 29;
1627    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1628    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1629    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1630    static final int REPORT_MEM_USAGE_MSG = 33;
1631    static final int REPORT_USER_SWITCH_MSG = 34;
1632    static final int CONTINUE_USER_SWITCH_MSG = 35;
1633    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1634    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1635    static final int PERSIST_URI_GRANTS_MSG = 38;
1636    static final int REQUEST_ALL_PSS_MSG = 39;
1637    static final int START_PROFILES_MSG = 40;
1638    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1639    static final int SYSTEM_USER_START_MSG = 42;
1640    static final int SYSTEM_USER_CURRENT_MSG = 43;
1641    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1642    static final int FINISH_BOOTING_MSG = 45;
1643    static final int START_USER_SWITCH_UI_MSG = 46;
1644    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1645    static final int DISMISS_DIALOG_UI_MSG = 48;
1646    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1647    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1648    static final int DELETE_DUMPHEAP_MSG = 51;
1649    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1650    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1651    static final int REPORT_TIME_TRACKER_MSG = 54;
1652    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1653    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1654    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1655    static final int IDLE_UIDS_MSG = 58;
1656    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1657    static final int LOG_STACK_STATE = 60;
1658    static final int VR_MODE_CHANGE_MSG = 61;
1659    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1660    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1661    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1662    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1663    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1664    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1665    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1666    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1667    static final int START_USER_SWITCH_FG_MSG = 712;
1668
1669    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1670    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1671    static final int FIRST_COMPAT_MODE_MSG = 300;
1672    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1673
1674    static ServiceThread sKillThread = null;
1675    static KillHandler sKillHandler = null;
1676
1677    CompatModeDialog mCompatModeDialog;
1678    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1679    long mLastMemUsageReportTime = 0;
1680
1681    /**
1682     * Flag whether the current user is a "monkey", i.e. whether
1683     * the UI is driven by a UI automation tool.
1684     */
1685    private boolean mUserIsMonkey;
1686
1687    /** Flag whether the device has a Recents UI */
1688    boolean mHasRecents;
1689
1690    /** The dimensions of the thumbnails in the Recents UI. */
1691    int mThumbnailWidth;
1692    int mThumbnailHeight;
1693    float mFullscreenThumbnailScale;
1694
1695    final ServiceThread mHandlerThread;
1696    final MainHandler mHandler;
1697    final Handler mUiHandler;
1698
1699    final ActivityManagerConstants mConstants;
1700
1701    PackageManagerInternal mPackageManagerInt;
1702
1703    // VoiceInteraction session ID that changes for each new request except when
1704    // being called for multiwindow assist in a single session.
1705    private int mViSessionId = 1000;
1706
1707    final boolean mPermissionReviewRequired;
1708
1709    /**
1710     * Current global configuration information. Contains general settings for the entire system,
1711     * also corresponds to the merged configuration of the default display.
1712     */
1713    Configuration getGlobalConfiguration() {
1714        return mStackSupervisor.getConfiguration();
1715    }
1716
1717    final class KillHandler extends Handler {
1718        static final int KILL_PROCESS_GROUP_MSG = 4000;
1719
1720        public KillHandler(Looper looper) {
1721            super(looper, null, true);
1722        }
1723
1724        @Override
1725        public void handleMessage(Message msg) {
1726            switch (msg.what) {
1727                case KILL_PROCESS_GROUP_MSG:
1728                {
1729                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1730                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1731                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1732                }
1733                break;
1734
1735                default:
1736                    super.handleMessage(msg);
1737            }
1738        }
1739    }
1740
1741    final class UiHandler extends Handler {
1742        public UiHandler() {
1743            super(com.android.server.UiThread.get().getLooper(), null, true);
1744        }
1745
1746        @Override
1747        public void handleMessage(Message msg) {
1748            switch (msg.what) {
1749            case SHOW_ERROR_UI_MSG: {
1750                mAppErrors.handleShowAppErrorUi(msg);
1751                ensureBootCompleted();
1752            } break;
1753            case SHOW_NOT_RESPONDING_UI_MSG: {
1754                mAppErrors.handleShowAnrUi(msg);
1755                ensureBootCompleted();
1756            } break;
1757            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1758                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1759                synchronized (ActivityManagerService.this) {
1760                    ProcessRecord proc = (ProcessRecord) data.get("app");
1761                    if (proc == null) {
1762                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1763                        break;
1764                    }
1765                    if (proc.crashDialog != null) {
1766                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1767                        return;
1768                    }
1769                    AppErrorResult res = (AppErrorResult) data.get("result");
1770                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1771                        Dialog d = new StrictModeViolationDialog(mContext,
1772                                ActivityManagerService.this, res, proc);
1773                        d.show();
1774                        proc.crashDialog = d;
1775                    } else {
1776                        // The device is asleep, so just pretend that the user
1777                        // saw a crash dialog and hit "force quit".
1778                        res.set(0);
1779                    }
1780                }
1781                ensureBootCompleted();
1782            } break;
1783            case SHOW_FACTORY_ERROR_UI_MSG: {
1784                Dialog d = new FactoryErrorDialog(
1785                        mUiContext, msg.getData().getCharSequence("msg"));
1786                d.show();
1787                ensureBootCompleted();
1788            } break;
1789            case WAIT_FOR_DEBUGGER_UI_MSG: {
1790                synchronized (ActivityManagerService.this) {
1791                    ProcessRecord app = (ProcessRecord)msg.obj;
1792                    if (msg.arg1 != 0) {
1793                        if (!app.waitedForDebugger) {
1794                            Dialog d = new AppWaitingForDebuggerDialog(
1795                                    ActivityManagerService.this,
1796                                    mUiContext, app);
1797                            app.waitDialog = d;
1798                            app.waitedForDebugger = true;
1799                            d.show();
1800                        }
1801                    } else {
1802                        if (app.waitDialog != null) {
1803                            app.waitDialog.dismiss();
1804                            app.waitDialog = null;
1805                        }
1806                    }
1807                }
1808            } break;
1809            case SHOW_UID_ERROR_UI_MSG: {
1810                if (mShowDialogs) {
1811                    AlertDialog d = new BaseErrorDialog(mUiContext);
1812                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1813                    d.setCancelable(false);
1814                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1815                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1816                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1817                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1818                    d.show();
1819                }
1820            } break;
1821            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1822                if (mShowDialogs) {
1823                    AlertDialog d = new BaseErrorDialog(mUiContext);
1824                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1825                    d.setCancelable(false);
1826                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1827                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1828                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1829                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1830                    d.show();
1831                }
1832            } break;
1833            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1834                synchronized (ActivityManagerService.this) {
1835                    ActivityRecord ar = (ActivityRecord) msg.obj;
1836                    if (mCompatModeDialog != null) {
1837                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1838                                ar.info.applicationInfo.packageName)) {
1839                            return;
1840                        }
1841                        mCompatModeDialog.dismiss();
1842                        mCompatModeDialog = null;
1843                    }
1844                    if (ar != null && false) {
1845                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1846                                ar.packageName)) {
1847                            int mode = mCompatModePackages.computeCompatModeLocked(
1848                                    ar.info.applicationInfo);
1849                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1850                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1851                                mCompatModeDialog = new CompatModeDialog(
1852                                        ActivityManagerService.this, mUiContext,
1853                                        ar.info.applicationInfo);
1854                                mCompatModeDialog.show();
1855                            }
1856                        }
1857                    }
1858                }
1859                break;
1860            }
1861            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1862                synchronized (ActivityManagerService.this) {
1863                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1864                    if (mUnsupportedDisplaySizeDialog != null) {
1865                        mUnsupportedDisplaySizeDialog.dismiss();
1866                        mUnsupportedDisplaySizeDialog = null;
1867                    }
1868                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1869                            ar.packageName)) {
1870                        // TODO(multi-display): Show dialog on appropriate display.
1871                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1872                                ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1873                        mUnsupportedDisplaySizeDialog.show();
1874                    }
1875                }
1876                break;
1877            }
1878            case START_USER_SWITCH_UI_MSG: {
1879                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1880                break;
1881            }
1882            case DISMISS_DIALOG_UI_MSG: {
1883                final Dialog d = (Dialog) msg.obj;
1884                d.dismiss();
1885                break;
1886            }
1887            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1888                dispatchProcessesChanged();
1889                break;
1890            }
1891            case DISPATCH_PROCESS_DIED_UI_MSG: {
1892                final int pid = msg.arg1;
1893                final int uid = msg.arg2;
1894                dispatchProcessDied(pid, uid);
1895                break;
1896            }
1897            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1898                dispatchUidsChanged();
1899            } break;
1900            case PUSH_TEMP_WHITELIST_UI_MSG: {
1901                pushTempWhitelist();
1902            } break;
1903            }
1904        }
1905    }
1906
1907    final class MainHandler extends Handler {
1908        public MainHandler(Looper looper) {
1909            super(looper, null, true);
1910        }
1911
1912        @Override
1913        public void handleMessage(Message msg) {
1914            switch (msg.what) {
1915            case UPDATE_CONFIGURATION_MSG: {
1916                final ContentResolver resolver = mContext.getContentResolver();
1917                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1918                        msg.arg1);
1919            } break;
1920            case GC_BACKGROUND_PROCESSES_MSG: {
1921                synchronized (ActivityManagerService.this) {
1922                    performAppGcsIfAppropriateLocked();
1923                }
1924            } break;
1925            case SERVICE_TIMEOUT_MSG: {
1926                if (mDidDexOpt) {
1927                    mDidDexOpt = false;
1928                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1929                    nmsg.obj = msg.obj;
1930                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1931                    return;
1932                }
1933                mServices.serviceTimeout((ProcessRecord)msg.obj);
1934            } break;
1935            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1936                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1937            } break;
1938            case SERVICE_FOREGROUND_CRASH_MSG: {
1939                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1940            } break;
1941            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1942                RemoteCallbackList<IResultReceiver> callbacks
1943                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
1944                int N = callbacks.beginBroadcast();
1945                for (int i = 0; i < N; i++) {
1946                    try {
1947                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1948                    } catch (RemoteException e) {
1949                    }
1950                }
1951                callbacks.finishBroadcast();
1952            } break;
1953            case UPDATE_TIME_ZONE: {
1954                synchronized (ActivityManagerService.this) {
1955                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1956                        ProcessRecord r = mLruProcesses.get(i);
1957                        if (r.thread != null) {
1958                            try {
1959                                r.thread.updateTimeZone();
1960                            } catch (RemoteException ex) {
1961                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1962                            }
1963                        }
1964                    }
1965                }
1966            } break;
1967            case CLEAR_DNS_CACHE_MSG: {
1968                synchronized (ActivityManagerService.this) {
1969                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1970                        ProcessRecord r = mLruProcesses.get(i);
1971                        if (r.thread != null) {
1972                            try {
1973                                r.thread.clearDnsCache();
1974                            } catch (RemoteException ex) {
1975                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1976                            }
1977                        }
1978                    }
1979                }
1980            } break;
1981            case UPDATE_HTTP_PROXY_MSG: {
1982                ProxyInfo proxy = (ProxyInfo)msg.obj;
1983                String host = "";
1984                String port = "";
1985                String exclList = "";
1986                Uri pacFileUrl = Uri.EMPTY;
1987                if (proxy != null) {
1988                    host = proxy.getHost();
1989                    port = Integer.toString(proxy.getPort());
1990                    exclList = proxy.getExclusionListAsString();
1991                    pacFileUrl = proxy.getPacFileUrl();
1992                }
1993                synchronized (ActivityManagerService.this) {
1994                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1995                        ProcessRecord r = mLruProcesses.get(i);
1996                        if (r.thread != null) {
1997                            try {
1998                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1999                            } catch (RemoteException ex) {
2000                                Slog.w(TAG, "Failed to update http proxy for: " +
2001                                        r.info.processName);
2002                            }
2003                        }
2004                    }
2005                }
2006            } break;
2007            case PROC_START_TIMEOUT_MSG: {
2008                if (mDidDexOpt) {
2009                    mDidDexOpt = false;
2010                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2011                    nmsg.obj = msg.obj;
2012                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
2013                    return;
2014                }
2015                ProcessRecord app = (ProcessRecord)msg.obj;
2016                synchronized (ActivityManagerService.this) {
2017                    processStartTimedOutLocked(app);
2018                }
2019            } break;
2020            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2021                ProcessRecord app = (ProcessRecord)msg.obj;
2022                synchronized (ActivityManagerService.this) {
2023                    processContentProviderPublishTimedOutLocked(app);
2024                }
2025            } break;
2026            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2027                synchronized (ActivityManagerService.this) {
2028                    mActivityStarter.doPendingActivityLaunchesLocked(true);
2029                }
2030            } break;
2031            case KILL_APPLICATION_MSG: {
2032                synchronized (ActivityManagerService.this) {
2033                    final int appId = msg.arg1;
2034                    final int userId = msg.arg2;
2035                    Bundle bundle = (Bundle)msg.obj;
2036                    String pkg = bundle.getString("pkg");
2037                    String reason = bundle.getString("reason");
2038                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2039                            false, userId, reason);
2040                }
2041            } break;
2042            case FINALIZE_PENDING_INTENT_MSG: {
2043                ((PendingIntentRecord)msg.obj).completeFinalize();
2044            } break;
2045            case POST_HEAVY_NOTIFICATION_MSG: {
2046                INotificationManager inm = NotificationManager.getService();
2047                if (inm == null) {
2048                    return;
2049                }
2050
2051                ActivityRecord root = (ActivityRecord)msg.obj;
2052                ProcessRecord process = root.app;
2053                if (process == null) {
2054                    return;
2055                }
2056
2057                try {
2058                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2059                    String text = mContext.getString(R.string.heavy_weight_notification,
2060                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2061                    Notification notification =
2062                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2063                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2064                            .setWhen(0)
2065                            .setOngoing(true)
2066                            .setTicker(text)
2067                            .setColor(mContext.getColor(
2068                                    com.android.internal.R.color.system_notification_accent_color))
2069                            .setContentTitle(text)
2070                            .setContentText(
2071                                    mContext.getText(R.string.heavy_weight_notification_detail))
2072                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2073                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2074                                    new UserHandle(root.userId)))
2075                            .build();
2076                    try {
2077                        inm.enqueueNotificationWithTag("android", "android", null,
2078                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2079                                notification, root.userId);
2080                    } catch (RuntimeException e) {
2081                        Slog.w(ActivityManagerService.TAG,
2082                                "Error showing notification for heavy-weight app", e);
2083                    } catch (RemoteException e) {
2084                    }
2085                } catch (NameNotFoundException e) {
2086                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2087                }
2088            } break;
2089            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2090                INotificationManager inm = NotificationManager.getService();
2091                if (inm == null) {
2092                    return;
2093                }
2094                try {
2095                    inm.cancelNotificationWithTag("android", null,
2096                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2097                } catch (RuntimeException e) {
2098                    Slog.w(ActivityManagerService.TAG,
2099                            "Error canceling notification for service", e);
2100                } catch (RemoteException e) {
2101                }
2102            } break;
2103            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2104                synchronized (ActivityManagerService.this) {
2105                    checkExcessivePowerUsageLocked(true);
2106                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2107                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2108                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
2109                }
2110            } break;
2111            case REPORT_MEM_USAGE_MSG: {
2112                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2113                Thread thread = new Thread() {
2114                    @Override public void run() {
2115                        reportMemUsage(memInfos);
2116                    }
2117                };
2118                thread.start();
2119                break;
2120            }
2121            case START_USER_SWITCH_FG_MSG: {
2122                mUserController.startUserInForeground(msg.arg1);
2123                break;
2124            }
2125            case REPORT_USER_SWITCH_MSG: {
2126                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2127                break;
2128            }
2129            case CONTINUE_USER_SWITCH_MSG: {
2130                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2131                break;
2132            }
2133            case USER_SWITCH_TIMEOUT_MSG: {
2134                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2135                break;
2136            }
2137            case IMMERSIVE_MODE_LOCK_MSG: {
2138                final boolean nextState = (msg.arg1 != 0);
2139                if (mUpdateLock.isHeld() != nextState) {
2140                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2141                            "Applying new update lock state '" + nextState
2142                            + "' for " + (ActivityRecord)msg.obj);
2143                    if (nextState) {
2144                        mUpdateLock.acquire();
2145                    } else {
2146                        mUpdateLock.release();
2147                    }
2148                }
2149                break;
2150            }
2151            case PERSIST_URI_GRANTS_MSG: {
2152                writeGrantedUriPermissions();
2153                break;
2154            }
2155            case REQUEST_ALL_PSS_MSG: {
2156                synchronized (ActivityManagerService.this) {
2157                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2158                }
2159                break;
2160            }
2161            case START_PROFILES_MSG: {
2162                synchronized (ActivityManagerService.this) {
2163                    mUserController.startProfilesLocked();
2164                }
2165                break;
2166            }
2167            case UPDATE_TIME_PREFERENCE_MSG: {
2168                // The user's time format preference might have changed.
2169                // For convenience we re-use the Intent extra values.
2170                synchronized (ActivityManagerService.this) {
2171                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2172                        ProcessRecord r = mLruProcesses.get(i);
2173                        if (r.thread != null) {
2174                            try {
2175                                r.thread.updateTimePrefs(msg.arg1);
2176                            } catch (RemoteException ex) {
2177                                Slog.w(TAG, "Failed to update preferences for: "
2178                                        + r.info.processName);
2179                            }
2180                        }
2181                    }
2182                }
2183                break;
2184            }
2185            case SYSTEM_USER_START_MSG: {
2186                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2187                        Integer.toString(msg.arg1), msg.arg1);
2188                mSystemServiceManager.startUser(msg.arg1);
2189                break;
2190            }
2191            case SYSTEM_USER_UNLOCK_MSG: {
2192                final int userId = msg.arg1;
2193                mSystemServiceManager.unlockUser(userId);
2194                synchronized (ActivityManagerService.this) {
2195                    mRecentTasks.loadUserRecentsLocked(userId);
2196                }
2197                if (userId == UserHandle.USER_SYSTEM) {
2198                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2199                }
2200                installEncryptionUnawareProviders(userId);
2201                mUserController.finishUserUnlocked((UserState) msg.obj);
2202                break;
2203            }
2204            case SYSTEM_USER_CURRENT_MSG: {
2205                mBatteryStatsService.noteEvent(
2206                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2207                        Integer.toString(msg.arg2), msg.arg2);
2208                mBatteryStatsService.noteEvent(
2209                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2210                        Integer.toString(msg.arg1), msg.arg1);
2211                mSystemServiceManager.switchUser(msg.arg1);
2212                break;
2213            }
2214            case ENTER_ANIMATION_COMPLETE_MSG: {
2215                synchronized (ActivityManagerService.this) {
2216                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2217                    if (r != null && r.app != null && r.app.thread != null) {
2218                        try {
2219                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2220                        } catch (RemoteException e) {
2221                        }
2222                    }
2223                }
2224                break;
2225            }
2226            case FINISH_BOOTING_MSG: {
2227                if (msg.arg1 != 0) {
2228                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2229                    finishBooting();
2230                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2231                }
2232                if (msg.arg2 != 0) {
2233                    enableScreenAfterBoot();
2234                }
2235                break;
2236            }
2237            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2238                try {
2239                    Locale l = (Locale) msg.obj;
2240                    IBinder service = ServiceManager.getService("mount");
2241                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2242                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2243                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2244                } catch (RemoteException e) {
2245                    Log.e(TAG, "Error storing locale for decryption UI", e);
2246                }
2247                break;
2248            }
2249            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2250                final int uid = msg.arg1;
2251                final byte[] firstPacket = (byte[]) msg.obj;
2252
2253                synchronized (mPidsSelfLocked) {
2254                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2255                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2256                        if (p.uid == uid) {
2257                            try {
2258                                p.thread.notifyCleartextNetwork(firstPacket);
2259                            } catch (RemoteException ignored) {
2260                            }
2261                        }
2262                    }
2263                }
2264                break;
2265            }
2266            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2267                final String procName;
2268                final int uid;
2269                final long memLimit;
2270                final String reportPackage;
2271                synchronized (ActivityManagerService.this) {
2272                    procName = mMemWatchDumpProcName;
2273                    uid = mMemWatchDumpUid;
2274                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2275                    if (val == null) {
2276                        val = mMemWatchProcesses.get(procName, 0);
2277                    }
2278                    if (val != null) {
2279                        memLimit = val.first;
2280                        reportPackage = val.second;
2281                    } else {
2282                        memLimit = 0;
2283                        reportPackage = null;
2284                    }
2285                }
2286                if (procName == null) {
2287                    return;
2288                }
2289
2290                if (DEBUG_PSS) Slog.d(TAG_PSS,
2291                        "Showing dump heap notification from " + procName + "/" + uid);
2292
2293                INotificationManager inm = NotificationManager.getService();
2294                if (inm == null) {
2295                    return;
2296                }
2297
2298                String text = mContext.getString(R.string.dump_heap_notification, procName);
2299
2300
2301                Intent deleteIntent = new Intent();
2302                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2303                Intent intent = new Intent();
2304                intent.setClassName("android", DumpHeapActivity.class.getName());
2305                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2306                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2307                if (reportPackage != null) {
2308                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2309                }
2310                int userId = UserHandle.getUserId(uid);
2311                Notification notification =
2312                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2313                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2314                        .setWhen(0)
2315                        .setOngoing(true)
2316                        .setAutoCancel(true)
2317                        .setTicker(text)
2318                        .setColor(mContext.getColor(
2319                                com.android.internal.R.color.system_notification_accent_color))
2320                        .setContentTitle(text)
2321                        .setContentText(
2322                                mContext.getText(R.string.dump_heap_notification_detail))
2323                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2324                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2325                                new UserHandle(userId)))
2326                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2327                                deleteIntent, 0, UserHandle.SYSTEM))
2328                        .build();
2329
2330                try {
2331                    inm.enqueueNotificationWithTag("android", "android", null,
2332                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2333                            notification, userId);
2334                } catch (RuntimeException e) {
2335                    Slog.w(ActivityManagerService.TAG,
2336                            "Error showing notification for dump heap", e);
2337                } catch (RemoteException e) {
2338                }
2339            } break;
2340            case DELETE_DUMPHEAP_MSG: {
2341                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2342                        null, DumpHeapActivity.JAVA_URI,
2343                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2344                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2345                        UserHandle.myUserId());
2346                synchronized (ActivityManagerService.this) {
2347                    mMemWatchDumpFile = null;
2348                    mMemWatchDumpProcName = null;
2349                    mMemWatchDumpPid = -1;
2350                    mMemWatchDumpUid = -1;
2351                }
2352            } break;
2353            case FOREGROUND_PROFILE_CHANGED_MSG: {
2354                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2355            } break;
2356            case REPORT_TIME_TRACKER_MSG: {
2357                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2358                tracker.deliverResult(mContext);
2359            } break;
2360            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2361                mUserController.dispatchUserSwitchComplete(msg.arg1);
2362            } break;
2363            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2364                mUserController.dispatchLockedBootComplete(msg.arg1);
2365            } break;
2366            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2367                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2368                try {
2369                    connection.shutdown();
2370                } catch (RemoteException e) {
2371                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2372                }
2373                // Only a UiAutomation can set this flag and now that
2374                // it is finished we make sure it is reset to its default.
2375                mUserIsMonkey = false;
2376            } break;
2377            case IDLE_UIDS_MSG: {
2378                idleUids();
2379            } break;
2380            case VR_MODE_CHANGE_MSG: {
2381                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2382                    return;
2383                }
2384                synchronized (ActivityManagerService.this) {
2385                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2386                    mWindowManager.disableNonVrUi(disableNonVrUi);
2387                    if (disableNonVrUi) {
2388                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2389                        // then remove the pinned stack.
2390                        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2391                                PINNED_STACK_ID);
2392                        if (pinnedStack != null) {
2393                            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2394                        }
2395                    }
2396                }
2397            } break;
2398            case NOTIFY_VR_SLEEPING_MSG: {
2399                notifyVrManagerOfSleepState(msg.arg1 != 0);
2400            } break;
2401            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2402                synchronized (ActivityManagerService.this) {
2403                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2404                        ProcessRecord r = mLruProcesses.get(i);
2405                        if (r.thread != null) {
2406                            try {
2407                                r.thread.handleTrustStorageUpdate();
2408                            } catch (RemoteException ex) {
2409                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2410                                        r.info.processName);
2411                            }
2412                        }
2413                    }
2414                }
2415            } break;
2416            }
2417        }
2418    };
2419
2420    static final int COLLECT_PSS_BG_MSG = 1;
2421
2422    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2423        @Override
2424        public void handleMessage(Message msg) {
2425            switch (msg.what) {
2426            case COLLECT_PSS_BG_MSG: {
2427                long start = SystemClock.uptimeMillis();
2428                MemInfoReader memInfo = null;
2429                synchronized (ActivityManagerService.this) {
2430                    if (mFullPssPending) {
2431                        mFullPssPending = false;
2432                        memInfo = new MemInfoReader();
2433                    }
2434                }
2435                if (memInfo != null) {
2436                    updateCpuStatsNow();
2437                    long nativeTotalPss = 0;
2438                    final List<ProcessCpuTracker.Stats> stats;
2439                    synchronized (mProcessCpuTracker) {
2440                        stats = mProcessCpuTracker.getStats( (st)-> {
2441                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2442                        });
2443                    }
2444                    final int N = stats.size();
2445                    for (int j = 0; j < N; j++) {
2446                        synchronized (mPidsSelfLocked) {
2447                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2448                                // This is one of our own processes; skip it.
2449                                continue;
2450                            }
2451                        }
2452                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2453                    }
2454                    memInfo.readMemInfo();
2455                    synchronized (ActivityManagerService.this) {
2456                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2457                                + (SystemClock.uptimeMillis()-start) + "ms");
2458                        final long cachedKb = memInfo.getCachedSizeKb();
2459                        final long freeKb = memInfo.getFreeSizeKb();
2460                        final long zramKb = memInfo.getZramTotalSizeKb();
2461                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2462                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2463                                kernelKb*1024, nativeTotalPss*1024);
2464                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2465                                nativeTotalPss);
2466                    }
2467                }
2468
2469                int num = 0;
2470                long[] tmp = new long[2];
2471                do {
2472                    ProcessRecord proc;
2473                    int procState;
2474                    int pid;
2475                    long lastPssTime;
2476                    synchronized (ActivityManagerService.this) {
2477                        if (mPendingPssProcesses.size() <= 0) {
2478                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2479                                    "Collected PSS of " + num + " processes in "
2480                                    + (SystemClock.uptimeMillis() - start) + "ms");
2481                            mPendingPssProcesses.clear();
2482                            return;
2483                        }
2484                        proc = mPendingPssProcesses.remove(0);
2485                        procState = proc.pssProcState;
2486                        lastPssTime = proc.lastPssTime;
2487                        if (proc.thread != null && procState == proc.setProcState
2488                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2489                                        < SystemClock.uptimeMillis()) {
2490                            pid = proc.pid;
2491                        } else {
2492                            proc = null;
2493                            pid = 0;
2494                        }
2495                    }
2496                    if (proc != null) {
2497                        long pss = Debug.getPss(pid, tmp, null);
2498                        synchronized (ActivityManagerService.this) {
2499                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2500                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2501                                num++;
2502                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2503                                        SystemClock.uptimeMillis());
2504                            }
2505                        }
2506                    }
2507                } while (true);
2508            }
2509            }
2510        }
2511    };
2512
2513    public void setSystemProcess() {
2514        try {
2515            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2516            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2517            ServiceManager.addService("meminfo", new MemBinder(this));
2518            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2519            ServiceManager.addService("dbinfo", new DbBinder(this));
2520            if (MONITOR_CPU_USAGE) {
2521                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2522            }
2523            ServiceManager.addService("permission", new PermissionController(this));
2524            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2525
2526            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2527                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2528            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2529
2530            synchronized (this) {
2531                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2532                app.persistent = true;
2533                app.pid = MY_PID;
2534                app.maxAdj = ProcessList.SYSTEM_ADJ;
2535                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2536                synchronized (mPidsSelfLocked) {
2537                    mPidsSelfLocked.put(app.pid, app);
2538                }
2539                updateLruProcessLocked(app, false, null);
2540                updateOomAdjLocked();
2541            }
2542        } catch (PackageManager.NameNotFoundException e) {
2543            throw new RuntimeException(
2544                    "Unable to find android system package", e);
2545        }
2546    }
2547
2548    public void setWindowManager(WindowManagerService wm) {
2549        mWindowManager = wm;
2550        mStackSupervisor.setWindowManager(wm);
2551        mActivityStarter.setWindowManager(wm);
2552    }
2553
2554    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2555        mUsageStatsService = usageStatsManager;
2556    }
2557
2558    public void startObservingNativeCrashes() {
2559        final NativeCrashListener ncl = new NativeCrashListener(this);
2560        ncl.start();
2561    }
2562
2563    public IAppOpsService getAppOpsService() {
2564        return mAppOpsService;
2565    }
2566
2567    static class MemBinder extends Binder {
2568        ActivityManagerService mActivityManagerService;
2569        MemBinder(ActivityManagerService activityManagerService) {
2570            mActivityManagerService = activityManagerService;
2571        }
2572
2573        @Override
2574        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2575            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2576                    "meminfo", pw)) return;
2577            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2578        }
2579    }
2580
2581    static class GraphicsBinder extends Binder {
2582        ActivityManagerService mActivityManagerService;
2583        GraphicsBinder(ActivityManagerService activityManagerService) {
2584            mActivityManagerService = activityManagerService;
2585        }
2586
2587        @Override
2588        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2589            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2590                    "gfxinfo", pw)) return;
2591            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2592        }
2593    }
2594
2595    static class DbBinder extends Binder {
2596        ActivityManagerService mActivityManagerService;
2597        DbBinder(ActivityManagerService activityManagerService) {
2598            mActivityManagerService = activityManagerService;
2599        }
2600
2601        @Override
2602        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2603            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2604                    "dbinfo", pw)) return;
2605            mActivityManagerService.dumpDbInfo(fd, pw, args);
2606        }
2607    }
2608
2609    static class CpuBinder extends Binder {
2610        ActivityManagerService mActivityManagerService;
2611        CpuBinder(ActivityManagerService activityManagerService) {
2612            mActivityManagerService = activityManagerService;
2613        }
2614
2615        @Override
2616        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2617            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2618                    "cpuinfo", pw)) return;
2619            synchronized (mActivityManagerService.mProcessCpuTracker) {
2620                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2621                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2622                        SystemClock.uptimeMillis()));
2623            }
2624        }
2625    }
2626
2627    public static final class Lifecycle extends SystemService {
2628        private final ActivityManagerService mService;
2629
2630        public Lifecycle(Context context) {
2631            super(context);
2632            mService = new ActivityManagerService(context);
2633        }
2634
2635        @Override
2636        public void onStart() {
2637            mService.start();
2638        }
2639
2640        public ActivityManagerService getService() {
2641            return mService;
2642        }
2643    }
2644
2645    @VisibleForTesting
2646    public ActivityManagerService(Injector injector) {
2647        mInjector = injector;
2648        mContext = mInjector.getContext();
2649        mUiContext = null;
2650        GL_ES_VERSION = 0;
2651        mActivityStarter = null;
2652        mAppErrors = null;
2653        mAppOpsService = mInjector.getAppOpsService(null, null);
2654        mBatteryStatsService = null;
2655        mCompatModePackages = null;
2656        mConstants = null;
2657        mGrantFile = null;
2658        mHandler = null;
2659        mHandlerThread = null;
2660        mIntentFirewall = null;
2661        mKeyguardController = null;
2662        mPermissionReviewRequired = false;
2663        mProcessCpuThread = null;
2664        mProcessStats = null;
2665        mProviderMap = null;
2666        mRecentTasks = null;
2667        mServices = null;
2668        mStackSupervisor = null;
2669        mSystemThread = null;
2670        mTaskChangeNotificationController = null;
2671        mUiHandler = injector.getUiHandler(null);
2672        mUserController = null;
2673        mVrController = null;
2674    }
2675
2676    // Note: This method is invoked on the main thread but may need to attach various
2677    // handlers to other threads.  So take care to be explicit about the looper.
2678    public ActivityManagerService(Context systemContext) {
2679        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2680        mInjector = new Injector();
2681        mContext = systemContext;
2682
2683        mFactoryTest = FactoryTest.getMode();
2684        mSystemThread = ActivityThread.currentActivityThread();
2685        mUiContext = mSystemThread.getSystemUiContext();
2686
2687        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2688
2689        mPermissionReviewRequired = mContext.getResources().getBoolean(
2690                com.android.internal.R.bool.config_permissionReviewRequired);
2691
2692        mHandlerThread = new ServiceThread(TAG,
2693                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2694        mHandlerThread.start();
2695        mHandler = new MainHandler(mHandlerThread.getLooper());
2696        mUiHandler = mInjector.getUiHandler(this);
2697
2698        mConstants = new ActivityManagerConstants(this, mHandler);
2699
2700        /* static; one-time init here */
2701        if (sKillHandler == null) {
2702            sKillThread = new ServiceThread(TAG + ":kill",
2703                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2704            sKillThread.start();
2705            sKillHandler = new KillHandler(sKillThread.getLooper());
2706        }
2707
2708        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2709                "foreground", BROADCAST_FG_TIMEOUT, false);
2710        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2711                "background", BROADCAST_BG_TIMEOUT, true);
2712        mBroadcastQueues[0] = mFgBroadcastQueue;
2713        mBroadcastQueues[1] = mBgBroadcastQueue;
2714
2715        mServices = new ActiveServices(this);
2716        mProviderMap = new ProviderMap(this);
2717        mAppErrors = new AppErrors(mUiContext, this);
2718
2719        // TODO: Move creation of battery stats service outside of activity manager service.
2720        File dataDir = Environment.getDataDirectory();
2721        File systemDir = new File(dataDir, "system");
2722        systemDir.mkdirs();
2723        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2724        mBatteryStatsService.getActiveStatistics().readLocked();
2725        mBatteryStatsService.scheduleWriteToDisk();
2726        mOnBattery = DEBUG_POWER ? true
2727                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2728        mBatteryStatsService.getActiveStatistics().setCallback(this);
2729
2730        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2731
2732        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2733        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2734                new IAppOpsCallback.Stub() {
2735                    @Override public void opChanged(int op, int uid, String packageName) {
2736                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2737                            if (mAppOpsService.checkOperation(op, uid, packageName)
2738                                    != AppOpsManager.MODE_ALLOWED) {
2739                                runInBackgroundDisabled(uid);
2740                            }
2741                        }
2742                    }
2743                });
2744
2745        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2746
2747        mUserController = new UserController(this);
2748
2749        mVrController = new VrController(this);
2750
2751        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2752            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2753
2754        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2755            mUseFifoUiScheduling = true;
2756        }
2757
2758        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2759        mTempConfig.setToDefaults();
2760        mTempConfig.setLocales(LocaleList.getDefault());
2761        mConfigurationSeq = mTempConfig.seq = 1;
2762        mStackSupervisor = createStackSupervisor();
2763        mStackSupervisor.onConfigurationChanged(mTempConfig);
2764        mKeyguardController = mStackSupervisor.mKeyguardController;
2765        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2766        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2767        mTaskChangeNotificationController =
2768                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2769        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2770        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2771
2772        mProcessCpuThread = new Thread("CpuTracker") {
2773            @Override
2774            public void run() {
2775                synchronized (mProcessCpuTracker) {
2776                    mProcessCpuInitLatch.countDown();
2777                    mProcessCpuTracker.init();
2778                }
2779                while (true) {
2780                    try {
2781                        try {
2782                            synchronized(this) {
2783                                final long now = SystemClock.uptimeMillis();
2784                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2785                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2786                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2787                                //        + ", write delay=" + nextWriteDelay);
2788                                if (nextWriteDelay < nextCpuDelay) {
2789                                    nextCpuDelay = nextWriteDelay;
2790                                }
2791                                if (nextCpuDelay > 0) {
2792                                    mProcessCpuMutexFree.set(true);
2793                                    this.wait(nextCpuDelay);
2794                                }
2795                            }
2796                        } catch (InterruptedException e) {
2797                        }
2798                        updateCpuStatsNow();
2799                    } catch (Exception e) {
2800                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2801                    }
2802                }
2803            }
2804        };
2805
2806        Watchdog.getInstance().addMonitor(this);
2807        Watchdog.getInstance().addThread(mHandler);
2808    }
2809
2810    protected ActivityStackSupervisor createStackSupervisor() {
2811        return new ActivityStackSupervisor(this, mHandler.getLooper());
2812    }
2813
2814    public void setSystemServiceManager(SystemServiceManager mgr) {
2815        mSystemServiceManager = mgr;
2816    }
2817
2818    public void setInstaller(Installer installer) {
2819        mInstaller = installer;
2820    }
2821
2822    private void start() {
2823        removeAllProcessGroups();
2824        mProcessCpuThread.start();
2825
2826        mBatteryStatsService.publish(mContext);
2827        mAppOpsService.publish(mContext);
2828        Slog.d("AppOps", "AppOpsService published");
2829        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2830        // Wait for the synchronized block started in mProcessCpuThread,
2831        // so that any other acccess to mProcessCpuTracker from main thread
2832        // will be blocked during mProcessCpuTracker initialization.
2833        try {
2834            mProcessCpuInitLatch.await();
2835        } catch (InterruptedException e) {
2836            Slog.wtf(TAG, "Interrupted wait during start", e);
2837            Thread.currentThread().interrupt();
2838            throw new IllegalStateException("Interrupted wait during start");
2839        }
2840    }
2841
2842    void onUserStoppedLocked(int userId) {
2843        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2844    }
2845
2846    public void initPowerManagement() {
2847        mStackSupervisor.initPowerManagement();
2848        mBatteryStatsService.initPowerManagement();
2849        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2850        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2851        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2852        mVoiceWakeLock.setReferenceCounted(false);
2853    }
2854
2855    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2856        if (mBackgroundLaunchBroadcasts == null) {
2857            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2858        }
2859        return mBackgroundLaunchBroadcasts;
2860    }
2861
2862    @Override
2863    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2864            throws RemoteException {
2865        if (code == SYSPROPS_TRANSACTION) {
2866            // We need to tell all apps about the system property change.
2867            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2868            synchronized(this) {
2869                final int NP = mProcessNames.getMap().size();
2870                for (int ip=0; ip<NP; ip++) {
2871                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2872                    final int NA = apps.size();
2873                    for (int ia=0; ia<NA; ia++) {
2874                        ProcessRecord app = apps.valueAt(ia);
2875                        if (app.thread != null) {
2876                            procs.add(app.thread.asBinder());
2877                        }
2878                    }
2879                }
2880            }
2881
2882            int N = procs.size();
2883            for (int i=0; i<N; i++) {
2884                Parcel data2 = Parcel.obtain();
2885                try {
2886                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2887                            Binder.FLAG_ONEWAY);
2888                } catch (RemoteException e) {
2889                }
2890                data2.recycle();
2891            }
2892        }
2893        try {
2894            return super.onTransact(code, data, reply, flags);
2895        } catch (RuntimeException e) {
2896            // The activity manager only throws security exceptions, so let's
2897            // log all others.
2898            if (!(e instanceof SecurityException)) {
2899                Slog.wtf(TAG, "Activity Manager Crash", e);
2900            }
2901            throw e;
2902        }
2903    }
2904
2905    void updateCpuStats() {
2906        final long now = SystemClock.uptimeMillis();
2907        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2908            return;
2909        }
2910        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2911            synchronized (mProcessCpuThread) {
2912                mProcessCpuThread.notify();
2913            }
2914        }
2915    }
2916
2917    void updateCpuStatsNow() {
2918        synchronized (mProcessCpuTracker) {
2919            mProcessCpuMutexFree.set(false);
2920            final long now = SystemClock.uptimeMillis();
2921            boolean haveNewCpuStats = false;
2922
2923            if (MONITOR_CPU_USAGE &&
2924                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2925                mLastCpuTime.set(now);
2926                mProcessCpuTracker.update();
2927                if (mProcessCpuTracker.hasGoodLastStats()) {
2928                    haveNewCpuStats = true;
2929                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2930                    //Slog.i(TAG, "Total CPU usage: "
2931                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2932
2933                    // Slog the cpu usage if the property is set.
2934                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2935                        int user = mProcessCpuTracker.getLastUserTime();
2936                        int system = mProcessCpuTracker.getLastSystemTime();
2937                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2938                        int irq = mProcessCpuTracker.getLastIrqTime();
2939                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2940                        int idle = mProcessCpuTracker.getLastIdleTime();
2941
2942                        int total = user + system + iowait + irq + softIrq + idle;
2943                        if (total == 0) total = 1;
2944
2945                        EventLog.writeEvent(EventLogTags.CPU,
2946                                ((user+system+iowait+irq+softIrq) * 100) / total,
2947                                (user * 100) / total,
2948                                (system * 100) / total,
2949                                (iowait * 100) / total,
2950                                (irq * 100) / total,
2951                                (softIrq * 100) / total);
2952                    }
2953                }
2954            }
2955
2956            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2957            synchronized(bstats) {
2958                synchronized(mPidsSelfLocked) {
2959                    if (haveNewCpuStats) {
2960                        if (bstats.startAddingCpuLocked()) {
2961                            int totalUTime = 0;
2962                            int totalSTime = 0;
2963                            final int N = mProcessCpuTracker.countStats();
2964                            for (int i=0; i<N; i++) {
2965                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2966                                if (!st.working) {
2967                                    continue;
2968                                }
2969                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2970                                totalUTime += st.rel_utime;
2971                                totalSTime += st.rel_stime;
2972                                if (pr != null) {
2973                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2974                                    if (ps == null || !ps.isActive()) {
2975                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2976                                                pr.info.uid, pr.processName);
2977                                    }
2978                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2979                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2980                                } else {
2981                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2982                                    if (ps == null || !ps.isActive()) {
2983                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2984                                                bstats.mapUid(st.uid), st.name);
2985                                    }
2986                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2987                                }
2988                            }
2989                            final int userTime = mProcessCpuTracker.getLastUserTime();
2990                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2991                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2992                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2993                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2994                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2995                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2996                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2997                        }
2998                    }
2999                }
3000
3001                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3002                    mLastWriteTime = now;
3003                    mBatteryStatsService.scheduleWriteToDisk();
3004                }
3005            }
3006        }
3007    }
3008
3009    @Override
3010    public void batteryNeedsCpuUpdate() {
3011        updateCpuStatsNow();
3012    }
3013
3014    @Override
3015    public void batteryPowerChanged(boolean onBattery) {
3016        // When plugging in, update the CPU stats first before changing
3017        // the plug state.
3018        updateCpuStatsNow();
3019        synchronized (this) {
3020            synchronized(mPidsSelfLocked) {
3021                mOnBattery = DEBUG_POWER ? true : onBattery;
3022            }
3023        }
3024    }
3025
3026    @Override
3027    public void batterySendBroadcast(Intent intent) {
3028        synchronized (this) {
3029            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3030                    AppOpsManager.OP_NONE, null, false, false,
3031                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3032        }
3033    }
3034
3035    /**
3036     * Initialize the application bind args. These are passed to each
3037     * process when the bindApplication() IPC is sent to the process. They're
3038     * lazily setup to make sure the services are running when they're asked for.
3039     */
3040    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3041        // Isolated processes won't get this optimization, so that we don't
3042        // violate the rules about which services they have access to.
3043        if (isolated) {
3044            if (mIsolatedAppBindArgs == null) {
3045                mIsolatedAppBindArgs = new HashMap<>();
3046                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3047            }
3048            return mIsolatedAppBindArgs;
3049        }
3050
3051        if (mAppBindArgs == null) {
3052            mAppBindArgs = new HashMap<>();
3053
3054            // Setup the application init args
3055            mAppBindArgs.put("package", ServiceManager.getService("package"));
3056            mAppBindArgs.put("window", ServiceManager.getService("window"));
3057            mAppBindArgs.put(Context.ALARM_SERVICE,
3058                    ServiceManager.getService(Context.ALARM_SERVICE));
3059        }
3060        return mAppBindArgs;
3061    }
3062
3063    /**
3064     * Update AMS states when an activity is resumed. This should only be called by
3065     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3066     */
3067    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3068        final TaskRecord task = r.getTask();
3069        if (task.isApplicationTask()) {
3070            if (mCurAppTimeTracker != r.appTimeTracker) {
3071                // We are switching app tracking.  Complete the current one.
3072                if (mCurAppTimeTracker != null) {
3073                    mCurAppTimeTracker.stop();
3074                    mHandler.obtainMessage(
3075                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3076                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3077                    mCurAppTimeTracker = null;
3078                }
3079                if (r.appTimeTracker != null) {
3080                    mCurAppTimeTracker = r.appTimeTracker;
3081                    startTimeTrackingFocusedActivityLocked();
3082                }
3083            } else {
3084                startTimeTrackingFocusedActivityLocked();
3085            }
3086        } else {
3087            r.appTimeTracker = null;
3088        }
3089        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3090        // TODO: Probably not, because we don't want to resume voice on switching
3091        // back to this activity
3092        if (task.voiceInteractor != null) {
3093            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3094        } else {
3095            finishRunningVoiceLocked();
3096
3097            if (mLastResumedActivity != null) {
3098                final IVoiceInteractionSession session;
3099
3100                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3101                if (lastResumedActivityTask != null
3102                        && lastResumedActivityTask.voiceSession != null) {
3103                    session = lastResumedActivityTask.voiceSession;
3104                } else {
3105                    session = mLastResumedActivity.voiceSession;
3106                }
3107
3108                if (session != null) {
3109                    // We had been in a voice interaction session, but now focused has
3110                    // move to something different.  Just finish the session, we can't
3111                    // return to it and retain the proper state and synchronization with
3112                    // the voice interaction service.
3113                    finishVoiceTask(session);
3114                }
3115            }
3116        }
3117
3118        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3119            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3120            mHandler.obtainMessage(
3121                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3122        }
3123        mLastResumedActivity = r;
3124
3125        mWindowManager.setFocusedApp(r.appToken, true);
3126
3127        applyUpdateLockStateLocked(r);
3128        applyUpdateVrModeLocked(r);
3129
3130        EventLogTags.writeAmSetResumedActivity(
3131                r == null ? -1 : r.userId,
3132                r == null ? "NULL" : r.shortComponentName,
3133                reason);
3134    }
3135
3136    @Override
3137    public void setFocusedStack(int stackId) {
3138        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3139        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3140        final long callingId = Binder.clearCallingIdentity();
3141        try {
3142            synchronized (this) {
3143                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3144                if (stack == null) {
3145                    return;
3146                }
3147                final ActivityRecord r = stack.topRunningActivityLocked();
3148                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3149                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3150                }
3151            }
3152        } finally {
3153            Binder.restoreCallingIdentity(callingId);
3154        }
3155    }
3156
3157    @Override
3158    public void setFocusedTask(int taskId) {
3159        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3160        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3161        final long callingId = Binder.clearCallingIdentity();
3162        try {
3163            synchronized (this) {
3164                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3165                if (task == null) {
3166                    return;
3167                }
3168                final ActivityRecord r = task.topRunningActivityLocked();
3169                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3170                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3171                }
3172            }
3173        } finally {
3174            Binder.restoreCallingIdentity(callingId);
3175        }
3176    }
3177
3178    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3179    @Override
3180    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3181        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3182        mTaskChangeNotificationController.registerTaskStackListener(listener);
3183    }
3184
3185    /**
3186     * Unregister a task stack listener so that it stops receiving callbacks.
3187     */
3188    @Override
3189    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3190         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3191         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3192     }
3193
3194    @Override
3195    public void notifyActivityDrawn(IBinder token) {
3196        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3197        synchronized (this) {
3198            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3199            if (r != null) {
3200                r.getStack().notifyActivityDrawnLocked(r);
3201            }
3202        }
3203    }
3204
3205    final void applyUpdateLockStateLocked(ActivityRecord r) {
3206        // Modifications to the UpdateLock state are done on our handler, outside
3207        // the activity manager's locks.  The new state is determined based on the
3208        // state *now* of the relevant activity record.  The object is passed to
3209        // the handler solely for logging detail, not to be consulted/modified.
3210        final boolean nextState = r != null && r.immersive;
3211        mHandler.sendMessage(
3212                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3213    }
3214
3215    final void applyUpdateVrModeLocked(ActivityRecord r) {
3216        mHandler.sendMessage(
3217                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3218    }
3219
3220    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3221        mHandler.sendMessage(
3222                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3223    }
3224
3225    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3226        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3227        if (vrService == null) {
3228            return;
3229        }
3230        vrService.onSleepStateChanged(isSleeping);
3231    }
3232
3233    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3234        Message msg = Message.obtain();
3235        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3236        msg.obj = r.getTask().askedCompatMode ? null : r;
3237        mUiHandler.sendMessage(msg);
3238    }
3239
3240    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3241        final Configuration globalConfig = getGlobalConfiguration();
3242        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3243                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3244            final Message msg = Message.obtain();
3245            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3246            msg.obj = r;
3247            mUiHandler.sendMessage(msg);
3248        }
3249    }
3250
3251    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3252            String what, Object obj, ProcessRecord srcApp) {
3253        app.lastActivityTime = now;
3254
3255        if (app.activities.size() > 0) {
3256            // Don't want to touch dependent processes that are hosting activities.
3257            return index;
3258        }
3259
3260        int lrui = mLruProcesses.lastIndexOf(app);
3261        if (lrui < 0) {
3262            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3263                    + what + " " + obj + " from " + srcApp);
3264            return index;
3265        }
3266
3267        if (lrui >= index) {
3268            // Don't want to cause this to move dependent processes *back* in the
3269            // list as if they were less frequently used.
3270            return index;
3271        }
3272
3273        if (lrui >= mLruProcessActivityStart) {
3274            // Don't want to touch dependent processes that are hosting activities.
3275            return index;
3276        }
3277
3278        mLruProcesses.remove(lrui);
3279        if (index > 0) {
3280            index--;
3281        }
3282        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3283                + " in LRU list: " + app);
3284        mLruProcesses.add(index, app);
3285        return index;
3286    }
3287
3288    static void killProcessGroup(int uid, int pid) {
3289        if (sKillHandler != null) {
3290            sKillHandler.sendMessage(
3291                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3292        } else {
3293            Slog.w(TAG, "Asked to kill process group before system bringup!");
3294            Process.killProcessGroup(uid, pid);
3295        }
3296    }
3297
3298    final void removeLruProcessLocked(ProcessRecord app) {
3299        int lrui = mLruProcesses.lastIndexOf(app);
3300        if (lrui >= 0) {
3301            if (!app.killed) {
3302                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3303                killProcessQuiet(app.pid);
3304                killProcessGroup(app.uid, app.pid);
3305            }
3306            if (lrui <= mLruProcessActivityStart) {
3307                mLruProcessActivityStart--;
3308            }
3309            if (lrui <= mLruProcessServiceStart) {
3310                mLruProcessServiceStart--;
3311            }
3312            mLruProcesses.remove(lrui);
3313        }
3314    }
3315
3316    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3317            ProcessRecord client) {
3318        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3319                || app.treatLikeActivity;
3320        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3321        if (!activityChange && hasActivity) {
3322            // The process has activities, so we are only allowing activity-based adjustments
3323            // to move it.  It should be kept in the front of the list with other
3324            // processes that have activities, and we don't want those to change their
3325            // order except due to activity operations.
3326            return;
3327        }
3328
3329        mLruSeq++;
3330        final long now = SystemClock.uptimeMillis();
3331        app.lastActivityTime = now;
3332
3333        // First a quick reject: if the app is already at the position we will
3334        // put it, then there is nothing to do.
3335        if (hasActivity) {
3336            final int N = mLruProcesses.size();
3337            if (N > 0 && mLruProcesses.get(N-1) == app) {
3338                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3339                return;
3340            }
3341        } else {
3342            if (mLruProcessServiceStart > 0
3343                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3344                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3345                return;
3346            }
3347        }
3348
3349        int lrui = mLruProcesses.lastIndexOf(app);
3350
3351        if (app.persistent && lrui >= 0) {
3352            // We don't care about the position of persistent processes, as long as
3353            // they are in the list.
3354            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3355            return;
3356        }
3357
3358        /* In progress: compute new position first, so we can avoid doing work
3359           if the process is not actually going to move.  Not yet working.
3360        int addIndex;
3361        int nextIndex;
3362        boolean inActivity = false, inService = false;
3363        if (hasActivity) {
3364            // Process has activities, put it at the very tipsy-top.
3365            addIndex = mLruProcesses.size();
3366            nextIndex = mLruProcessServiceStart;
3367            inActivity = true;
3368        } else if (hasService) {
3369            // Process has services, put it at the top of the service list.
3370            addIndex = mLruProcessActivityStart;
3371            nextIndex = mLruProcessServiceStart;
3372            inActivity = true;
3373            inService = true;
3374        } else  {
3375            // Process not otherwise of interest, it goes to the top of the non-service area.
3376            addIndex = mLruProcessServiceStart;
3377            if (client != null) {
3378                int clientIndex = mLruProcesses.lastIndexOf(client);
3379                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3380                        + app);
3381                if (clientIndex >= 0 && addIndex > clientIndex) {
3382                    addIndex = clientIndex;
3383                }
3384            }
3385            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3386        }
3387
3388        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3389                + mLruProcessActivityStart + "): " + app);
3390        */
3391
3392        if (lrui >= 0) {
3393            if (lrui < mLruProcessActivityStart) {
3394                mLruProcessActivityStart--;
3395            }
3396            if (lrui < mLruProcessServiceStart) {
3397                mLruProcessServiceStart--;
3398            }
3399            /*
3400            if (addIndex > lrui) {
3401                addIndex--;
3402            }
3403            if (nextIndex > lrui) {
3404                nextIndex--;
3405            }
3406            */
3407            mLruProcesses.remove(lrui);
3408        }
3409
3410        /*
3411        mLruProcesses.add(addIndex, app);
3412        if (inActivity) {
3413            mLruProcessActivityStart++;
3414        }
3415        if (inService) {
3416            mLruProcessActivityStart++;
3417        }
3418        */
3419
3420        int nextIndex;
3421        if (hasActivity) {
3422            final int N = mLruProcesses.size();
3423            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3424                // Process doesn't have activities, but has clients with
3425                // activities...  move it up, but one below the top (the top
3426                // should always have a real activity).
3427                if (DEBUG_LRU) Slog.d(TAG_LRU,
3428                        "Adding to second-top of LRU activity list: " + app);
3429                mLruProcesses.add(N - 1, app);
3430                // To keep it from spamming the LRU list (by making a bunch of clients),
3431                // we will push down any other entries owned by the app.
3432                final int uid = app.info.uid;
3433                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3434                    ProcessRecord subProc = mLruProcesses.get(i);
3435                    if (subProc.info.uid == uid) {
3436                        // We want to push this one down the list.  If the process after
3437                        // it is for the same uid, however, don't do so, because we don't
3438                        // want them internally to be re-ordered.
3439                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3440                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3441                                    "Pushing uid " + uid + " swapping at " + i + ": "
3442                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3443                            ProcessRecord tmp = mLruProcesses.get(i);
3444                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3445                            mLruProcesses.set(i - 1, tmp);
3446                            i--;
3447                        }
3448                    } else {
3449                        // A gap, we can stop here.
3450                        break;
3451                    }
3452                }
3453            } else {
3454                // Process has activities, put it at the very tipsy-top.
3455                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3456                mLruProcesses.add(app);
3457            }
3458            nextIndex = mLruProcessServiceStart;
3459        } else if (hasService) {
3460            // Process has services, put it at the top of the service list.
3461            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3462            mLruProcesses.add(mLruProcessActivityStart, app);
3463            nextIndex = mLruProcessServiceStart;
3464            mLruProcessActivityStart++;
3465        } else  {
3466            // Process not otherwise of interest, it goes to the top of the non-service area.
3467            int index = mLruProcessServiceStart;
3468            if (client != null) {
3469                // If there is a client, don't allow the process to be moved up higher
3470                // in the list than that client.
3471                int clientIndex = mLruProcesses.lastIndexOf(client);
3472                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3473                        + " when updating " + app);
3474                if (clientIndex <= lrui) {
3475                    // Don't allow the client index restriction to push it down farther in the
3476                    // list than it already is.
3477                    clientIndex = lrui;
3478                }
3479                if (clientIndex >= 0 && index > clientIndex) {
3480                    index = clientIndex;
3481                }
3482            }
3483            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3484            mLruProcesses.add(index, app);
3485            nextIndex = index-1;
3486            mLruProcessActivityStart++;
3487            mLruProcessServiceStart++;
3488        }
3489
3490        // If the app is currently using a content provider or service,
3491        // bump those processes as well.
3492        for (int j=app.connections.size()-1; j>=0; j--) {
3493            ConnectionRecord cr = app.connections.valueAt(j);
3494            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3495                    && cr.binding.service.app != null
3496                    && cr.binding.service.app.lruSeq != mLruSeq
3497                    && !cr.binding.service.app.persistent) {
3498                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3499                        "service connection", cr, app);
3500            }
3501        }
3502        for (int j=app.conProviders.size()-1; j>=0; j--) {
3503            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3504            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3505                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3506                        "provider reference", cpr, app);
3507            }
3508        }
3509    }
3510
3511    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3512        if (uid == SYSTEM_UID) {
3513            // The system gets to run in any process.  If there are multiple
3514            // processes with the same uid, just pick the first (this
3515            // should never happen).
3516            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3517            if (procs == null) return null;
3518            final int procCount = procs.size();
3519            for (int i = 0; i < procCount; i++) {
3520                final int procUid = procs.keyAt(i);
3521                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3522                    // Don't use an app process or different user process for system component.
3523                    continue;
3524                }
3525                return procs.valueAt(i);
3526            }
3527        }
3528        ProcessRecord proc = mProcessNames.get(processName, uid);
3529        if (false && proc != null && !keepIfLarge
3530                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3531                && proc.lastCachedPss >= 4000) {
3532            // Turn this condition on to cause killing to happen regularly, for testing.
3533            if (proc.baseProcessTracker != null) {
3534                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3535            }
3536            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3537        } else if (proc != null && !keepIfLarge
3538                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3539                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3540            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3541            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3542                if (proc.baseProcessTracker != null) {
3543                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3544                }
3545                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3546            }
3547        }
3548        return proc;
3549    }
3550
3551    void notifyPackageUse(String packageName, int reason) {
3552        IPackageManager pm = AppGlobals.getPackageManager();
3553        try {
3554            pm.notifyPackageUse(packageName, reason);
3555        } catch (RemoteException e) {
3556        }
3557    }
3558
3559    boolean isNextTransitionForward() {
3560        int transit = mWindowManager.getPendingAppTransition();
3561        return transit == TRANSIT_ACTIVITY_OPEN
3562                || transit == TRANSIT_TASK_OPEN
3563                || transit == TRANSIT_TASK_TO_FRONT;
3564    }
3565
3566    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3567            String processName, String abiOverride, int uid, Runnable crashHandler) {
3568        synchronized(this) {
3569            ApplicationInfo info = new ApplicationInfo();
3570            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3571            // For isolated processes, the former contains the parent's uid and the latter the
3572            // actual uid of the isolated process.
3573            // In the special case introduced by this method (which is, starting an isolated
3574            // process directly from the SystemServer without an actual parent app process) the
3575            // closest thing to a parent's uid is SYSTEM_UID.
3576            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3577            // the |isolated| logic in the ProcessRecord constructor.
3578            info.uid = SYSTEM_UID;
3579            info.processName = processName;
3580            info.className = entryPoint;
3581            info.packageName = "android";
3582            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3583            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3584                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3585                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3586                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3587                    crashHandler);
3588            return proc != null ? proc.pid : 0;
3589        }
3590    }
3591
3592    final ProcessRecord startProcessLocked(String processName,
3593            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3594            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3595            boolean isolated, boolean keepIfLarge) {
3596        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3597                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3598                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3599                null /* crashHandler */);
3600    }
3601
3602    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3603            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3604            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3605            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3606        long startTime = SystemClock.elapsedRealtime();
3607        ProcessRecord app;
3608        if (!isolated) {
3609            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3610            checkTime(startTime, "startProcess: after getProcessRecord");
3611
3612            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3613                // If we are in the background, then check to see if this process
3614                // is bad.  If so, we will just silently fail.
3615                if (mAppErrors.isBadProcessLocked(info)) {
3616                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3617                            + "/" + info.processName);
3618                    return null;
3619                }
3620            } else {
3621                // When the user is explicitly starting a process, then clear its
3622                // crash count so that we won't make it bad until they see at
3623                // least one crash dialog again, and make the process good again
3624                // if it had been bad.
3625                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3626                        + "/" + info.processName);
3627                mAppErrors.resetProcessCrashTimeLocked(info);
3628                if (mAppErrors.isBadProcessLocked(info)) {
3629                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3630                            UserHandle.getUserId(info.uid), info.uid,
3631                            info.processName);
3632                    mAppErrors.clearBadProcessLocked(info);
3633                    if (app != null) {
3634                        app.bad = false;
3635                    }
3636                }
3637            }
3638        } else {
3639            // If this is an isolated process, it can't re-use an existing process.
3640            app = null;
3641        }
3642
3643        // We don't have to do anything more if:
3644        // (1) There is an existing application record; and
3645        // (2) The caller doesn't think it is dead, OR there is no thread
3646        //     object attached to it so we know it couldn't have crashed; and
3647        // (3) There is a pid assigned to it, so it is either starting or
3648        //     already running.
3649        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3650                + " app=" + app + " knownToBeDead=" + knownToBeDead
3651                + " thread=" + (app != null ? app.thread : null)
3652                + " pid=" + (app != null ? app.pid : -1));
3653        if (app != null && app.pid > 0) {
3654            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3655                // We already have the app running, or are waiting for it to
3656                // come up (we have a pid but not yet its thread), so keep it.
3657                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3658                // If this is a new package in the process, add the package to the list
3659                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3660                checkTime(startTime, "startProcess: done, added package to proc");
3661                return app;
3662            }
3663
3664            // An application record is attached to a previous process,
3665            // clean it up now.
3666            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3667            checkTime(startTime, "startProcess: bad proc running, killing");
3668            killProcessGroup(app.uid, app.pid);
3669            handleAppDiedLocked(app, true, true);
3670            checkTime(startTime, "startProcess: done killing old proc");
3671        }
3672
3673        String hostingNameStr = hostingName != null
3674                ? hostingName.flattenToShortString() : null;
3675
3676        if (app == null) {
3677            checkTime(startTime, "startProcess: creating new process record");
3678            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3679            if (app == null) {
3680                Slog.w(TAG, "Failed making new process record for "
3681                        + processName + "/" + info.uid + " isolated=" + isolated);
3682                return null;
3683            }
3684            app.crashHandler = crashHandler;
3685            checkTime(startTime, "startProcess: done creating new process record");
3686        } else {
3687            // If this is a new package in the process, add the package to the list
3688            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3689            checkTime(startTime, "startProcess: added package to existing proc");
3690        }
3691
3692        // If the system is not ready yet, then hold off on starting this
3693        // process until it is.
3694        if (!mProcessesReady
3695                && !isAllowedWhileBooting(info)
3696                && !allowWhileBooting) {
3697            if (!mProcessesOnHold.contains(app)) {
3698                mProcessesOnHold.add(app);
3699            }
3700            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3701                    "System not ready, putting on hold: " + app);
3702            checkTime(startTime, "startProcess: returning with proc on hold");
3703            return app;
3704        }
3705
3706        checkTime(startTime, "startProcess: stepping in to startProcess");
3707        startProcessLocked(
3708                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3709        checkTime(startTime, "startProcess: done starting proc!");
3710        return (app.pid != 0) ? app : null;
3711    }
3712
3713    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3714        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3715    }
3716
3717    private final void startProcessLocked(ProcessRecord app,
3718            String hostingType, String hostingNameStr) {
3719        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3720                null /* entryPoint */, null /* entryPointArgs */);
3721    }
3722
3723    private final void startProcessLocked(ProcessRecord app, String hostingType,
3724            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3725        long startTime = SystemClock.elapsedRealtime();
3726        if (app.pid > 0 && app.pid != MY_PID) {
3727            checkTime(startTime, "startProcess: removing from pids map");
3728            synchronized (mPidsSelfLocked) {
3729                mPidsSelfLocked.remove(app.pid);
3730                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3731            }
3732            checkTime(startTime, "startProcess: done removing from pids map");
3733            app.setPid(0);
3734        }
3735
3736        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3737                "startProcessLocked removing on hold: " + app);
3738        mProcessesOnHold.remove(app);
3739
3740        checkTime(startTime, "startProcess: starting to update cpu stats");
3741        updateCpuStats();
3742        checkTime(startTime, "startProcess: done updating cpu stats");
3743
3744        try {
3745            try {
3746                final int userId = UserHandle.getUserId(app.uid);
3747                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3748            } catch (RemoteException e) {
3749                throw e.rethrowAsRuntimeException();
3750            }
3751
3752            int uid = app.uid;
3753            int[] gids = null;
3754            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3755            if (!app.isolated) {
3756                int[] permGids = null;
3757                try {
3758                    checkTime(startTime, "startProcess: getting gids from package manager");
3759                    final IPackageManager pm = AppGlobals.getPackageManager();
3760                    permGids = pm.getPackageGids(app.info.packageName,
3761                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3762                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3763                            StorageManagerInternal.class);
3764                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3765                            app.info.packageName);
3766                } catch (RemoteException e) {
3767                    throw e.rethrowAsRuntimeException();
3768                }
3769
3770                /*
3771                 * Add shared application and profile GIDs so applications can share some
3772                 * resources like shared libraries and access user-wide resources
3773                 */
3774                if (ArrayUtils.isEmpty(permGids)) {
3775                    gids = new int[3];
3776                } else {
3777                    gids = new int[permGids.length + 3];
3778                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3779                }
3780                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3781                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3782                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3783            }
3784            checkTime(startTime, "startProcess: building args");
3785            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3786                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3787                        && mTopComponent != null
3788                        && app.processName.equals(mTopComponent.getPackageName())) {
3789                    uid = 0;
3790                }
3791                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3792                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3793                    uid = 0;
3794                }
3795            }
3796            int debugFlags = 0;
3797            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3798                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3799                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3800                // Also turn on CheckJNI for debuggable apps. It's quite
3801                // awkward to turn on otherwise.
3802                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3803            }
3804            // Run the app in safe mode if its manifest requests so or the
3805            // system is booted in safe mode.
3806            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3807                mSafeMode == true) {
3808                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3809            }
3810            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3811                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3812            }
3813            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3814            if ("true".equals(genDebugInfoProperty)) {
3815                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3816            }
3817            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3818                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3819            }
3820            if ("1".equals(SystemProperties.get("debug.assert"))) {
3821                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3822            }
3823            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3824                // Enable all debug flags required by the native debugger.
3825                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3826                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3827                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3828                mNativeDebuggingApp = null;
3829            }
3830
3831            String invokeWith = null;
3832            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3833                // Debuggable apps may include a wrapper script with their library directory.
3834                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3835                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3836                try {
3837                    if (new File(wrapperFileName).exists()) {
3838                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3839                    }
3840                } finally {
3841                    StrictMode.setThreadPolicy(oldPolicy);
3842                }
3843            }
3844
3845            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3846            if (requiredAbi == null) {
3847                requiredAbi = Build.SUPPORTED_ABIS[0];
3848            }
3849
3850            String instructionSet = null;
3851            if (app.info.primaryCpuAbi != null) {
3852                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3853            }
3854
3855            app.gids = gids;
3856            app.requiredAbi = requiredAbi;
3857            app.instructionSet = instructionSet;
3858
3859            // the per-user SELinux context must be set
3860            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3861                Slog.wtf(TAG, "SELinux tag not defined",
3862                        new IllegalStateException("SELinux tag not defined for "
3863                        + app.info.packageName + " (uid " + app.uid + ")"));
3864            }
3865            final String seInfo = app.info.seInfo
3866                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3867            // Start the process.  It will either succeed and return a result containing
3868            // the PID of the new process, or else throw a RuntimeException.
3869            boolean isActivityProcess = (entryPoint == null);
3870            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3871            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3872                    app.processName);
3873            checkTime(startTime, "startProcess: asking zygote to start proc");
3874            ProcessStartResult startResult;
3875            if (hostingType.equals("webview_service")) {
3876                startResult = startWebView(entryPoint,
3877                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3878                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3879                        app.info.dataDir, null, entryPointArgs);
3880            } else {
3881                startResult = Process.start(entryPoint,
3882                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3883                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3884                        app.info.dataDir, invokeWith, entryPointArgs);
3885            }
3886            checkTime(startTime, "startProcess: returned from zygote!");
3887            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3888
3889            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3890            checkTime(startTime, "startProcess: done updating battery stats");
3891
3892            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3893                    UserHandle.getUserId(uid), startResult.pid, uid,
3894                    app.processName, hostingType,
3895                    hostingNameStr != null ? hostingNameStr : "");
3896
3897            try {
3898                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3899                        seInfo, app.info.sourceDir, startResult.pid);
3900            } catch (RemoteException ex) {
3901                // Ignore
3902            }
3903
3904            if (app.persistent) {
3905                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3906            }
3907
3908            checkTime(startTime, "startProcess: building log message");
3909            StringBuilder buf = mStringBuilder;
3910            buf.setLength(0);
3911            buf.append("Start proc ");
3912            buf.append(startResult.pid);
3913            buf.append(':');
3914            buf.append(app.processName);
3915            buf.append('/');
3916            UserHandle.formatUid(buf, uid);
3917            if (!isActivityProcess) {
3918                buf.append(" [");
3919                buf.append(entryPoint);
3920                buf.append("]");
3921            }
3922            buf.append(" for ");
3923            buf.append(hostingType);
3924            if (hostingNameStr != null) {
3925                buf.append(" ");
3926                buf.append(hostingNameStr);
3927            }
3928            Slog.i(TAG, buf.toString());
3929            app.setPid(startResult.pid);
3930            app.usingWrapper = startResult.usingWrapper;
3931            app.removed = false;
3932            app.killed = false;
3933            app.killedByAm = false;
3934            checkTime(startTime, "startProcess: starting to update pids map");
3935            ProcessRecord oldApp;
3936            synchronized (mPidsSelfLocked) {
3937                oldApp = mPidsSelfLocked.get(startResult.pid);
3938            }
3939            // If there is already an app occupying that pid that hasn't been cleaned up
3940            if (oldApp != null && !app.isolated) {
3941                // Clean up anything relating to this pid first
3942                Slog.w(TAG, "Reusing pid " + startResult.pid
3943                        + " while app is still mapped to it");
3944                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3945                        true /*replacingPid*/);
3946            }
3947            synchronized (mPidsSelfLocked) {
3948                this.mPidsSelfLocked.put(startResult.pid, app);
3949                if (isActivityProcess) {
3950                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3951                    msg.obj = app;
3952                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3953                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3954                }
3955            }
3956            checkTime(startTime, "startProcess: done updating pids map");
3957        } catch (RuntimeException e) {
3958            Slog.e(TAG, "Failure starting process " + app.processName, e);
3959
3960            // Something went very wrong while trying to start this process; one
3961            // common case is when the package is frozen due to an active
3962            // upgrade. To recover, clean up any active bookkeeping related to
3963            // starting this process. (We already invoked this method once when
3964            // the package was initially frozen through KILL_APPLICATION_MSG, so
3965            // it doesn't hurt to use it again.)
3966            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3967                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3968        }
3969    }
3970
3971    void updateUsageStats(ActivityRecord component, boolean resumed) {
3972        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3973                "updateUsageStats: comp=" + component + "res=" + resumed);
3974        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3975        if (resumed) {
3976            if (mUsageStatsService != null) {
3977                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3978                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3979            }
3980            synchronized (stats) {
3981                stats.noteActivityResumedLocked(component.app.uid);
3982            }
3983        } else {
3984            if (mUsageStatsService != null) {
3985                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3986                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3987            }
3988            synchronized (stats) {
3989                stats.noteActivityPausedLocked(component.app.uid);
3990            }
3991        }
3992    }
3993
3994    Intent getHomeIntent() {
3995        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3996        intent.setComponent(mTopComponent);
3997        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3998        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3999            intent.addCategory(Intent.CATEGORY_HOME);
4000        }
4001        return intent;
4002    }
4003
4004    boolean startHomeActivityLocked(int userId, String reason) {
4005        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4006                && mTopAction == null) {
4007            // We are running in factory test mode, but unable to find
4008            // the factory test app, so just sit around displaying the
4009            // error message and don't try to start anything.
4010            return false;
4011        }
4012        Intent intent = getHomeIntent();
4013        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4014        if (aInfo != null) {
4015            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4016            // Don't do this if the home app is currently being
4017            // instrumented.
4018            aInfo = new ActivityInfo(aInfo);
4019            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4020            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4021                    aInfo.applicationInfo.uid, true);
4022            if (app == null || app.instr == null) {
4023                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4024                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
4025            }
4026        } else {
4027            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4028        }
4029
4030        return true;
4031    }
4032
4033    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4034        ActivityInfo ai = null;
4035        ComponentName comp = intent.getComponent();
4036        try {
4037            if (comp != null) {
4038                // Factory test.
4039                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4040            } else {
4041                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4042                        intent,
4043                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4044                        flags, userId);
4045
4046                if (info != null) {
4047                    ai = info.activityInfo;
4048                }
4049            }
4050        } catch (RemoteException e) {
4051            // ignore
4052        }
4053
4054        return ai;
4055    }
4056
4057    /**
4058     * Starts the "new version setup screen" if appropriate.
4059     */
4060    void startSetupActivityLocked() {
4061        // Only do this once per boot.
4062        if (mCheckedForSetup) {
4063            return;
4064        }
4065
4066        // We will show this screen if the current one is a different
4067        // version than the last one shown, and we are not running in
4068        // low-level factory test mode.
4069        final ContentResolver resolver = mContext.getContentResolver();
4070        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4071                Settings.Global.getInt(resolver,
4072                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4073            mCheckedForSetup = true;
4074
4075            // See if we should be showing the platform update setup UI.
4076            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4077            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4078                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4079            if (!ris.isEmpty()) {
4080                final ResolveInfo ri = ris.get(0);
4081                String vers = ri.activityInfo.metaData != null
4082                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4083                        : null;
4084                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4085                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4086                            Intent.METADATA_SETUP_VERSION);
4087                }
4088                String lastVers = Settings.Secure.getString(
4089                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4090                if (vers != null && !vers.equals(lastVers)) {
4091                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4092                    intent.setComponent(new ComponentName(
4093                            ri.activityInfo.packageName, ri.activityInfo.name));
4094                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4095                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4096                            null, 0, 0, 0, null, false, false, null, null, null);
4097                }
4098            }
4099        }
4100    }
4101
4102    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4103        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4104    }
4105
4106    void enforceNotIsolatedCaller(String caller) {
4107        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4108            throw new SecurityException("Isolated process not allowed to call " + caller);
4109        }
4110    }
4111
4112    void enforceShellRestriction(String restriction, int userHandle) {
4113        if (Binder.getCallingUid() == SHELL_UID) {
4114            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4115                throw new SecurityException("Shell does not have permission to access user "
4116                        + userHandle);
4117            }
4118        }
4119    }
4120
4121    @Override
4122    public int getFrontActivityScreenCompatMode() {
4123        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4124        synchronized (this) {
4125            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4126        }
4127    }
4128
4129    @Override
4130    public void setFrontActivityScreenCompatMode(int mode) {
4131        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4132                "setFrontActivityScreenCompatMode");
4133        synchronized (this) {
4134            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4135        }
4136    }
4137
4138    @Override
4139    public int getPackageScreenCompatMode(String packageName) {
4140        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4141        synchronized (this) {
4142            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4143        }
4144    }
4145
4146    @Override
4147    public void setPackageScreenCompatMode(String packageName, int mode) {
4148        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4149                "setPackageScreenCompatMode");
4150        synchronized (this) {
4151            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4152        }
4153    }
4154
4155    @Override
4156    public boolean getPackageAskScreenCompat(String packageName) {
4157        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4158        synchronized (this) {
4159            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4160        }
4161    }
4162
4163    @Override
4164    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4165        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4166                "setPackageAskScreenCompat");
4167        synchronized (this) {
4168            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4169        }
4170    }
4171
4172    private boolean hasUsageStatsPermission(String callingPackage) {
4173        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4174                Binder.getCallingUid(), callingPackage);
4175        if (mode == AppOpsManager.MODE_DEFAULT) {
4176            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4177                    == PackageManager.PERMISSION_GRANTED;
4178        }
4179        return mode == AppOpsManager.MODE_ALLOWED;
4180    }
4181
4182    @Override
4183    public int getPackageProcessState(String packageName, String callingPackage) {
4184        if (!hasUsageStatsPermission(callingPackage)) {
4185            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4186                    "getPackageProcessState");
4187        }
4188
4189        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4190        synchronized (this) {
4191            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4192                final ProcessRecord proc = mLruProcesses.get(i);
4193                if (procState > proc.setProcState) {
4194                    if (proc.pkgList.containsKey(packageName) ||
4195                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4196                        procState = proc.setProcState;
4197                    }
4198                }
4199            }
4200        }
4201        return procState;
4202    }
4203
4204    @Override
4205    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4206            throws RemoteException {
4207        synchronized (this) {
4208            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4209            if (app == null) {
4210                throw new IllegalArgumentException("Unknown process: " + process);
4211            }
4212            if (app.thread == null) {
4213                throw new IllegalArgumentException("Process has no app thread");
4214            }
4215            if (app.trimMemoryLevel >= level) {
4216                throw new IllegalArgumentException(
4217                        "Unable to set a higher trim level than current level");
4218            }
4219            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4220                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4221                throw new IllegalArgumentException("Unable to set a background trim level "
4222                    + "on a foreground process");
4223            }
4224            app.thread.scheduleTrimMemory(level);
4225            app.trimMemoryLevel = level;
4226            return true;
4227        }
4228    }
4229
4230    private void dispatchProcessesChanged() {
4231        int N;
4232        synchronized (this) {
4233            N = mPendingProcessChanges.size();
4234            if (mActiveProcessChanges.length < N) {
4235                mActiveProcessChanges = new ProcessChangeItem[N];
4236            }
4237            mPendingProcessChanges.toArray(mActiveProcessChanges);
4238            mPendingProcessChanges.clear();
4239            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4240                    "*** Delivering " + N + " process changes");
4241        }
4242
4243        int i = mProcessObservers.beginBroadcast();
4244        while (i > 0) {
4245            i--;
4246            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4247            if (observer != null) {
4248                try {
4249                    for (int j=0; j<N; j++) {
4250                        ProcessChangeItem item = mActiveProcessChanges[j];
4251                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4252                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4253                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4254                                    + item.uid + ": " + item.foregroundActivities);
4255                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4256                                    item.foregroundActivities);
4257                        }
4258                    }
4259                } catch (RemoteException e) {
4260                }
4261            }
4262        }
4263        mProcessObservers.finishBroadcast();
4264
4265        synchronized (this) {
4266            for (int j=0; j<N; j++) {
4267                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4268            }
4269        }
4270    }
4271
4272    private void dispatchProcessDied(int pid, int uid) {
4273        int i = mProcessObservers.beginBroadcast();
4274        while (i > 0) {
4275            i--;
4276            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4277            if (observer != null) {
4278                try {
4279                    observer.onProcessDied(pid, uid);
4280                } catch (RemoteException e) {
4281                }
4282            }
4283        }
4284        mProcessObservers.finishBroadcast();
4285    }
4286
4287    @VisibleForTesting
4288    void dispatchUidsChanged() {
4289        int N;
4290        synchronized (this) {
4291            N = mPendingUidChanges.size();
4292            if (mActiveUidChanges.length < N) {
4293                mActiveUidChanges = new UidRecord.ChangeItem[N];
4294            }
4295            for (int i=0; i<N; i++) {
4296                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4297                mActiveUidChanges[i] = change;
4298                if (change.uidRecord != null) {
4299                    change.uidRecord.pendingChange = null;
4300                    change.uidRecord = null;
4301                }
4302            }
4303            mPendingUidChanges.clear();
4304            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4305                    "*** Delivering " + N + " uid changes");
4306        }
4307
4308        int i = mUidObservers.beginBroadcast();
4309        while (i > 0) {
4310            i--;
4311            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4312                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4313        }
4314        mUidObservers.finishBroadcast();
4315
4316        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4317            for (int j = 0; j < N; ++j) {
4318                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4319                if (item.change == UidRecord.CHANGE_GONE
4320                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4321                    mValidateUids.remove(item.uid);
4322                } else {
4323                    UidRecord validateUid = mValidateUids.get(item.uid);
4324                    if (validateUid == null) {
4325                        validateUid = new UidRecord(item.uid);
4326                        mValidateUids.put(item.uid, validateUid);
4327                    }
4328                    if (item.change == UidRecord.CHANGE_IDLE) {
4329                        validateUid.idle = true;
4330                    } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4331                        validateUid.idle = false;
4332                    }
4333                    validateUid.curProcState = validateUid.setProcState = item.processState;
4334                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4335                }
4336            }
4337        }
4338
4339        synchronized (this) {
4340            for (int j = 0; j < N; j++) {
4341                mAvailUidChanges.add(mActiveUidChanges[j]);
4342            }
4343        }
4344    }
4345
4346    private void dispatchUidsChangedForObserver(IUidObserver observer,
4347            UidObserverRegistration reg, int changesSize) {
4348        if (observer == null) {
4349            return;
4350        }
4351        try {
4352            for (int j = 0; j < changesSize; j++) {
4353                UidRecord.ChangeItem item = mActiveUidChanges[j];
4354                final int change = item.change;
4355                if (change == UidRecord.CHANGE_IDLE
4356                        || change == UidRecord.CHANGE_GONE_IDLE) {
4357                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4358                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4359                                "UID idle uid=" + item.uid);
4360                        observer.onUidIdle(item.uid, item.ephemeral);
4361                    }
4362                } else if (change == UidRecord.CHANGE_ACTIVE) {
4363                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4364                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4365                                "UID active uid=" + item.uid);
4366                        observer.onUidActive(item.uid);
4367                    }
4368                }
4369                if (change == UidRecord.CHANGE_GONE
4370                        || change == UidRecord.CHANGE_GONE_IDLE) {
4371                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4372                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4373                                "UID gone uid=" + item.uid);
4374                        observer.onUidGone(item.uid, item.ephemeral);
4375                    }
4376                    if (reg.lastProcStates != null) {
4377                        reg.lastProcStates.delete(item.uid);
4378                    }
4379                } else {
4380                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4381                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4382                                "UID CHANGED uid=" + item.uid
4383                                        + ": " + item.processState);
4384                        boolean doReport = true;
4385                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4386                            final int lastState = reg.lastProcStates.get(item.uid,
4387                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4388                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4389                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4390                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4391                                doReport = lastAboveCut != newAboveCut;
4392                            } else {
4393                                doReport = item.processState
4394                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4395                            }
4396                        }
4397                        if (doReport) {
4398                            if (reg.lastProcStates != null) {
4399                                reg.lastProcStates.put(item.uid, item.processState);
4400                            }
4401                            observer.onUidStateChanged(item.uid, item.processState,
4402                                    item.procStateSeq);
4403                        }
4404                    }
4405                }
4406            }
4407        } catch (RemoteException e) {
4408        }
4409    }
4410
4411    @Override
4412    public final int startActivity(IApplicationThread caller, String callingPackage,
4413            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4414            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4415        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4416                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4417                UserHandle.getCallingUserId());
4418    }
4419
4420    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4421        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4422        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4423                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4424                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4425
4426        // TODO: Switch to user app stacks here.
4427        String mimeType = intent.getType();
4428        final Uri data = intent.getData();
4429        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4430            mimeType = getProviderMimeType(data, userId);
4431        }
4432        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4433
4434        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4435        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4436                null, 0, 0, null, null, null, null, false, userId, container, null);
4437    }
4438
4439    @Override
4440    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4441            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4442            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4443        enforceNotIsolatedCaller("startActivity");
4444        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4445                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4446        // TODO: Switch to user app stacks here.
4447        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4448                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4449                profilerInfo, null, null, bOptions, false, userId, null, null);
4450    }
4451
4452    @Override
4453    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4454            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4455            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4456            int userId) {
4457
4458        // This is very dangerous -- it allows you to perform a start activity (including
4459        // permission grants) as any app that may launch one of your own activities.  So
4460        // we will only allow this to be done from activities that are part of the core framework,
4461        // and then only when they are running as the system.
4462        final ActivityRecord sourceRecord;
4463        final int targetUid;
4464        final String targetPackage;
4465        synchronized (this) {
4466            if (resultTo == null) {
4467                throw new SecurityException("Must be called from an activity");
4468            }
4469            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4470            if (sourceRecord == null) {
4471                throw new SecurityException("Called with bad activity token: " + resultTo);
4472            }
4473            if (!sourceRecord.info.packageName.equals("android")) {
4474                throw new SecurityException(
4475                        "Must be called from an activity that is declared in the android package");
4476            }
4477            if (sourceRecord.app == null) {
4478                throw new SecurityException("Called without a process attached to activity");
4479            }
4480            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4481                // This is still okay, as long as this activity is running under the
4482                // uid of the original calling activity.
4483                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4484                    throw new SecurityException(
4485                            "Calling activity in uid " + sourceRecord.app.uid
4486                                    + " must be system uid or original calling uid "
4487                                    + sourceRecord.launchedFromUid);
4488                }
4489            }
4490            if (ignoreTargetSecurity) {
4491                if (intent.getComponent() == null) {
4492                    throw new SecurityException(
4493                            "Component must be specified with ignoreTargetSecurity");
4494                }
4495                if (intent.getSelector() != null) {
4496                    throw new SecurityException(
4497                            "Selector not allowed with ignoreTargetSecurity");
4498                }
4499            }
4500            targetUid = sourceRecord.launchedFromUid;
4501            targetPackage = sourceRecord.launchedFromPackage;
4502        }
4503
4504        if (userId == UserHandle.USER_NULL) {
4505            userId = UserHandle.getUserId(sourceRecord.app.uid);
4506        }
4507
4508        // TODO: Switch to user app stacks here.
4509        try {
4510            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4511                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4512                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4513            return ret;
4514        } catch (SecurityException e) {
4515            // XXX need to figure out how to propagate to original app.
4516            // A SecurityException here is generally actually a fault of the original
4517            // calling activity (such as a fairly granting permissions), so propagate it
4518            // back to them.
4519            /*
4520            StringBuilder msg = new StringBuilder();
4521            msg.append("While launching");
4522            msg.append(intent.toString());
4523            msg.append(": ");
4524            msg.append(e.getMessage());
4525            */
4526            throw e;
4527        }
4528    }
4529
4530    @Override
4531    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4532            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4533            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4534        enforceNotIsolatedCaller("startActivityAndWait");
4535        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4536                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4537        WaitResult res = new WaitResult();
4538        // TODO: Switch to user app stacks here.
4539        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4540                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4541                bOptions, false, userId, null, null);
4542        return res;
4543    }
4544
4545    @Override
4546    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4547            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4548            int startFlags, Configuration config, Bundle bOptions, int userId) {
4549        enforceNotIsolatedCaller("startActivityWithConfig");
4550        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4551                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4552        // TODO: Switch to user app stacks here.
4553        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4554                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4555                null, null, config, bOptions, false, userId, null, null);
4556        return ret;
4557    }
4558
4559    @Override
4560    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4561            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4562            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4563            throws TransactionTooLargeException {
4564        enforceNotIsolatedCaller("startActivityIntentSender");
4565        // Refuse possible leaked file descriptors
4566        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4567            throw new IllegalArgumentException("File descriptors passed in Intent");
4568        }
4569
4570        IIntentSender sender = intent.getTarget();
4571        if (!(sender instanceof PendingIntentRecord)) {
4572            throw new IllegalArgumentException("Bad PendingIntent object");
4573        }
4574
4575        PendingIntentRecord pir = (PendingIntentRecord)sender;
4576
4577        synchronized (this) {
4578            // If this is coming from the currently resumed activity, it is
4579            // effectively saying that app switches are allowed at this point.
4580            final ActivityStack stack = getFocusedStack();
4581            if (stack.mResumedActivity != null &&
4582                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4583                mAppSwitchesAllowedTime = 0;
4584            }
4585        }
4586        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4587                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4588        return ret;
4589    }
4590
4591    @Override
4592    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4593            Intent intent, String resolvedType, IVoiceInteractionSession session,
4594            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4595            Bundle bOptions, int userId) {
4596        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4597                != PackageManager.PERMISSION_GRANTED) {
4598            String msg = "Permission Denial: startVoiceActivity() from pid="
4599                    + Binder.getCallingPid()
4600                    + ", uid=" + Binder.getCallingUid()
4601                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4602            Slog.w(TAG, msg);
4603            throw new SecurityException(msg);
4604        }
4605        if (session == null || interactor == null) {
4606            throw new NullPointerException("null session or interactor");
4607        }
4608        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4609                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4610        // TODO: Switch to user app stacks here.
4611        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4612                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4613                null, bOptions, false, userId, null, null);
4614    }
4615
4616    @Override
4617    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4618            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4619        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4620                != PackageManager.PERMISSION_GRANTED) {
4621            final String msg = "Permission Denial: startAssistantActivity() from pid="
4622                    + Binder.getCallingPid()
4623                    + ", uid=" + Binder.getCallingUid()
4624                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4625            Slog.w(TAG, msg);
4626            throw new SecurityException(msg);
4627        }
4628        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4629                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4630        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4631                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4632                userId, null, null);
4633    }
4634
4635    @Override
4636    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4637            throws RemoteException {
4638        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4639        synchronized (this) {
4640            ActivityRecord activity = getFocusedStack().topActivity();
4641            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4642                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4643            }
4644            if (mRunningVoice != null || activity.getTask().voiceSession != null
4645                    || activity.voiceSession != null) {
4646                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4647                return;
4648            }
4649            if (activity.pendingVoiceInteractionStart) {
4650                Slog.w(TAG, "Pending start of voice interaction already.");
4651                return;
4652            }
4653            activity.pendingVoiceInteractionStart = true;
4654        }
4655        LocalServices.getService(VoiceInteractionManagerInternal.class)
4656                .startLocalVoiceInteraction(callingActivity, options);
4657    }
4658
4659    @Override
4660    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4661        LocalServices.getService(VoiceInteractionManagerInternal.class)
4662                .stopLocalVoiceInteraction(callingActivity);
4663    }
4664
4665    @Override
4666    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4667        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4668                .supportsLocalVoiceInteraction();
4669    }
4670
4671    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4672            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4673        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4674        if (activityToCallback == null) return;
4675        activityToCallback.setVoiceSessionLocked(voiceSession);
4676
4677        // Inform the activity
4678        try {
4679            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4680                    voiceInteractor);
4681            long token = Binder.clearCallingIdentity();
4682            try {
4683                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4684            } finally {
4685                Binder.restoreCallingIdentity(token);
4686            }
4687            // TODO: VI Should we cache the activity so that it's easier to find later
4688            // rather than scan through all the stacks and activities?
4689        } catch (RemoteException re) {
4690            activityToCallback.clearVoiceSessionLocked();
4691            // TODO: VI Should this terminate the voice session?
4692        }
4693    }
4694
4695    @Override
4696    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4697        synchronized (this) {
4698            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4699                if (keepAwake) {
4700                    mVoiceWakeLock.acquire();
4701                } else {
4702                    mVoiceWakeLock.release();
4703                }
4704            }
4705        }
4706    }
4707
4708    @Override
4709    public boolean startNextMatchingActivity(IBinder callingActivity,
4710            Intent intent, Bundle bOptions) {
4711        // Refuse possible leaked file descriptors
4712        if (intent != null && intent.hasFileDescriptors() == true) {
4713            throw new IllegalArgumentException("File descriptors passed in Intent");
4714        }
4715        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4716
4717        synchronized (this) {
4718            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4719            if (r == null) {
4720                ActivityOptions.abort(options);
4721                return false;
4722            }
4723            if (r.app == null || r.app.thread == null) {
4724                // The caller is not running...  d'oh!
4725                ActivityOptions.abort(options);
4726                return false;
4727            }
4728            intent = new Intent(intent);
4729            // The caller is not allowed to change the data.
4730            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4731            // And we are resetting to find the next component...
4732            intent.setComponent(null);
4733
4734            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4735
4736            ActivityInfo aInfo = null;
4737            try {
4738                List<ResolveInfo> resolves =
4739                    AppGlobals.getPackageManager().queryIntentActivities(
4740                            intent, r.resolvedType,
4741                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4742                            UserHandle.getCallingUserId()).getList();
4743
4744                // Look for the original activity in the list...
4745                final int N = resolves != null ? resolves.size() : 0;
4746                for (int i=0; i<N; i++) {
4747                    ResolveInfo rInfo = resolves.get(i);
4748                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4749                            && rInfo.activityInfo.name.equals(r.info.name)) {
4750                        // We found the current one...  the next matching is
4751                        // after it.
4752                        i++;
4753                        if (i<N) {
4754                            aInfo = resolves.get(i).activityInfo;
4755                        }
4756                        if (debug) {
4757                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4758                                    + "/" + r.info.name);
4759                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4760                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4761                        }
4762                        break;
4763                    }
4764                }
4765            } catch (RemoteException e) {
4766            }
4767
4768            if (aInfo == null) {
4769                // Nobody who is next!
4770                ActivityOptions.abort(options);
4771                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4772                return false;
4773            }
4774
4775            intent.setComponent(new ComponentName(
4776                    aInfo.applicationInfo.packageName, aInfo.name));
4777            intent.setFlags(intent.getFlags()&~(
4778                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4779                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4780                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4781                    Intent.FLAG_ACTIVITY_NEW_TASK));
4782
4783            // Okay now we need to start the new activity, replacing the
4784            // currently running activity.  This is a little tricky because
4785            // we want to start the new one as if the current one is finished,
4786            // but not finish the current one first so that there is no flicker.
4787            // And thus...
4788            final boolean wasFinishing = r.finishing;
4789            r.finishing = true;
4790
4791            // Propagate reply information over to the new activity.
4792            final ActivityRecord resultTo = r.resultTo;
4793            final String resultWho = r.resultWho;
4794            final int requestCode = r.requestCode;
4795            r.resultTo = null;
4796            if (resultTo != null) {
4797                resultTo.removeResultsLocked(r, resultWho, requestCode);
4798            }
4799
4800            final long origId = Binder.clearCallingIdentity();
4801            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4802                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4803                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4804                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4805                    false, false, null, null, null);
4806            Binder.restoreCallingIdentity(origId);
4807
4808            r.finishing = wasFinishing;
4809            if (res != ActivityManager.START_SUCCESS) {
4810                return false;
4811            }
4812            return true;
4813        }
4814    }
4815
4816    @Override
4817    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4818        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4819            String msg = "Permission Denial: startActivityFromRecents called without " +
4820                    START_TASKS_FROM_RECENTS;
4821            Slog.w(TAG, msg);
4822            throw new SecurityException(msg);
4823        }
4824        final long origId = Binder.clearCallingIdentity();
4825        try {
4826            synchronized (this) {
4827                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4828            }
4829        } finally {
4830            Binder.restoreCallingIdentity(origId);
4831        }
4832    }
4833
4834    final int startActivityInPackage(int uid, String callingPackage,
4835            Intent intent, String resolvedType, IBinder resultTo,
4836            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4837            IActivityContainer container, TaskRecord inTask) {
4838
4839        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4840                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4841
4842        // TODO: Switch to user app stacks here.
4843        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4844                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4845                null, null, null, bOptions, false, userId, container, inTask);
4846        return ret;
4847    }
4848
4849    @Override
4850    public final int startActivities(IApplicationThread caller, String callingPackage,
4851            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4852            int userId) {
4853        enforceNotIsolatedCaller("startActivities");
4854        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4855                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4856        // TODO: Switch to user app stacks here.
4857        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4858                resolvedTypes, resultTo, bOptions, userId);
4859        return ret;
4860    }
4861
4862    final int startActivitiesInPackage(int uid, String callingPackage,
4863            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4864            Bundle bOptions, int userId) {
4865
4866        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4867                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4868        // TODO: Switch to user app stacks here.
4869        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4870                resultTo, bOptions, userId);
4871        return ret;
4872    }
4873
4874    @Override
4875    public void reportActivityFullyDrawn(IBinder token) {
4876        synchronized (this) {
4877            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4878            if (r == null) {
4879                return;
4880            }
4881            r.reportFullyDrawnLocked();
4882        }
4883    }
4884
4885    @Override
4886    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4887        synchronized (this) {
4888            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4889            if (r == null) {
4890                return;
4891            }
4892            final long origId = Binder.clearCallingIdentity();
4893            try {
4894                r.setRequestedOrientation(requestedOrientation);
4895            } finally {
4896                Binder.restoreCallingIdentity(origId);
4897            }
4898        }
4899    }
4900
4901    @Override
4902    public int getRequestedOrientation(IBinder token) {
4903        synchronized (this) {
4904            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4905            if (r == null) {
4906                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4907            }
4908            return r.getRequestedOrientation();
4909        }
4910    }
4911
4912    @Override
4913    public final void requestActivityRelaunch(IBinder token) {
4914        synchronized(this) {
4915            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4916            if (r == null) {
4917                return;
4918            }
4919            final long origId = Binder.clearCallingIdentity();
4920            try {
4921                r.forceNewConfig = true;
4922                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4923                        true /* preserveWindow */);
4924            } finally {
4925                Binder.restoreCallingIdentity(origId);
4926            }
4927        }
4928    }
4929
4930    /**
4931     * This is the internal entry point for handling Activity.finish().
4932     *
4933     * @param token The Binder token referencing the Activity we want to finish.
4934     * @param resultCode Result code, if any, from this Activity.
4935     * @param resultData Result data (Intent), if any, from this Activity.
4936     * @param finishTask Whether to finish the task associated with this Activity.
4937     *
4938     * @return Returns true if the activity successfully finished, or false if it is still running.
4939     */
4940    @Override
4941    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4942            int finishTask) {
4943        // Refuse possible leaked file descriptors
4944        if (resultData != null && resultData.hasFileDescriptors() == true) {
4945            throw new IllegalArgumentException("File descriptors passed in Intent");
4946        }
4947
4948        synchronized(this) {
4949            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4950            if (r == null) {
4951                return true;
4952            }
4953            // Keep track of the root activity of the task before we finish it
4954            TaskRecord tr = r.getTask();
4955            ActivityRecord rootR = tr.getRootActivity();
4956            if (rootR == null) {
4957                Slog.w(TAG, "Finishing task with all activities already finished");
4958            }
4959            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4960            // finish.
4961            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4962                    mStackSupervisor.isLastLockedTask(tr)) {
4963                Slog.i(TAG, "Not finishing task in lock task mode");
4964                mStackSupervisor.showLockTaskToast();
4965                return false;
4966            }
4967            if (mController != null) {
4968                // Find the first activity that is not finishing.
4969                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
4970                if (next != null) {
4971                    // ask watcher if this is allowed
4972                    boolean resumeOK = true;
4973                    try {
4974                        resumeOK = mController.activityResuming(next.packageName);
4975                    } catch (RemoteException e) {
4976                        mController = null;
4977                        Watchdog.getInstance().setActivityController(null);
4978                    }
4979
4980                    if (!resumeOK) {
4981                        Slog.i(TAG, "Not finishing activity because controller resumed");
4982                        return false;
4983                    }
4984                }
4985            }
4986            final long origId = Binder.clearCallingIdentity();
4987            try {
4988                boolean res;
4989                final boolean finishWithRootActivity =
4990                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4991                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4992                        || (finishWithRootActivity && r == rootR)) {
4993                    // If requested, remove the task that is associated to this activity only if it
4994                    // was the root activity in the task. The result code and data is ignored
4995                    // because we don't support returning them across task boundaries. Also, to
4996                    // keep backwards compatibility we remove the task from recents when finishing
4997                    // task with root activity.
4998                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4999                    if (!res) {
5000                        Slog.i(TAG, "Removing task failed to finish activity");
5001                    }
5002                } else {
5003                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5004                            resultData, "app-request", true);
5005                    if (!res) {
5006                        Slog.i(TAG, "Failed to finish by app-request");
5007                    }
5008                }
5009                return res;
5010            } finally {
5011                Binder.restoreCallingIdentity(origId);
5012            }
5013        }
5014    }
5015
5016    @Override
5017    public final void finishHeavyWeightApp() {
5018        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5019                != PackageManager.PERMISSION_GRANTED) {
5020            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5021                    + Binder.getCallingPid()
5022                    + ", uid=" + Binder.getCallingUid()
5023                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5024            Slog.w(TAG, msg);
5025            throw new SecurityException(msg);
5026        }
5027
5028        synchronized(this) {
5029            if (mHeavyWeightProcess == null) {
5030                return;
5031            }
5032
5033            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5034            for (int i = 0; i < activities.size(); i++) {
5035                ActivityRecord r = activities.get(i);
5036                if (!r.finishing && r.isInStackLocked()) {
5037                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5038                            null, "finish-heavy", true);
5039                }
5040            }
5041
5042            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5043                    mHeavyWeightProcess.userId, 0));
5044            mHeavyWeightProcess = null;
5045        }
5046    }
5047
5048    @Override
5049    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5050            String message) {
5051        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5052                != PackageManager.PERMISSION_GRANTED) {
5053            String msg = "Permission Denial: crashApplication() from pid="
5054                    + Binder.getCallingPid()
5055                    + ", uid=" + Binder.getCallingUid()
5056                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5057            Slog.w(TAG, msg);
5058            throw new SecurityException(msg);
5059        }
5060
5061        synchronized(this) {
5062            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5063        }
5064    }
5065
5066    @Override
5067    public final void finishSubActivity(IBinder token, String resultWho,
5068            int requestCode) {
5069        synchronized(this) {
5070            final long origId = Binder.clearCallingIdentity();
5071            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5072            if (r != null) {
5073                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5074            }
5075            Binder.restoreCallingIdentity(origId);
5076        }
5077    }
5078
5079    @Override
5080    public boolean finishActivityAffinity(IBinder token) {
5081        synchronized(this) {
5082            final long origId = Binder.clearCallingIdentity();
5083            try {
5084                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5085                if (r == null) {
5086                    return false;
5087                }
5088
5089                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5090                // can finish.
5091                final TaskRecord task = r.getTask();
5092                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5093                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5094                    mStackSupervisor.showLockTaskToast();
5095                    return false;
5096                }
5097                return task.getStack().finishActivityAffinityLocked(r);
5098            } finally {
5099                Binder.restoreCallingIdentity(origId);
5100            }
5101        }
5102    }
5103
5104    @Override
5105    public void finishVoiceTask(IVoiceInteractionSession session) {
5106        synchronized (this) {
5107            final long origId = Binder.clearCallingIdentity();
5108            try {
5109                // TODO: VI Consider treating local voice interactions and voice tasks
5110                // differently here
5111                mStackSupervisor.finishVoiceTask(session);
5112            } finally {
5113                Binder.restoreCallingIdentity(origId);
5114            }
5115        }
5116
5117    }
5118
5119    @Override
5120    public boolean releaseActivityInstance(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                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5129            } finally {
5130                Binder.restoreCallingIdentity(origId);
5131            }
5132        }
5133    }
5134
5135    @Override
5136    public void releaseSomeActivities(IApplicationThread appInt) {
5137        synchronized(this) {
5138            final long origId = Binder.clearCallingIdentity();
5139            try {
5140                ProcessRecord app = getRecordForAppLocked(appInt);
5141                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5142            } finally {
5143                Binder.restoreCallingIdentity(origId);
5144            }
5145        }
5146    }
5147
5148    @Override
5149    public boolean willActivityBeVisible(IBinder token) {
5150        synchronized(this) {
5151            ActivityStack stack = ActivityRecord.getStackLocked(token);
5152            if (stack != null) {
5153                return stack.willActivityBeVisibleLocked(token);
5154            }
5155            return false;
5156        }
5157    }
5158
5159    @Override
5160    public void overridePendingTransition(IBinder token, String packageName,
5161            int enterAnim, int exitAnim) {
5162        synchronized(this) {
5163            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5164            if (self == null) {
5165                return;
5166            }
5167
5168            final long origId = Binder.clearCallingIdentity();
5169
5170            if (self.state == ActivityState.RESUMED
5171                    || self.state == ActivityState.PAUSING) {
5172                mWindowManager.overridePendingAppTransition(packageName,
5173                        enterAnim, exitAnim, null);
5174            }
5175
5176            Binder.restoreCallingIdentity(origId);
5177        }
5178    }
5179
5180    /**
5181     * Main function for removing an existing process from the activity manager
5182     * as a result of that process going away.  Clears out all connections
5183     * to the process.
5184     */
5185    private final void handleAppDiedLocked(ProcessRecord app,
5186            boolean restarting, boolean allowRestart) {
5187        int pid = app.pid;
5188        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5189                false /*replacingPid*/);
5190        if (!kept && !restarting) {
5191            removeLruProcessLocked(app);
5192            if (pid > 0) {
5193                ProcessList.remove(pid);
5194            }
5195        }
5196
5197        if (mProfileProc == app) {
5198            clearProfilerLocked();
5199        }
5200
5201        // Remove this application's activities from active lists.
5202        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5203
5204        app.activities.clear();
5205
5206        if (app.instr != null) {
5207            Slog.w(TAG, "Crash of app " + app.processName
5208                  + " running instrumentation " + app.instr.mClass);
5209            Bundle info = new Bundle();
5210            info.putString("shortMsg", "Process crashed.");
5211            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5212        }
5213
5214        mWindowManager.deferSurfaceLayout();
5215        try {
5216            if (!restarting && hasVisibleActivities
5217                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5218                // If there was nothing to resume, and we are not already restarting this process, but
5219                // there is a visible activity that is hosted by the process...  then make sure all
5220                // visible activities are running, taking care of restarting this process.
5221                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5222            }
5223        } finally {
5224            mWindowManager.continueSurfaceLayout();
5225        }
5226    }
5227
5228    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5229        final IBinder threadBinder = thread.asBinder();
5230        // Find the application record.
5231        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5232            final ProcessRecord rec = mLruProcesses.get(i);
5233            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5234                return i;
5235            }
5236        }
5237        return -1;
5238    }
5239
5240    final ProcessRecord getRecordForAppLocked(
5241            IApplicationThread thread) {
5242        if (thread == null) {
5243            return null;
5244        }
5245
5246        int appIndex = getLRURecordIndexForAppLocked(thread);
5247        if (appIndex >= 0) {
5248            return mLruProcesses.get(appIndex);
5249        }
5250
5251        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5252        // double-check that.
5253        final IBinder threadBinder = thread.asBinder();
5254        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5255        for (int i = pmap.size()-1; i >= 0; i--) {
5256            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5257            for (int j = procs.size()-1; j >= 0; j--) {
5258                final ProcessRecord proc = procs.valueAt(j);
5259                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5260                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5261                            + proc);
5262                    return proc;
5263                }
5264            }
5265        }
5266
5267        return null;
5268    }
5269
5270    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5271        // If there are no longer any background processes running,
5272        // and the app that died was not running instrumentation,
5273        // then tell everyone we are now low on memory.
5274        boolean haveBg = false;
5275        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5276            ProcessRecord rec = mLruProcesses.get(i);
5277            if (rec.thread != null
5278                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5279                haveBg = true;
5280                break;
5281            }
5282        }
5283
5284        if (!haveBg) {
5285            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5286            if (doReport) {
5287                long now = SystemClock.uptimeMillis();
5288                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5289                    doReport = false;
5290                } else {
5291                    mLastMemUsageReportTime = now;
5292                }
5293            }
5294            final ArrayList<ProcessMemInfo> memInfos
5295                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5296            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5297            long now = SystemClock.uptimeMillis();
5298            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5299                ProcessRecord rec = mLruProcesses.get(i);
5300                if (rec == dyingProc || rec.thread == null) {
5301                    continue;
5302                }
5303                if (doReport) {
5304                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5305                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5306                }
5307                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5308                    // The low memory report is overriding any current
5309                    // state for a GC request.  Make sure to do
5310                    // heavy/important/visible/foreground processes first.
5311                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5312                        rec.lastRequestedGc = 0;
5313                    } else {
5314                        rec.lastRequestedGc = rec.lastLowMemory;
5315                    }
5316                    rec.reportLowMemory = true;
5317                    rec.lastLowMemory = now;
5318                    mProcessesToGc.remove(rec);
5319                    addProcessToGcListLocked(rec);
5320                }
5321            }
5322            if (doReport) {
5323                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5324                mHandler.sendMessage(msg);
5325            }
5326            scheduleAppGcsLocked();
5327        }
5328    }
5329
5330    final void appDiedLocked(ProcessRecord app) {
5331       appDiedLocked(app, app.pid, app.thread, false);
5332    }
5333
5334    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5335            boolean fromBinderDied) {
5336        // First check if this ProcessRecord is actually active for the pid.
5337        synchronized (mPidsSelfLocked) {
5338            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5339            if (curProc != app) {
5340                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5341                return;
5342            }
5343        }
5344
5345        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5346        synchronized (stats) {
5347            stats.noteProcessDiedLocked(app.info.uid, pid);
5348        }
5349
5350        if (!app.killed) {
5351            if (!fromBinderDied) {
5352                killProcessQuiet(pid);
5353            }
5354            killProcessGroup(app.uid, pid);
5355            app.killed = true;
5356        }
5357
5358        // Clean up already done if the process has been re-started.
5359        if (app.pid == pid && app.thread != null &&
5360                app.thread.asBinder() == thread.asBinder()) {
5361            boolean doLowMem = app.instr == null;
5362            boolean doOomAdj = doLowMem;
5363            if (!app.killedByAm) {
5364                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5365                        + ") has died");
5366                mAllowLowerMemLevel = true;
5367            } else {
5368                // Note that we always want to do oom adj to update our state with the
5369                // new number of procs.
5370                mAllowLowerMemLevel = false;
5371                doLowMem = false;
5372            }
5373            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5374            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5375                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5376            handleAppDiedLocked(app, false, true);
5377
5378            if (doOomAdj) {
5379                updateOomAdjLocked();
5380            }
5381            if (doLowMem) {
5382                doLowMemReportIfNeededLocked(app);
5383            }
5384        } else if (app.pid != pid) {
5385            // A new process has already been started.
5386            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5387                    + ") has died and restarted (pid " + app.pid + ").");
5388            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5389        } else if (DEBUG_PROCESSES) {
5390            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5391                    + thread.asBinder());
5392        }
5393    }
5394
5395    /**
5396     * If a stack trace dump file is configured, dump process stack traces.
5397     * @param clearTraces causes the dump file to be erased prior to the new
5398     *    traces being written, if true; when false, the new traces will be
5399     *    appended to any existing file content.
5400     * @param firstPids of dalvik VM processes to dump stack traces for first
5401     * @param lastPids of dalvik VM processes to dump stack traces for last
5402     * @param nativePids optional list of native pids to dump stack crawls
5403     * @return file containing stack traces, or null if no dump file is configured
5404     */
5405    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5406            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5407            ArrayList<Integer> nativePids) {
5408        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5409        if (tracesPath == null || tracesPath.length() == 0) {
5410            return null;
5411        }
5412
5413        File tracesFile = new File(tracesPath);
5414        try {
5415            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5416            tracesFile.createNewFile();
5417            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5418        } catch (IOException e) {
5419            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5420            return null;
5421        }
5422
5423        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativePids);
5424        return tracesFile;
5425    }
5426
5427    public static class DumpStackFileObserver extends FileObserver {
5428        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5429        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5430        static final int TRACE_DUMP_TIMEOUT_SECONDS = TRACE_DUMP_TIMEOUT_MS / 1000;
5431
5432        private final String mTracesPath;
5433        private boolean mClosed;
5434
5435        public DumpStackFileObserver(String tracesPath) {
5436            super(tracesPath, FileObserver.CLOSE_WRITE);
5437            mTracesPath = tracesPath;
5438        }
5439
5440        @Override
5441        public synchronized void onEvent(int event, String path) {
5442            mClosed = true;
5443            notify();
5444        }
5445
5446        public void dumpWithTimeout(int pid) {
5447            sendSignal(pid, SIGNAL_QUIT);
5448            synchronized (this) {
5449                try {
5450                    wait(TRACE_DUMP_TIMEOUT_MS); // Wait for traces file to be closed.
5451                } catch (InterruptedException e) {
5452                    Slog.wtf(TAG, e);
5453                }
5454            }
5455            if (!mClosed) {
5456                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5457                       ". Attempting native stack collection.");
5458                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath, TRACE_DUMP_TIMEOUT_SECONDS);
5459            }
5460            mClosed = false;
5461        }
5462    }
5463
5464    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5465            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5466            ArrayList<Integer> nativePids) {
5467        // Use a FileObserver to detect when traces finish writing.
5468        // The order of traces is considered important to maintain for legibility.
5469        DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
5470        try {
5471            observer.startWatching();
5472
5473            // First collect all of the stacks of the most important pids.
5474            if (firstPids != null) {
5475                int num = firstPids.size();
5476                for (int i = 0; i < num; i++) {
5477                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5478                            + firstPids.get(i));
5479                    final long sime = SystemClock.elapsedRealtime();
5480                    observer.dumpWithTimeout(firstPids.get(i));
5481                    if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5482                            + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5483                }
5484            }
5485
5486            // Next collect the stacks of the native pids
5487            if (nativePids != null) {
5488                for (int pid : nativePids) {
5489                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5490                    final long sime = SystemClock.elapsedRealtime();
5491
5492                    Debug.dumpNativeBacktraceToFileTimeout(
5493                            pid, tracesPath, DumpStackFileObserver.TRACE_DUMP_TIMEOUT_SECONDS);
5494                    if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5495                            + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5496                }
5497            }
5498
5499            // Lastly, measure CPU usage.
5500            if (processCpuTracker != null) {
5501                processCpuTracker.init();
5502                System.gc();
5503                processCpuTracker.update();
5504                try {
5505                    synchronized (processCpuTracker) {
5506                        processCpuTracker.wait(500); // measure over 1/2 second.
5507                    }
5508                } catch (InterruptedException e) {
5509                }
5510                processCpuTracker.update();
5511
5512                // We'll take the stack crawls of just the top apps using CPU.
5513                final int N = processCpuTracker.countWorkingStats();
5514                int numProcs = 0;
5515                for (int i=0; i<N && numProcs<5; i++) {
5516                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5517                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5518                        numProcs++;
5519                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5520                                + stats.pid);
5521                        final long stime = SystemClock.elapsedRealtime();
5522                        observer.dumpWithTimeout(stats.pid);
5523                        if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5524                                + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5525                    } else if (DEBUG_ANR) {
5526                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5527                                + stats.pid);
5528                    }
5529                }
5530            }
5531        } finally {
5532            observer.stopWatching();
5533        }
5534    }
5535
5536    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5537        if (true || IS_USER_BUILD) {
5538            return;
5539        }
5540        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5541        if (tracesPath == null || tracesPath.length() == 0) {
5542            return;
5543        }
5544
5545        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5546        StrictMode.allowThreadDiskWrites();
5547        try {
5548            final File tracesFile = new File(tracesPath);
5549            final File tracesDir = tracesFile.getParentFile();
5550            final File tracesTmp = new File(tracesDir, "__tmp__");
5551            try {
5552                if (tracesFile.exists()) {
5553                    tracesTmp.delete();
5554                    tracesFile.renameTo(tracesTmp);
5555                }
5556                StringBuilder sb = new StringBuilder();
5557                Time tobj = new Time();
5558                tobj.set(System.currentTimeMillis());
5559                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5560                sb.append(": ");
5561                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5562                sb.append(" since ");
5563                sb.append(msg);
5564                FileOutputStream fos = new FileOutputStream(tracesFile);
5565                fos.write(sb.toString().getBytes());
5566                if (app == null) {
5567                    fos.write("\n*** No application process!".getBytes());
5568                }
5569                fos.close();
5570                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5571            } catch (IOException e) {
5572                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5573                return;
5574            }
5575
5576            if (app != null) {
5577                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5578                firstPids.add(app.pid);
5579                dumpStackTraces(tracesPath, firstPids, null, null, null);
5580            }
5581
5582            File lastTracesFile = null;
5583            File curTracesFile = null;
5584            for (int i=9; i>=0; i--) {
5585                String name = String.format(Locale.US, "slow%02d.txt", i);
5586                curTracesFile = new File(tracesDir, name);
5587                if (curTracesFile.exists()) {
5588                    if (lastTracesFile != null) {
5589                        curTracesFile.renameTo(lastTracesFile);
5590                    } else {
5591                        curTracesFile.delete();
5592                    }
5593                }
5594                lastTracesFile = curTracesFile;
5595            }
5596            tracesFile.renameTo(curTracesFile);
5597            if (tracesTmp.exists()) {
5598                tracesTmp.renameTo(tracesFile);
5599            }
5600        } finally {
5601            StrictMode.setThreadPolicy(oldPolicy);
5602        }
5603    }
5604
5605    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5606        if (!mLaunchWarningShown) {
5607            mLaunchWarningShown = true;
5608            mUiHandler.post(new Runnable() {
5609                @Override
5610                public void run() {
5611                    synchronized (ActivityManagerService.this) {
5612                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5613                        d.show();
5614                        mUiHandler.postDelayed(new Runnable() {
5615                            @Override
5616                            public void run() {
5617                                synchronized (ActivityManagerService.this) {
5618                                    d.dismiss();
5619                                    mLaunchWarningShown = false;
5620                                }
5621                            }
5622                        }, 4000);
5623                    }
5624                }
5625            });
5626        }
5627    }
5628
5629    @Override
5630    public boolean clearApplicationUserData(final String packageName,
5631            final IPackageDataObserver observer, int userId) {
5632        enforceNotIsolatedCaller("clearApplicationUserData");
5633        int uid = Binder.getCallingUid();
5634        int pid = Binder.getCallingPid();
5635        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5636                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5637
5638
5639        long callingId = Binder.clearCallingIdentity();
5640        try {
5641            IPackageManager pm = AppGlobals.getPackageManager();
5642            int pkgUid = -1;
5643            synchronized(this) {
5644                if (getPackageManagerInternalLocked().isPackageDataProtected(
5645                        userId, packageName)) {
5646                    throw new SecurityException(
5647                            "Cannot clear data for a protected package: " + packageName);
5648                }
5649
5650                try {
5651                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5652                } catch (RemoteException e) {
5653                }
5654                if (pkgUid == -1) {
5655                    Slog.w(TAG, "Invalid packageName: " + packageName);
5656                    if (observer != null) {
5657                        try {
5658                            observer.onRemoveCompleted(packageName, false);
5659                        } catch (RemoteException e) {
5660                            Slog.i(TAG, "Observer no longer exists.");
5661                        }
5662                    }
5663                    return false;
5664                }
5665                if (uid == pkgUid || checkComponentPermission(
5666                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5667                        pid, uid, -1, true)
5668                        == PackageManager.PERMISSION_GRANTED) {
5669                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5670                } else {
5671                    throw new SecurityException("PID " + pid + " does not have permission "
5672                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5673                                    + " of package " + packageName);
5674                }
5675
5676                // Remove all tasks match the cleared application package and user
5677                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5678                    final TaskRecord tr = mRecentTasks.get(i);
5679                    final String taskPackageName =
5680                            tr.getBaseIntent().getComponent().getPackageName();
5681                    if (tr.userId != userId) continue;
5682                    if (!taskPackageName.equals(packageName)) continue;
5683                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5684                }
5685            }
5686
5687            final int pkgUidF = pkgUid;
5688            final int userIdF = userId;
5689            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5690                @Override
5691                public void onRemoveCompleted(String packageName, boolean succeeded)
5692                        throws RemoteException {
5693                    synchronized (ActivityManagerService.this) {
5694                        finishForceStopPackageLocked(packageName, pkgUidF);
5695                    }
5696
5697                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5698                            Uri.fromParts("package", packageName, null));
5699                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5700                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5701                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5702                    broadcastIntentInPackage("android", SYSTEM_UID, intent,
5703                            null, null, 0, null, null, null, null, false, false, userIdF);
5704
5705                    if (observer != null) {
5706                        observer.onRemoveCompleted(packageName, succeeded);
5707                    }
5708                }
5709            };
5710
5711            try {
5712                // Clear application user data
5713                pm.clearApplicationUserData(packageName, localObserver, userId);
5714
5715                synchronized(this) {
5716                    // Remove all permissions granted from/to this package
5717                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5718                }
5719
5720                // Reset notification settings.
5721                INotificationManager inm = NotificationManager.getService();
5722                inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5723            } catch (RemoteException e) {
5724            }
5725        } finally {
5726            Binder.restoreCallingIdentity(callingId);
5727        }
5728        return true;
5729    }
5730
5731    @Override
5732    public void killBackgroundProcesses(final String packageName, int userId) {
5733        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5734                != PackageManager.PERMISSION_GRANTED &&
5735                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5736                        != PackageManager.PERMISSION_GRANTED) {
5737            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5738                    + Binder.getCallingPid()
5739                    + ", uid=" + Binder.getCallingUid()
5740                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5741            Slog.w(TAG, msg);
5742            throw new SecurityException(msg);
5743        }
5744
5745        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5746                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5747        long callingId = Binder.clearCallingIdentity();
5748        try {
5749            IPackageManager pm = AppGlobals.getPackageManager();
5750            synchronized(this) {
5751                int appId = -1;
5752                try {
5753                    appId = UserHandle.getAppId(
5754                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5755                } catch (RemoteException e) {
5756                }
5757                if (appId == -1) {
5758                    Slog.w(TAG, "Invalid packageName: " + packageName);
5759                    return;
5760                }
5761                killPackageProcessesLocked(packageName, appId, userId,
5762                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5763            }
5764        } finally {
5765            Binder.restoreCallingIdentity(callingId);
5766        }
5767    }
5768
5769    @Override
5770    public void killAllBackgroundProcesses() {
5771        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5772                != PackageManager.PERMISSION_GRANTED) {
5773            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5774                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5775                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5776            Slog.w(TAG, msg);
5777            throw new SecurityException(msg);
5778        }
5779
5780        final long callingId = Binder.clearCallingIdentity();
5781        try {
5782            synchronized (this) {
5783                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5784                final int NP = mProcessNames.getMap().size();
5785                for (int ip = 0; ip < NP; ip++) {
5786                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5787                    final int NA = apps.size();
5788                    for (int ia = 0; ia < NA; ia++) {
5789                        final ProcessRecord app = apps.valueAt(ia);
5790                        if (app.persistent) {
5791                            // We don't kill persistent processes.
5792                            continue;
5793                        }
5794                        if (app.removed) {
5795                            procs.add(app);
5796                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5797                            app.removed = true;
5798                            procs.add(app);
5799                        }
5800                    }
5801                }
5802
5803                final int N = procs.size();
5804                for (int i = 0; i < N; i++) {
5805                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5806                }
5807
5808                mAllowLowerMemLevel = true;
5809
5810                updateOomAdjLocked();
5811                doLowMemReportIfNeededLocked(null);
5812            }
5813        } finally {
5814            Binder.restoreCallingIdentity(callingId);
5815        }
5816    }
5817
5818    /**
5819     * Kills all background processes, except those matching any of the
5820     * specified properties.
5821     *
5822     * @param minTargetSdk the target SDK version at or above which to preserve
5823     *                     processes, or {@code -1} to ignore the target SDK
5824     * @param maxProcState the process state at or below which to preserve
5825     *                     processes, or {@code -1} to ignore the process state
5826     */
5827    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5828        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5829                != PackageManager.PERMISSION_GRANTED) {
5830            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5831                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5832                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5833            Slog.w(TAG, msg);
5834            throw new SecurityException(msg);
5835        }
5836
5837        final long callingId = Binder.clearCallingIdentity();
5838        try {
5839            synchronized (this) {
5840                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5841                final int NP = mProcessNames.getMap().size();
5842                for (int ip = 0; ip < NP; ip++) {
5843                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5844                    final int NA = apps.size();
5845                    for (int ia = 0; ia < NA; ia++) {
5846                        final ProcessRecord app = apps.valueAt(ia);
5847                        if (app.removed) {
5848                            procs.add(app);
5849                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5850                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5851                            app.removed = true;
5852                            procs.add(app);
5853                        }
5854                    }
5855                }
5856
5857                final int N = procs.size();
5858                for (int i = 0; i < N; i++) {
5859                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5860                }
5861            }
5862        } finally {
5863            Binder.restoreCallingIdentity(callingId);
5864        }
5865    }
5866
5867    @Override
5868    public void forceStopPackage(final String packageName, int userId) {
5869        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5870                != PackageManager.PERMISSION_GRANTED) {
5871            String msg = "Permission Denial: forceStopPackage() from pid="
5872                    + Binder.getCallingPid()
5873                    + ", uid=" + Binder.getCallingUid()
5874                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5875            Slog.w(TAG, msg);
5876            throw new SecurityException(msg);
5877        }
5878        final int callingPid = Binder.getCallingPid();
5879        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5880                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5881        long callingId = Binder.clearCallingIdentity();
5882        try {
5883            IPackageManager pm = AppGlobals.getPackageManager();
5884            synchronized(this) {
5885                int[] users = userId == UserHandle.USER_ALL
5886                        ? mUserController.getUsers() : new int[] { userId };
5887                for (int user : users) {
5888                    int pkgUid = -1;
5889                    try {
5890                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5891                                user);
5892                    } catch (RemoteException e) {
5893                    }
5894                    if (pkgUid == -1) {
5895                        Slog.w(TAG, "Invalid packageName: " + packageName);
5896                        continue;
5897                    }
5898                    try {
5899                        pm.setPackageStoppedState(packageName, true, user);
5900                    } catch (RemoteException e) {
5901                    } catch (IllegalArgumentException e) {
5902                        Slog.w(TAG, "Failed trying to unstop package "
5903                                + packageName + ": " + e);
5904                    }
5905                    if (mUserController.isUserRunningLocked(user, 0)) {
5906                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5907                        finishForceStopPackageLocked(packageName, pkgUid);
5908                    }
5909                }
5910            }
5911        } finally {
5912            Binder.restoreCallingIdentity(callingId);
5913        }
5914    }
5915
5916    @Override
5917    public void addPackageDependency(String packageName) {
5918        synchronized (this) {
5919            int callingPid = Binder.getCallingPid();
5920            if (callingPid == myPid()) {
5921                //  Yeah, um, no.
5922                return;
5923            }
5924            ProcessRecord proc;
5925            synchronized (mPidsSelfLocked) {
5926                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5927            }
5928            if (proc != null) {
5929                if (proc.pkgDeps == null) {
5930                    proc.pkgDeps = new ArraySet<String>(1);
5931                }
5932                proc.pkgDeps.add(packageName);
5933            }
5934        }
5935    }
5936
5937    /*
5938     * The pkg name and app id have to be specified.
5939     */
5940    @Override
5941    public void killApplication(String pkg, int appId, int userId, String reason) {
5942        if (pkg == null) {
5943            return;
5944        }
5945        // Make sure the uid is valid.
5946        if (appId < 0) {
5947            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5948            return;
5949        }
5950        int callerUid = Binder.getCallingUid();
5951        // Only the system server can kill an application
5952        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
5953            // Post an aysnc message to kill the application
5954            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5955            msg.arg1 = appId;
5956            msg.arg2 = userId;
5957            Bundle bundle = new Bundle();
5958            bundle.putString("pkg", pkg);
5959            bundle.putString("reason", reason);
5960            msg.obj = bundle;
5961            mHandler.sendMessage(msg);
5962        } else {
5963            throw new SecurityException(callerUid + " cannot kill pkg: " +
5964                    pkg);
5965        }
5966    }
5967
5968    @Override
5969    public void closeSystemDialogs(String reason) {
5970        enforceNotIsolatedCaller("closeSystemDialogs");
5971
5972        final int pid = Binder.getCallingPid();
5973        final int uid = Binder.getCallingUid();
5974        final long origId = Binder.clearCallingIdentity();
5975        try {
5976            synchronized (this) {
5977                // Only allow this from foreground processes, so that background
5978                // applications can't abuse it to prevent system UI from being shown.
5979                if (uid >= FIRST_APPLICATION_UID) {
5980                    ProcessRecord proc;
5981                    synchronized (mPidsSelfLocked) {
5982                        proc = mPidsSelfLocked.get(pid);
5983                    }
5984                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5985                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5986                                + " from background process " + proc);
5987                        return;
5988                    }
5989                }
5990                closeSystemDialogsLocked(reason);
5991            }
5992        } finally {
5993            Binder.restoreCallingIdentity(origId);
5994        }
5995    }
5996
5997    void closeSystemDialogsLocked(String reason) {
5998        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5999        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6000                | Intent.FLAG_RECEIVER_FOREGROUND);
6001        if (reason != null) {
6002            intent.putExtra("reason", reason);
6003        }
6004        mWindowManager.closeSystemDialogs(reason);
6005
6006        mStackSupervisor.closeSystemDialogsLocked();
6007
6008        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6009                AppOpsManager.OP_NONE, null, false, false,
6010                -1, SYSTEM_UID, UserHandle.USER_ALL);
6011    }
6012
6013    @Override
6014    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6015        enforceNotIsolatedCaller("getProcessMemoryInfo");
6016        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6017        for (int i=pids.length-1; i>=0; i--) {
6018            ProcessRecord proc;
6019            int oomAdj;
6020            synchronized (this) {
6021                synchronized (mPidsSelfLocked) {
6022                    proc = mPidsSelfLocked.get(pids[i]);
6023                    oomAdj = proc != null ? proc.setAdj : 0;
6024                }
6025            }
6026            infos[i] = new Debug.MemoryInfo();
6027            Debug.getMemoryInfo(pids[i], infos[i]);
6028            if (proc != null) {
6029                synchronized (this) {
6030                    if (proc.thread != null && proc.setAdj == oomAdj) {
6031                        // Record this for posterity if the process has been stable.
6032                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6033                                infos[i].getTotalUss(), false, proc.pkgList);
6034                    }
6035                }
6036            }
6037        }
6038        return infos;
6039    }
6040
6041    @Override
6042    public long[] getProcessPss(int[] pids) {
6043        enforceNotIsolatedCaller("getProcessPss");
6044        long[] pss = new long[pids.length];
6045        for (int i=pids.length-1; i>=0; i--) {
6046            ProcessRecord proc;
6047            int oomAdj;
6048            synchronized (this) {
6049                synchronized (mPidsSelfLocked) {
6050                    proc = mPidsSelfLocked.get(pids[i]);
6051                    oomAdj = proc != null ? proc.setAdj : 0;
6052                }
6053            }
6054            long[] tmpUss = new long[1];
6055            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6056            if (proc != null) {
6057                synchronized (this) {
6058                    if (proc.thread != null && proc.setAdj == oomAdj) {
6059                        // Record this for posterity if the process has been stable.
6060                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6061                    }
6062                }
6063            }
6064        }
6065        return pss;
6066    }
6067
6068    @Override
6069    public void killApplicationProcess(String processName, int uid) {
6070        if (processName == null) {
6071            return;
6072        }
6073
6074        int callerUid = Binder.getCallingUid();
6075        // Only the system server can kill an application
6076        if (callerUid == SYSTEM_UID) {
6077            synchronized (this) {
6078                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6079                if (app != null && app.thread != null) {
6080                    try {
6081                        app.thread.scheduleSuicide();
6082                    } catch (RemoteException e) {
6083                        // If the other end already died, then our work here is done.
6084                    }
6085                } else {
6086                    Slog.w(TAG, "Process/uid not found attempting kill of "
6087                            + processName + " / " + uid);
6088                }
6089            }
6090        } else {
6091            throw new SecurityException(callerUid + " cannot kill app process: " +
6092                    processName);
6093        }
6094    }
6095
6096    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6097        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6098                false, true, false, false, UserHandle.getUserId(uid), reason);
6099    }
6100
6101    private void finishForceStopPackageLocked(final String packageName, int uid) {
6102        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6103                Uri.fromParts("package", packageName, null));
6104        if (!mProcessesReady) {
6105            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6106                    | Intent.FLAG_RECEIVER_FOREGROUND);
6107        }
6108        intent.putExtra(Intent.EXTRA_UID, uid);
6109        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6110        broadcastIntentLocked(null, null, intent,
6111                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6112                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6113    }
6114
6115
6116    private final boolean killPackageProcessesLocked(String packageName, int appId,
6117            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6118            boolean doit, boolean evenPersistent, String reason) {
6119        ArrayList<ProcessRecord> procs = new ArrayList<>();
6120
6121        // Remove all processes this package may have touched: all with the
6122        // same UID (except for the system or root user), and all whose name
6123        // matches the package name.
6124        final int NP = mProcessNames.getMap().size();
6125        for (int ip=0; ip<NP; ip++) {
6126            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6127            final int NA = apps.size();
6128            for (int ia=0; ia<NA; ia++) {
6129                ProcessRecord app = apps.valueAt(ia);
6130                if (app.persistent && !evenPersistent) {
6131                    // we don't kill persistent processes
6132                    continue;
6133                }
6134                if (app.removed) {
6135                    if (doit) {
6136                        procs.add(app);
6137                    }
6138                    continue;
6139                }
6140
6141                // Skip process if it doesn't meet our oom adj requirement.
6142                if (app.setAdj < minOomAdj) {
6143                    continue;
6144                }
6145
6146                // If no package is specified, we call all processes under the
6147                // give user id.
6148                if (packageName == null) {
6149                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6150                        continue;
6151                    }
6152                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6153                        continue;
6154                    }
6155                // Package has been specified, we want to hit all processes
6156                // that match it.  We need to qualify this by the processes
6157                // that are running under the specified app and user ID.
6158                } else {
6159                    final boolean isDep = app.pkgDeps != null
6160                            && app.pkgDeps.contains(packageName);
6161                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6162                        continue;
6163                    }
6164                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6165                        continue;
6166                    }
6167                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6168                        continue;
6169                    }
6170                }
6171
6172                // Process has passed all conditions, kill it!
6173                if (!doit) {
6174                    return true;
6175                }
6176                app.removed = true;
6177                procs.add(app);
6178            }
6179        }
6180
6181        int N = procs.size();
6182        for (int i=0; i<N; i++) {
6183            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6184        }
6185        updateOomAdjLocked();
6186        return N > 0;
6187    }
6188
6189    private void cleanupDisabledPackageComponentsLocked(
6190            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6191
6192        Set<String> disabledClasses = null;
6193        boolean packageDisabled = false;
6194        IPackageManager pm = AppGlobals.getPackageManager();
6195
6196        if (changedClasses == null) {
6197            // Nothing changed...
6198            return;
6199        }
6200
6201        // Determine enable/disable state of the package and its components.
6202        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6203        for (int i = changedClasses.length - 1; i >= 0; i--) {
6204            final String changedClass = changedClasses[i];
6205
6206            if (changedClass.equals(packageName)) {
6207                try {
6208                    // Entire package setting changed
6209                    enabled = pm.getApplicationEnabledSetting(packageName,
6210                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6211                } catch (Exception e) {
6212                    // No such package/component; probably racing with uninstall.  In any
6213                    // event it means we have nothing further to do here.
6214                    return;
6215                }
6216                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6217                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6218                if (packageDisabled) {
6219                    // Entire package is disabled.
6220                    // No need to continue to check component states.
6221                    disabledClasses = null;
6222                    break;
6223                }
6224            } else {
6225                try {
6226                    enabled = pm.getComponentEnabledSetting(
6227                            new ComponentName(packageName, changedClass),
6228                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6229                } catch (Exception e) {
6230                    // As above, probably racing with uninstall.
6231                    return;
6232                }
6233                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6234                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6235                    if (disabledClasses == null) {
6236                        disabledClasses = new ArraySet<>(changedClasses.length);
6237                    }
6238                    disabledClasses.add(changedClass);
6239                }
6240            }
6241        }
6242
6243        if (!packageDisabled && disabledClasses == null) {
6244            // Nothing to do here...
6245            return;
6246        }
6247
6248        // Clean-up disabled activities.
6249        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6250                packageName, disabledClasses, true, false, userId) && mBooted) {
6251            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6252            mStackSupervisor.scheduleIdleLocked();
6253        }
6254
6255        // Clean-up disabled tasks
6256        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6257
6258        // Clean-up disabled services.
6259        mServices.bringDownDisabledPackageServicesLocked(
6260                packageName, disabledClasses, userId, false, killProcess, true);
6261
6262        // Clean-up disabled providers.
6263        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6264        mProviderMap.collectPackageProvidersLocked(
6265                packageName, disabledClasses, true, false, userId, providers);
6266        for (int i = providers.size() - 1; i >= 0; i--) {
6267            removeDyingProviderLocked(null, providers.get(i), true);
6268        }
6269
6270        // Clean-up disabled broadcast receivers.
6271        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6272            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6273                    packageName, disabledClasses, userId, true);
6274        }
6275
6276    }
6277
6278    final boolean clearBroadcastQueueForUserLocked(int userId) {
6279        boolean didSomething = false;
6280        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6281            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6282                    null, null, userId, true);
6283        }
6284        return didSomething;
6285    }
6286
6287    final boolean forceStopPackageLocked(String packageName, int appId,
6288            boolean callerWillRestart, boolean purgeCache, boolean doit,
6289            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6290        int i;
6291
6292        if (userId == UserHandle.USER_ALL && packageName == null) {
6293            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6294        }
6295
6296        if (appId < 0 && packageName != null) {
6297            try {
6298                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6299                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6300            } catch (RemoteException e) {
6301            }
6302        }
6303
6304        if (doit) {
6305            if (packageName != null) {
6306                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6307                        + " user=" + userId + ": " + reason);
6308            } else {
6309                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6310            }
6311
6312            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6313        }
6314
6315        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6316                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6317                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6318
6319        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6320
6321        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6322                packageName, null, doit, evenPersistent, userId)) {
6323            if (!doit) {
6324                return true;
6325            }
6326            didSomething = true;
6327        }
6328
6329        if (mServices.bringDownDisabledPackageServicesLocked(
6330                packageName, null, userId, evenPersistent, true, doit)) {
6331            if (!doit) {
6332                return true;
6333            }
6334            didSomething = true;
6335        }
6336
6337        if (packageName == null) {
6338            // Remove all sticky broadcasts from this user.
6339            mStickyBroadcasts.remove(userId);
6340        }
6341
6342        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6343        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6344                userId, providers)) {
6345            if (!doit) {
6346                return true;
6347            }
6348            didSomething = true;
6349        }
6350        for (i = providers.size() - 1; i >= 0; i--) {
6351            removeDyingProviderLocked(null, providers.get(i), true);
6352        }
6353
6354        // Remove transient permissions granted from/to this package/user
6355        removeUriPermissionsForPackageLocked(packageName, userId, false);
6356
6357        if (doit) {
6358            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6359                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6360                        packageName, null, userId, doit);
6361            }
6362        }
6363
6364        if (packageName == null || uninstalling) {
6365            // Remove pending intents.  For now we only do this when force
6366            // stopping users, because we have some problems when doing this
6367            // for packages -- app widgets are not currently cleaned up for
6368            // such packages, so they can be left with bad pending intents.
6369            if (mIntentSenderRecords.size() > 0) {
6370                Iterator<WeakReference<PendingIntentRecord>> it
6371                        = mIntentSenderRecords.values().iterator();
6372                while (it.hasNext()) {
6373                    WeakReference<PendingIntentRecord> wpir = it.next();
6374                    if (wpir == null) {
6375                        it.remove();
6376                        continue;
6377                    }
6378                    PendingIntentRecord pir = wpir.get();
6379                    if (pir == null) {
6380                        it.remove();
6381                        continue;
6382                    }
6383                    if (packageName == null) {
6384                        // Stopping user, remove all objects for the user.
6385                        if (pir.key.userId != userId) {
6386                            // Not the same user, skip it.
6387                            continue;
6388                        }
6389                    } else {
6390                        if (UserHandle.getAppId(pir.uid) != appId) {
6391                            // Different app id, skip it.
6392                            continue;
6393                        }
6394                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6395                            // Different user, skip it.
6396                            continue;
6397                        }
6398                        if (!pir.key.packageName.equals(packageName)) {
6399                            // Different package, skip it.
6400                            continue;
6401                        }
6402                    }
6403                    if (!doit) {
6404                        return true;
6405                    }
6406                    didSomething = true;
6407                    it.remove();
6408                    makeIntentSenderCanceledLocked(pir);
6409                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6410                        pir.key.activity.pendingResults.remove(pir.ref);
6411                    }
6412                }
6413            }
6414        }
6415
6416        if (doit) {
6417            if (purgeCache && packageName != null) {
6418                AttributeCache ac = AttributeCache.instance();
6419                if (ac != null) {
6420                    ac.removePackage(packageName);
6421                }
6422            }
6423            if (mBooted) {
6424                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6425                mStackSupervisor.scheduleIdleLocked();
6426            }
6427        }
6428
6429        return didSomething;
6430    }
6431
6432    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6433        return removeProcessNameLocked(name, uid, null);
6434    }
6435
6436    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6437            final ProcessRecord expecting) {
6438        ProcessRecord old = mProcessNames.get(name, uid);
6439        // Only actually remove when the currently recorded value matches the
6440        // record that we expected; if it doesn't match then we raced with a
6441        // newly created process and we don't want to destroy the new one.
6442        if ((expecting == null) || (old == expecting)) {
6443            mProcessNames.remove(name, uid);
6444        }
6445        if (old != null && old.uidRecord != null) {
6446            old.uidRecord.numProcs--;
6447            if (old.uidRecord.numProcs == 0) {
6448                // No more processes using this uid, tell clients it is gone.
6449                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6450                        "No more processes in " + old.uidRecord);
6451                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6452                mActiveUids.remove(uid);
6453                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6454            }
6455            old.uidRecord = null;
6456        }
6457        mIsolatedProcesses.remove(uid);
6458        return old;
6459    }
6460
6461    private final void addProcessNameLocked(ProcessRecord proc) {
6462        // We shouldn't already have a process under this name, but just in case we
6463        // need to clean up whatever may be there now.
6464        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6465        if (old == proc && proc.persistent) {
6466            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6467            Slog.w(TAG, "Re-adding persistent process " + proc);
6468        } else if (old != null) {
6469            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6470        }
6471        UidRecord uidRec = mActiveUids.get(proc.uid);
6472        if (uidRec == null) {
6473            uidRec = new UidRecord(proc.uid);
6474            // This is the first appearance of the uid, report it now!
6475            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6476                    "Creating new process uid: " + uidRec);
6477            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6478                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6479                uidRec.setWhitelist = uidRec.curWhitelist = true;
6480            }
6481            uidRec.updateHasInternetPermission();
6482            mActiveUids.put(proc.uid, uidRec);
6483            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6484            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6485        }
6486        proc.uidRecord = uidRec;
6487
6488        // Reset render thread tid if it was already set, so new process can set it again.
6489        proc.renderThreadTid = 0;
6490        uidRec.numProcs++;
6491        mProcessNames.put(proc.processName, proc.uid, proc);
6492        if (proc.isolated) {
6493            mIsolatedProcesses.put(proc.uid, proc);
6494        }
6495    }
6496
6497    boolean removeProcessLocked(ProcessRecord app,
6498            boolean callerWillRestart, boolean allowRestart, String reason) {
6499        final String name = app.processName;
6500        final int uid = app.uid;
6501        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6502            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6503
6504        ProcessRecord old = mProcessNames.get(name, uid);
6505        if (old != app) {
6506            // This process is no longer active, so nothing to do.
6507            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6508            return false;
6509        }
6510        removeProcessNameLocked(name, uid);
6511        if (mHeavyWeightProcess == app) {
6512            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6513                    mHeavyWeightProcess.userId, 0));
6514            mHeavyWeightProcess = null;
6515        }
6516        boolean needRestart = false;
6517        if (app.pid > 0 && app.pid != MY_PID) {
6518            int pid = app.pid;
6519            synchronized (mPidsSelfLocked) {
6520                mPidsSelfLocked.remove(pid);
6521                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6522            }
6523            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6524            if (app.isolated) {
6525                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6526                getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6527            }
6528            boolean willRestart = false;
6529            if (app.persistent && !app.isolated) {
6530                if (!callerWillRestart) {
6531                    willRestart = true;
6532                } else {
6533                    needRestart = true;
6534                }
6535            }
6536            app.kill(reason, true);
6537            handleAppDiedLocked(app, willRestart, allowRestart);
6538            if (willRestart) {
6539                removeLruProcessLocked(app);
6540                addAppLocked(app.info, null, false, null /* ABI override */);
6541            }
6542        } else {
6543            mRemovedProcesses.add(app);
6544        }
6545
6546        return needRestart;
6547    }
6548
6549    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6550        cleanupAppInLaunchingProvidersLocked(app, true);
6551        removeProcessLocked(app, false, true, "timeout publishing content providers");
6552    }
6553
6554    private final void processStartTimedOutLocked(ProcessRecord app) {
6555        final int pid = app.pid;
6556        boolean gone = false;
6557        synchronized (mPidsSelfLocked) {
6558            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6559            if (knownApp != null && knownApp.thread == null) {
6560                mPidsSelfLocked.remove(pid);
6561                gone = true;
6562            }
6563        }
6564
6565        if (gone) {
6566            Slog.w(TAG, "Process " + app + " failed to attach");
6567            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6568                    pid, app.uid, app.processName);
6569            removeProcessNameLocked(app.processName, app.uid);
6570            if (mHeavyWeightProcess == app) {
6571                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6572                        mHeavyWeightProcess.userId, 0));
6573                mHeavyWeightProcess = null;
6574            }
6575            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6576            if (app.isolated) {
6577                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6578            }
6579            // Take care of any launching providers waiting for this process.
6580            cleanupAppInLaunchingProvidersLocked(app, true);
6581            // Take care of any services that are waiting for the process.
6582            mServices.processStartTimedOutLocked(app);
6583            app.kill("start timeout", true);
6584            removeLruProcessLocked(app);
6585            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6586                Slog.w(TAG, "Unattached app died before backup, skipping");
6587                mHandler.post(new Runnable() {
6588                @Override
6589                    public void run(){
6590                        try {
6591                            IBackupManager bm = IBackupManager.Stub.asInterface(
6592                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6593                            bm.agentDisconnected(app.info.packageName);
6594                        } catch (RemoteException e) {
6595                            // Can't happen; the backup manager is local
6596                        }
6597                    }
6598                });
6599            }
6600            if (isPendingBroadcastProcessLocked(pid)) {
6601                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6602                skipPendingBroadcastLocked(pid);
6603            }
6604        } else {
6605            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6606        }
6607    }
6608
6609    private final boolean attachApplicationLocked(IApplicationThread thread,
6610            int pid) {
6611
6612        // Find the application record that is being attached...  either via
6613        // the pid if we are running in multiple processes, or just pull the
6614        // next app record if we are emulating process with anonymous threads.
6615        ProcessRecord app;
6616        long startTime = SystemClock.uptimeMillis();
6617        if (pid != MY_PID && pid >= 0) {
6618            synchronized (mPidsSelfLocked) {
6619                app = mPidsSelfLocked.get(pid);
6620            }
6621        } else {
6622            app = null;
6623        }
6624
6625        if (app == null) {
6626            Slog.w(TAG, "No pending application record for pid " + pid
6627                    + " (IApplicationThread " + thread + "); dropping process");
6628            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6629            if (pid > 0 && pid != MY_PID) {
6630                killProcessQuiet(pid);
6631                //TODO: killProcessGroup(app.info.uid, pid);
6632            } else {
6633                try {
6634                    thread.scheduleExit();
6635                } catch (Exception e) {
6636                    // Ignore exceptions.
6637                }
6638            }
6639            return false;
6640        }
6641
6642        // If this application record is still attached to a previous
6643        // process, clean it up now.
6644        if (app.thread != null) {
6645            handleAppDiedLocked(app, true, true);
6646        }
6647
6648        // Tell the process all about itself.
6649
6650        if (DEBUG_ALL) Slog.v(
6651                TAG, "Binding process pid " + pid + " to record " + app);
6652
6653        final String processName = app.processName;
6654        try {
6655            AppDeathRecipient adr = new AppDeathRecipient(
6656                    app, pid, thread);
6657            thread.asBinder().linkToDeath(adr, 0);
6658            app.deathRecipient = adr;
6659        } catch (RemoteException e) {
6660            app.resetPackageList(mProcessStats);
6661            startProcessLocked(app, "link fail", processName);
6662            return false;
6663        }
6664
6665        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6666
6667        app.makeActive(thread, mProcessStats);
6668        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6669        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6670        app.forcingToForeground = null;
6671        updateProcessForegroundLocked(app, false, false);
6672        app.hasShownUi = false;
6673        app.debugging = false;
6674        app.cached = false;
6675        app.killedByAm = false;
6676        app.killed = false;
6677
6678
6679        // We carefully use the same state that PackageManager uses for
6680        // filtering, since we use this flag to decide if we need to install
6681        // providers when user is unlocked later
6682        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6683
6684        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6685
6686        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6687        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6688
6689        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6690            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6691            msg.obj = app;
6692            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6693        }
6694
6695        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6696
6697        if (!normalMode) {
6698            Slog.i(TAG, "Launching preboot mode app: " + app);
6699        }
6700
6701        if (DEBUG_ALL) Slog.v(
6702            TAG, "New app record " + app
6703            + " thread=" + thread.asBinder() + " pid=" + pid);
6704        try {
6705            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6706            if (mDebugApp != null && mDebugApp.equals(processName)) {
6707                testMode = mWaitForDebugger
6708                    ? ApplicationThreadConstants.DEBUG_WAIT
6709                    : ApplicationThreadConstants.DEBUG_ON;
6710                app.debugging = true;
6711                if (mDebugTransient) {
6712                    mDebugApp = mOrigDebugApp;
6713                    mWaitForDebugger = mOrigWaitForDebugger;
6714                }
6715            }
6716            String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6717            ParcelFileDescriptor profileFd = null;
6718            int samplingInterval = 0;
6719            boolean profileAutoStop = false;
6720            boolean profileStreamingOutput = false;
6721            if (mProfileApp != null && mProfileApp.equals(processName)) {
6722                mProfileProc = app;
6723                profileFile = mProfileFile;
6724                profileFd = mProfileFd;
6725                samplingInterval = mSamplingInterval;
6726                profileAutoStop = mAutoStopProfiler;
6727                profileStreamingOutput = mStreamingOutput;
6728            }
6729            boolean enableTrackAllocation = false;
6730            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6731                enableTrackAllocation = true;
6732                mTrackAllocationApp = null;
6733            }
6734
6735            // If the app is being launched for restore or full backup, set it up specially
6736            boolean isRestrictedBackupMode = false;
6737            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6738                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
6739                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6740                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6741                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6742            }
6743
6744            if (app.instr != null) {
6745                notifyPackageUse(app.instr.mClass.getPackageName(),
6746                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6747            }
6748            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6749                    + processName + " with config " + getGlobalConfiguration());
6750            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6751            app.compat = compatibilityInfoForPackageLocked(appInfo);
6752            if (profileFd != null) {
6753                profileFd = profileFd.dup();
6754            }
6755            ProfilerInfo profilerInfo = profileFile == null ? null
6756                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6757                                       profileStreamingOutput);
6758
6759            // We deprecated Build.SERIAL and it is not accessible to
6760            // apps that target the v2 security sandbox. Since access to
6761            // the serial is now behind a permission we push down the value.
6762            String buildSerial = Build.UNKNOWN;
6763            if (appInfo.targetSandboxVersion != 2) {
6764                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6765                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6766                        .getSerial();
6767            }
6768
6769            // Check if this is a secondary process that should be incorporated into some
6770            // currently active instrumentation.  (Note we do this AFTER all of the profiling
6771            // stuff above because profiling can currently happen only in the primary
6772            // instrumentation process.)
6773            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6774                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6775                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6776                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6777                        if (aInstr.mTargetProcesses.length == 0) {
6778                            // This is the wildcard mode, where every process brought up for
6779                            // the target instrumentation should be included.
6780                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6781                                app.instr = aInstr;
6782                                aInstr.mRunningProcesses.add(app);
6783                            }
6784                        } else {
6785                            for (String proc : aInstr.mTargetProcesses) {
6786                                if (proc.equals(app.processName)) {
6787                                    app.instr = aInstr;
6788                                    aInstr.mRunningProcesses.add(app);
6789                                    break;
6790                                }
6791                            }
6792                        }
6793                    }
6794                }
6795            }
6796
6797            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6798            if (app.instr != null) {
6799                thread.bindApplication(processName, appInfo, providers,
6800                        app.instr.mClass,
6801                        profilerInfo, app.instr.mArguments,
6802                        app.instr.mWatcher,
6803                        app.instr.mUiAutomationConnection, testMode,
6804                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6805                        isRestrictedBackupMode || !normalMode, app.persistent,
6806                        new Configuration(getGlobalConfiguration()), app.compat,
6807                        getCommonServicesLocked(app.isolated),
6808                        mCoreSettingsObserver.getCoreSettingsLocked(),
6809                        buildSerial);
6810            } else {
6811                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6812                        null, null, null, testMode,
6813                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6814                        isRestrictedBackupMode || !normalMode, app.persistent,
6815                        new Configuration(getGlobalConfiguration()), app.compat,
6816                        getCommonServicesLocked(app.isolated),
6817                        mCoreSettingsObserver.getCoreSettingsLocked(),
6818                        buildSerial);
6819            }
6820
6821            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6822            updateLruProcessLocked(app, false, null);
6823            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6824            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6825        } catch (Exception e) {
6826            // todo: Yikes!  What should we do?  For now we will try to
6827            // start another process, but that could easily get us in
6828            // an infinite loop of restarting processes...
6829            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6830
6831            app.resetPackageList(mProcessStats);
6832            app.unlinkDeathRecipient();
6833            startProcessLocked(app, "bind fail", processName);
6834            return false;
6835        }
6836
6837        // Remove this record from the list of starting applications.
6838        mPersistentStartingProcesses.remove(app);
6839        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6840                "Attach application locked removing on hold: " + app);
6841        mProcessesOnHold.remove(app);
6842
6843        boolean badApp = false;
6844        boolean didSomething = false;
6845
6846        // See if the top visible activity is waiting to run in this process...
6847        if (normalMode) {
6848            try {
6849                if (mStackSupervisor.attachApplicationLocked(app)) {
6850                    didSomething = true;
6851                }
6852            } catch (Exception e) {
6853                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6854                badApp = true;
6855            }
6856        }
6857
6858        // Find any services that should be running in this process...
6859        if (!badApp) {
6860            try {
6861                didSomething |= mServices.attachApplicationLocked(app, processName);
6862                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6863            } catch (Exception e) {
6864                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6865                badApp = true;
6866            }
6867        }
6868
6869        // Check if a next-broadcast receiver is in this process...
6870        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6871            try {
6872                didSomething |= sendPendingBroadcastsLocked(app);
6873                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6874            } catch (Exception e) {
6875                // If the app died trying to launch the receiver we declare it 'bad'
6876                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6877                badApp = true;
6878            }
6879        }
6880
6881        // Check whether the next backup agent is in this process...
6882        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6883            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6884                    "New app is backup target, launching agent for " + app);
6885            notifyPackageUse(mBackupTarget.appInfo.packageName,
6886                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6887            try {
6888                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6889                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6890                        mBackupTarget.backupMode);
6891            } catch (Exception e) {
6892                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6893                badApp = true;
6894            }
6895        }
6896
6897        if (badApp) {
6898            app.kill("error during init", true);
6899            handleAppDiedLocked(app, false, true);
6900            return false;
6901        }
6902
6903        if (!didSomething) {
6904            updateOomAdjLocked();
6905            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6906        }
6907
6908        return true;
6909    }
6910
6911    @Override
6912    public final void attachApplication(IApplicationThread thread) {
6913        synchronized (this) {
6914            int callingPid = Binder.getCallingPid();
6915            final long origId = Binder.clearCallingIdentity();
6916            attachApplicationLocked(thread, callingPid);
6917            Binder.restoreCallingIdentity(origId);
6918        }
6919    }
6920
6921    @Override
6922    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6923        final long origId = Binder.clearCallingIdentity();
6924        synchronized (this) {
6925            ActivityStack stack = ActivityRecord.getStackLocked(token);
6926            if (stack != null) {
6927                ActivityRecord r =
6928                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
6929                                false /* processPausingActivities */, config);
6930                if (stopProfiling) {
6931                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6932                        try {
6933                            mProfileFd.close();
6934                        } catch (IOException e) {
6935                        }
6936                        clearProfilerLocked();
6937                    }
6938                }
6939            }
6940        }
6941        Binder.restoreCallingIdentity(origId);
6942    }
6943
6944    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6945        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6946                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6947    }
6948
6949    void enableScreenAfterBoot() {
6950        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6951                SystemClock.uptimeMillis());
6952        mWindowManager.enableScreenAfterBoot();
6953
6954        synchronized (this) {
6955            updateEventDispatchingLocked();
6956        }
6957    }
6958
6959    @Override
6960    public void showBootMessage(final CharSequence msg, final boolean always) {
6961        if (Binder.getCallingUid() != myUid()) {
6962            throw new SecurityException();
6963        }
6964        mWindowManager.showBootMessage(msg, always);
6965    }
6966
6967    @Override
6968    public void keyguardGoingAway(int flags) {
6969        enforceNotIsolatedCaller("keyguardGoingAway");
6970        final long token = Binder.clearCallingIdentity();
6971        try {
6972            synchronized (this) {
6973                mKeyguardController.keyguardGoingAway(flags);
6974            }
6975        } finally {
6976            Binder.restoreCallingIdentity(token);
6977        }
6978    }
6979
6980    /**
6981     * @return whther the keyguard is currently locked.
6982     */
6983    boolean isKeyguardLocked() {
6984        return mKeyguardController.isKeyguardLocked();
6985    }
6986
6987    final void finishBooting() {
6988        synchronized (this) {
6989            if (!mBootAnimationComplete) {
6990                mCallFinishBooting = true;
6991                return;
6992            }
6993            mCallFinishBooting = false;
6994        }
6995
6996        ArraySet<String> completedIsas = new ArraySet<String>();
6997        for (String abi : Build.SUPPORTED_ABIS) {
6998            zygoteProcess.establishZygoteConnectionForAbi(abi);
6999            final String instructionSet = VMRuntime.getInstructionSet(abi);
7000            if (!completedIsas.contains(instructionSet)) {
7001                try {
7002                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7003                } catch (InstallerException e) {
7004                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7005                            e.getMessage() +")");
7006                }
7007                completedIsas.add(instructionSet);
7008            }
7009        }
7010
7011        IntentFilter pkgFilter = new IntentFilter();
7012        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7013        pkgFilter.addDataScheme("package");
7014        mContext.registerReceiver(new BroadcastReceiver() {
7015            @Override
7016            public void onReceive(Context context, Intent intent) {
7017                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7018                if (pkgs != null) {
7019                    for (String pkg : pkgs) {
7020                        synchronized (ActivityManagerService.this) {
7021                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7022                                    0, "query restart")) {
7023                                setResultCode(Activity.RESULT_OK);
7024                                return;
7025                            }
7026                        }
7027                    }
7028                }
7029            }
7030        }, pkgFilter);
7031
7032        IntentFilter dumpheapFilter = new IntentFilter();
7033        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7034        mContext.registerReceiver(new BroadcastReceiver() {
7035            @Override
7036            public void onReceive(Context context, Intent intent) {
7037                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7038                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7039                } else {
7040                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7041                }
7042            }
7043        }, dumpheapFilter);
7044
7045        // Let system services know.
7046        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7047
7048        synchronized (this) {
7049            // Ensure that any processes we had put on hold are now started
7050            // up.
7051            final int NP = mProcessesOnHold.size();
7052            if (NP > 0) {
7053                ArrayList<ProcessRecord> procs =
7054                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7055                for (int ip=0; ip<NP; ip++) {
7056                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7057                            + procs.get(ip));
7058                    startProcessLocked(procs.get(ip), "on-hold", null);
7059                }
7060            }
7061
7062            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7063                // Start looking for apps that are abusing wake locks.
7064                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7065                mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
7066                // Tell anyone interested that we are done booting!
7067                SystemProperties.set("sys.boot_completed", "1");
7068
7069                // And trigger dev.bootcomplete if we are not showing encryption progress
7070                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7071                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7072                    SystemProperties.set("dev.bootcomplete", "1");
7073                }
7074                mUserController.sendBootCompletedLocked(
7075                        new IIntentReceiver.Stub() {
7076                            @Override
7077                            public void performReceive(Intent intent, int resultCode,
7078                                    String data, Bundle extras, boolean ordered,
7079                                    boolean sticky, int sendingUser) {
7080                                synchronized (ActivityManagerService.this) {
7081                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7082                                            true, false);
7083                                }
7084                            }
7085                        });
7086                scheduleStartProfilesLocked();
7087            }
7088        }
7089    }
7090
7091    @Override
7092    public void bootAnimationComplete() {
7093        final boolean callFinishBooting;
7094        synchronized (this) {
7095            callFinishBooting = mCallFinishBooting;
7096            mBootAnimationComplete = true;
7097        }
7098        if (callFinishBooting) {
7099            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7100            finishBooting();
7101            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7102        }
7103    }
7104
7105    final void ensureBootCompleted() {
7106        boolean booting;
7107        boolean enableScreen;
7108        synchronized (this) {
7109            booting = mBooting;
7110            mBooting = false;
7111            enableScreen = !mBooted;
7112            mBooted = true;
7113        }
7114
7115        if (booting) {
7116            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7117            finishBooting();
7118            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7119        }
7120
7121        if (enableScreen) {
7122            enableScreenAfterBoot();
7123        }
7124    }
7125
7126    @Override
7127    public final void activityResumed(IBinder token) {
7128        final long origId = Binder.clearCallingIdentity();
7129        synchronized(this) {
7130            ActivityRecord.activityResumedLocked(token);
7131            mWindowManager.notifyAppResumedFinished(token);
7132        }
7133        Binder.restoreCallingIdentity(origId);
7134    }
7135
7136    @Override
7137    public final void activityPaused(IBinder token) {
7138        final long origId = Binder.clearCallingIdentity();
7139        synchronized(this) {
7140            ActivityStack stack = ActivityRecord.getStackLocked(token);
7141            if (stack != null) {
7142                stack.activityPausedLocked(token, false);
7143            }
7144        }
7145        Binder.restoreCallingIdentity(origId);
7146    }
7147
7148    @Override
7149    public final void activityStopped(IBinder token, Bundle icicle,
7150            PersistableBundle persistentState, CharSequence description) {
7151        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7152
7153        // Refuse possible leaked file descriptors
7154        if (icicle != null && icicle.hasFileDescriptors()) {
7155            throw new IllegalArgumentException("File descriptors passed in Bundle");
7156        }
7157
7158        final long origId = Binder.clearCallingIdentity();
7159
7160        synchronized (this) {
7161            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7162            if (r != null) {
7163                r.activityStoppedLocked(icicle, persistentState, description);
7164            }
7165        }
7166
7167        trimApplications();
7168
7169        Binder.restoreCallingIdentity(origId);
7170    }
7171
7172    @Override
7173    public final void activityDestroyed(IBinder token) {
7174        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7175        synchronized (this) {
7176            ActivityStack stack = ActivityRecord.getStackLocked(token);
7177            if (stack != null) {
7178                stack.activityDestroyedLocked(token, "activityDestroyed");
7179            }
7180        }
7181    }
7182
7183    @Override
7184    public final void activityRelaunched(IBinder token) {
7185        final long origId = Binder.clearCallingIdentity();
7186        synchronized (this) {
7187            mStackSupervisor.activityRelaunchedLocked(token);
7188        }
7189        Binder.restoreCallingIdentity(origId);
7190    }
7191
7192    @Override
7193    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7194            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7195        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7196                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7197        synchronized (this) {
7198            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7199            if (record == null) {
7200                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7201                        + "found for: " + token);
7202            }
7203            record.setSizeConfigurations(horizontalSizeConfiguration,
7204                    verticalSizeConfigurations, smallestSizeConfigurations);
7205        }
7206    }
7207
7208    @Override
7209    public final void backgroundResourcesReleased(IBinder token) {
7210        final long origId = Binder.clearCallingIdentity();
7211        try {
7212            synchronized (this) {
7213                ActivityStack stack = ActivityRecord.getStackLocked(token);
7214                if (stack != null) {
7215                    stack.backgroundResourcesReleased();
7216                }
7217            }
7218        } finally {
7219            Binder.restoreCallingIdentity(origId);
7220        }
7221    }
7222
7223    @Override
7224    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7225        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7226    }
7227
7228    @Override
7229    public final void notifyEnterAnimationComplete(IBinder token) {
7230        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7231    }
7232
7233    @Override
7234    public String getCallingPackage(IBinder token) {
7235        synchronized (this) {
7236            ActivityRecord r = getCallingRecordLocked(token);
7237            return r != null ? r.info.packageName : null;
7238        }
7239    }
7240
7241    @Override
7242    public ComponentName getCallingActivity(IBinder token) {
7243        synchronized (this) {
7244            ActivityRecord r = getCallingRecordLocked(token);
7245            return r != null ? r.intent.getComponent() : null;
7246        }
7247    }
7248
7249    private ActivityRecord getCallingRecordLocked(IBinder token) {
7250        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7251        if (r == null) {
7252            return null;
7253        }
7254        return r.resultTo;
7255    }
7256
7257    @Override
7258    public ComponentName getActivityClassForToken(IBinder token) {
7259        synchronized(this) {
7260            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7261            if (r == null) {
7262                return null;
7263            }
7264            return r.intent.getComponent();
7265        }
7266    }
7267
7268    @Override
7269    public String getPackageForToken(IBinder token) {
7270        synchronized(this) {
7271            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7272            if (r == null) {
7273                return null;
7274            }
7275            return r.packageName;
7276        }
7277    }
7278
7279    @Override
7280    public boolean isRootVoiceInteraction(IBinder token) {
7281        synchronized(this) {
7282            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7283            if (r == null) {
7284                return false;
7285            }
7286            return r.rootVoiceInteraction;
7287        }
7288    }
7289
7290    @Override
7291    public IIntentSender getIntentSender(int type,
7292            String packageName, IBinder token, String resultWho,
7293            int requestCode, Intent[] intents, String[] resolvedTypes,
7294            int flags, Bundle bOptions, int userId) {
7295        enforceNotIsolatedCaller("getIntentSender");
7296        // Refuse possible leaked file descriptors
7297        if (intents != null) {
7298            if (intents.length < 1) {
7299                throw new IllegalArgumentException("Intents array length must be >= 1");
7300            }
7301            for (int i=0; i<intents.length; i++) {
7302                Intent intent = intents[i];
7303                if (intent != null) {
7304                    if (intent.hasFileDescriptors()) {
7305                        throw new IllegalArgumentException("File descriptors passed in Intent");
7306                    }
7307                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7308                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7309                        throw new IllegalArgumentException(
7310                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7311                    }
7312                    intents[i] = new Intent(intent);
7313                }
7314            }
7315            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7316                throw new IllegalArgumentException(
7317                        "Intent array length does not match resolvedTypes length");
7318            }
7319        }
7320        if (bOptions != null) {
7321            if (bOptions.hasFileDescriptors()) {
7322                throw new IllegalArgumentException("File descriptors passed in options");
7323            }
7324        }
7325
7326        synchronized(this) {
7327            int callingUid = Binder.getCallingUid();
7328            int origUserId = userId;
7329            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7330                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7331                    ALLOW_NON_FULL, "getIntentSender", null);
7332            if (origUserId == UserHandle.USER_CURRENT) {
7333                // We don't want to evaluate this until the pending intent is
7334                // actually executed.  However, we do want to always do the
7335                // security checking for it above.
7336                userId = UserHandle.USER_CURRENT;
7337            }
7338            try {
7339                if (callingUid != 0 && callingUid != SYSTEM_UID) {
7340                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7341                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7342                    if (!UserHandle.isSameApp(callingUid, uid)) {
7343                        String msg = "Permission Denial: getIntentSender() from pid="
7344                            + Binder.getCallingPid()
7345                            + ", uid=" + Binder.getCallingUid()
7346                            + ", (need uid=" + uid + ")"
7347                            + " is not allowed to send as package " + packageName;
7348                        Slog.w(TAG, msg);
7349                        throw new SecurityException(msg);
7350                    }
7351                }
7352
7353                return getIntentSenderLocked(type, packageName, callingUid, userId,
7354                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7355
7356            } catch (RemoteException e) {
7357                throw new SecurityException(e);
7358            }
7359        }
7360    }
7361
7362    IIntentSender getIntentSenderLocked(int type, String packageName,
7363            int callingUid, int userId, IBinder token, String resultWho,
7364            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7365            Bundle bOptions) {
7366        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7367        ActivityRecord activity = null;
7368        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7369            activity = ActivityRecord.isInStackLocked(token);
7370            if (activity == null) {
7371                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7372                return null;
7373            }
7374            if (activity.finishing) {
7375                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7376                return null;
7377            }
7378        }
7379
7380        // We're going to be splicing together extras before sending, so we're
7381        // okay poking into any contained extras.
7382        if (intents != null) {
7383            for (int i = 0; i < intents.length; i++) {
7384                intents[i].setDefusable(true);
7385            }
7386        }
7387        Bundle.setDefusable(bOptions, true);
7388
7389        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7390        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7391        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7392        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7393                |PendingIntent.FLAG_UPDATE_CURRENT);
7394
7395        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7396                type, packageName, activity, resultWho,
7397                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7398        WeakReference<PendingIntentRecord> ref;
7399        ref = mIntentSenderRecords.get(key);
7400        PendingIntentRecord rec = ref != null ? ref.get() : null;
7401        if (rec != null) {
7402            if (!cancelCurrent) {
7403                if (updateCurrent) {
7404                    if (rec.key.requestIntent != null) {
7405                        rec.key.requestIntent.replaceExtras(intents != null ?
7406                                intents[intents.length - 1] : null);
7407                    }
7408                    if (intents != null) {
7409                        intents[intents.length-1] = rec.key.requestIntent;
7410                        rec.key.allIntents = intents;
7411                        rec.key.allResolvedTypes = resolvedTypes;
7412                    } else {
7413                        rec.key.allIntents = null;
7414                        rec.key.allResolvedTypes = null;
7415                    }
7416                }
7417                return rec;
7418            }
7419            makeIntentSenderCanceledLocked(rec);
7420            mIntentSenderRecords.remove(key);
7421        }
7422        if (noCreate) {
7423            return rec;
7424        }
7425        rec = new PendingIntentRecord(this, key, callingUid);
7426        mIntentSenderRecords.put(key, rec.ref);
7427        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7428            if (activity.pendingResults == null) {
7429                activity.pendingResults
7430                        = new HashSet<WeakReference<PendingIntentRecord>>();
7431            }
7432            activity.pendingResults.add(rec.ref);
7433        }
7434        return rec;
7435    }
7436
7437    @Override
7438    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7439            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7440        if (target instanceof PendingIntentRecord) {
7441            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7442                    finishedReceiver, requiredPermission, options);
7443        } else {
7444            if (intent == null) {
7445                // Weird case: someone has given us their own custom IIntentSender, and now
7446                // they have someone else trying to send to it but of course this isn't
7447                // really a PendingIntent, so there is no base Intent, and the caller isn't
7448                // supplying an Intent... but we never want to dispatch a null Intent to
7449                // a receiver, so um...  let's make something up.
7450                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7451                intent = new Intent(Intent.ACTION_MAIN);
7452            }
7453            try {
7454                target.send(code, intent, resolvedType, null, requiredPermission, options);
7455            } catch (RemoteException e) {
7456            }
7457            // Platform code can rely on getting a result back when the send is done, but if
7458            // this intent sender is from outside of the system we can't rely on it doing that.
7459            // So instead we don't give it the result receiver, and instead just directly
7460            // report the finish immediately.
7461            if (finishedReceiver != null) {
7462                try {
7463                    finishedReceiver.performReceive(intent, 0,
7464                            null, null, false, false, UserHandle.getCallingUserId());
7465                } catch (RemoteException e) {
7466                }
7467            }
7468            return 0;
7469        }
7470    }
7471
7472    @Override
7473    public void cancelIntentSender(IIntentSender sender) {
7474        if (!(sender instanceof PendingIntentRecord)) {
7475            return;
7476        }
7477        synchronized(this) {
7478            PendingIntentRecord rec = (PendingIntentRecord)sender;
7479            try {
7480                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7481                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7482                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7483                    String msg = "Permission Denial: cancelIntentSender() from pid="
7484                        + Binder.getCallingPid()
7485                        + ", uid=" + Binder.getCallingUid()
7486                        + " is not allowed to cancel package "
7487                        + rec.key.packageName;
7488                    Slog.w(TAG, msg);
7489                    throw new SecurityException(msg);
7490                }
7491            } catch (RemoteException e) {
7492                throw new SecurityException(e);
7493            }
7494            cancelIntentSenderLocked(rec, true);
7495        }
7496    }
7497
7498    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7499        makeIntentSenderCanceledLocked(rec);
7500        mIntentSenderRecords.remove(rec.key);
7501        if (cleanActivity && rec.key.activity != null) {
7502            rec.key.activity.pendingResults.remove(rec.ref);
7503        }
7504    }
7505
7506    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7507        rec.canceled = true;
7508        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7509        if (callbacks != null) {
7510            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7511        }
7512    }
7513
7514    @Override
7515    public String getPackageForIntentSender(IIntentSender pendingResult) {
7516        if (!(pendingResult instanceof PendingIntentRecord)) {
7517            return null;
7518        }
7519        try {
7520            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7521            return res.key.packageName;
7522        } catch (ClassCastException e) {
7523        }
7524        return null;
7525    }
7526
7527    @Override
7528    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7529        if (!(sender instanceof PendingIntentRecord)) {
7530            return;
7531        }
7532        synchronized(this) {
7533            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7534        }
7535    }
7536
7537    @Override
7538    public void unregisterIntentSenderCancelListener(IIntentSender sender,
7539            IResultReceiver receiver) {
7540        if (!(sender instanceof PendingIntentRecord)) {
7541            return;
7542        }
7543        synchronized(this) {
7544            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7545        }
7546    }
7547
7548    @Override
7549    public int getUidForIntentSender(IIntentSender sender) {
7550        if (sender instanceof PendingIntentRecord) {
7551            try {
7552                PendingIntentRecord res = (PendingIntentRecord)sender;
7553                return res.uid;
7554            } catch (ClassCastException e) {
7555            }
7556        }
7557        return -1;
7558    }
7559
7560    @Override
7561    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7562        if (!(pendingResult instanceof PendingIntentRecord)) {
7563            return false;
7564        }
7565        try {
7566            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7567            if (res.key.allIntents == null) {
7568                return false;
7569            }
7570            for (int i=0; i<res.key.allIntents.length; i++) {
7571                Intent intent = res.key.allIntents[i];
7572                if (intent.getPackage() != null && intent.getComponent() != null) {
7573                    return false;
7574                }
7575            }
7576            return true;
7577        } catch (ClassCastException e) {
7578        }
7579        return false;
7580    }
7581
7582    @Override
7583    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7584        if (!(pendingResult instanceof PendingIntentRecord)) {
7585            return false;
7586        }
7587        try {
7588            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7589            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7590                return true;
7591            }
7592            return false;
7593        } catch (ClassCastException e) {
7594        }
7595        return false;
7596    }
7597
7598    @Override
7599    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7600        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7601                "getIntentForIntentSender()");
7602        if (!(pendingResult instanceof PendingIntentRecord)) {
7603            return null;
7604        }
7605        try {
7606            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7607            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7608        } catch (ClassCastException e) {
7609        }
7610        return null;
7611    }
7612
7613    @Override
7614    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7615        if (!(pendingResult instanceof PendingIntentRecord)) {
7616            return null;
7617        }
7618        try {
7619            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7620            synchronized (this) {
7621                return getTagForIntentSenderLocked(res, prefix);
7622            }
7623        } catch (ClassCastException e) {
7624        }
7625        return null;
7626    }
7627
7628    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7629        final Intent intent = res.key.requestIntent;
7630        if (intent != null) {
7631            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7632                    || res.lastTagPrefix.equals(prefix))) {
7633                return res.lastTag;
7634            }
7635            res.lastTagPrefix = prefix;
7636            final StringBuilder sb = new StringBuilder(128);
7637            if (prefix != null) {
7638                sb.append(prefix);
7639            }
7640            if (intent.getAction() != null) {
7641                sb.append(intent.getAction());
7642            } else if (intent.getComponent() != null) {
7643                intent.getComponent().appendShortString(sb);
7644            } else {
7645                sb.append("?");
7646            }
7647            return res.lastTag = sb.toString();
7648        }
7649        return null;
7650    }
7651
7652    @Override
7653    public void setProcessLimit(int max) {
7654        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7655                "setProcessLimit()");
7656        synchronized (this) {
7657            mConstants.setOverrideMaxCachedProcesses(max);
7658        }
7659        trimApplications();
7660    }
7661
7662    @Override
7663    public int getProcessLimit() {
7664        synchronized (this) {
7665            return mConstants.getOverrideMaxCachedProcesses();
7666        }
7667    }
7668
7669    void foregroundTokenDied(ForegroundToken token) {
7670        synchronized (ActivityManagerService.this) {
7671            synchronized (mPidsSelfLocked) {
7672                ForegroundToken cur
7673                    = mForegroundProcesses.get(token.pid);
7674                if (cur != token) {
7675                    return;
7676                }
7677                mForegroundProcesses.remove(token.pid);
7678                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7679                if (pr == null) {
7680                    return;
7681                }
7682                pr.forcingToForeground = null;
7683                updateProcessForegroundLocked(pr, false, false);
7684            }
7685            updateOomAdjLocked();
7686        }
7687    }
7688
7689    @Override
7690    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7691        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7692                "setProcessForeground()");
7693        synchronized(this) {
7694            boolean changed = false;
7695
7696            synchronized (mPidsSelfLocked) {
7697                ProcessRecord pr = mPidsSelfLocked.get(pid);
7698                if (pr == null && isForeground) {
7699                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7700                    return;
7701                }
7702                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7703                if (oldToken != null) {
7704                    oldToken.token.unlinkToDeath(oldToken, 0);
7705                    mForegroundProcesses.remove(pid);
7706                    if (pr != null) {
7707                        pr.forcingToForeground = null;
7708                    }
7709                    changed = true;
7710                }
7711                if (isForeground && token != null) {
7712                    ForegroundToken newToken = new ForegroundToken() {
7713                        @Override
7714                        public void binderDied() {
7715                            foregroundTokenDied(this);
7716                        }
7717                    };
7718                    newToken.pid = pid;
7719                    newToken.token = token;
7720                    try {
7721                        token.linkToDeath(newToken, 0);
7722                        mForegroundProcesses.put(pid, newToken);
7723                        pr.forcingToForeground = token;
7724                        changed = true;
7725                    } catch (RemoteException e) {
7726                        // If the process died while doing this, we will later
7727                        // do the cleanup with the process death link.
7728                    }
7729                }
7730            }
7731
7732            if (changed) {
7733                updateOomAdjLocked();
7734            }
7735        }
7736    }
7737
7738    @Override
7739    public boolean isAppForeground(int uid) throws RemoteException {
7740        synchronized (this) {
7741            UidRecord uidRec = mActiveUids.get(uid);
7742            if (uidRec == null || uidRec.idle) {
7743                return false;
7744            }
7745            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7746        }
7747    }
7748
7749    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7750    // be guarded by permission checking.
7751    int getUidState(int uid) {
7752        synchronized (this) {
7753            UidRecord uidRec = mActiveUids.get(uid);
7754            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7755        }
7756    }
7757
7758    @Override
7759    public boolean isInMultiWindowMode(IBinder token) {
7760        final long origId = Binder.clearCallingIdentity();
7761        try {
7762            synchronized(this) {
7763                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7764                if (r == null) {
7765                    return false;
7766                }
7767                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7768                return !r.getTask().mFullscreen;
7769            }
7770        } finally {
7771            Binder.restoreCallingIdentity(origId);
7772        }
7773    }
7774
7775    @Override
7776    public boolean isInPictureInPictureMode(IBinder token) {
7777        final long origId = Binder.clearCallingIdentity();
7778        try {
7779            synchronized(this) {
7780                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
7781            }
7782        } finally {
7783            Binder.restoreCallingIdentity(origId);
7784        }
7785    }
7786
7787    private boolean isInPictureInPictureMode(ActivityRecord r) {
7788        if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
7789                r.getStack().isInStackLocked(r) == null) {
7790            return false;
7791        }
7792
7793        // If we are animating to fullscreen then we have already dispatched the PIP mode
7794        // changed, so we should reflect that check here as well.
7795        final PinnedActivityStack stack = r.getStack();
7796        final PinnedStackWindowController windowController = stack.getWindowContainerController();
7797        return !windowController.isAnimatingBoundsToFullscreen();
7798    }
7799
7800    @Override
7801    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
7802        final long origId = Binder.clearCallingIdentity();
7803        try {
7804            synchronized(this) {
7805                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
7806                        "enterPictureInPictureMode", token, params);
7807
7808                // If the activity is already in picture in picture mode, then just return early
7809                if (isInPictureInPictureMode(r)) {
7810                    return true;
7811                }
7812
7813                // Activity supports picture-in-picture, now check that we can enter PiP at this
7814                // point, if it is
7815                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7816                        false /* noThrow */, false /* beforeStopping */)) {
7817                    return false;
7818                }
7819
7820                final Runnable enterPipRunnable = () -> {
7821                    // Only update the saved args from the args that are set
7822                    r.pictureInPictureArgs.copyOnlySet(params);
7823                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
7824                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
7825                    // Adjust the source bounds by the insets for the transition down
7826                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
7827                    final Rect insets = r.pictureInPictureArgs.getSourceRectHintInsets();
7828                    if (insets != null) {
7829                        sourceBounds.offsetTo(Math.max(0, sourceBounds.left - insets.left),
7830                                Math.max(0, sourceBounds.top - insets.top));
7831                    }
7832
7833                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
7834                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
7835                    final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
7836                    stack.setPictureInPictureAspectRatio(aspectRatio);
7837                    stack.setPictureInPictureActions(actions);
7838
7839                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
7840                            r.supportsPictureInPictureWhilePausing);
7841                    logPictureInPictureArgs(params);
7842                };
7843
7844                if (isKeyguardLocked()) {
7845                    // If the keyguard is showing or occluded, then try and dismiss it before
7846                    // entering picture-in-picture (this will prompt the user to authenticate if the
7847                    // device is currently locked).
7848                    try {
7849                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7850                            @Override
7851                            public void onDismissError() throws RemoteException {
7852                                // Do nothing
7853                            }
7854
7855                            @Override
7856                            public void onDismissSucceeded() throws RemoteException {
7857                                mHandler.post(enterPipRunnable);
7858                            }
7859
7860                            @Override
7861                            public void onDismissCancelled() throws RemoteException {
7862                                // Do nothing
7863                            }
7864                        });
7865                    } catch (RemoteException e) {
7866                        // Local call
7867                    }
7868                } else {
7869                    // Enter picture in picture immediately otherwise
7870                    enterPipRunnable.run();
7871                }
7872                return true;
7873            }
7874        } finally {
7875            Binder.restoreCallingIdentity(origId);
7876        }
7877    }
7878
7879    @Override
7880    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
7881        final long origId = Binder.clearCallingIdentity();
7882        try {
7883            synchronized(this) {
7884                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
7885                        "setPictureInPictureParams", token, params);
7886
7887                // Only update the saved args from the args that are set
7888                r.pictureInPictureArgs.copyOnlySet(params);
7889                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7890                    // If the activity is already in picture-in-picture, update the pinned stack now
7891                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
7892                    // be used the next time the activity enters PiP
7893                    final PinnedActivityStack stack = r.getStack();
7894                    if (!stack.isAnimatingBoundsToFullscreen()) {
7895                        stack.setPictureInPictureAspectRatio(
7896                                r.pictureInPictureArgs.getAspectRatio());
7897                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
7898                    }
7899                }
7900                logPictureInPictureArgs(params);
7901            }
7902        } finally {
7903            Binder.restoreCallingIdentity(origId);
7904        }
7905    }
7906
7907    @Override
7908    public int getMaxNumPictureInPictureActions(IBinder token) {
7909        // Currently, this is a static constant, but later, we may change this to be dependent on
7910        // the context of the activity
7911        return 3;
7912    }
7913
7914    private void logPictureInPictureArgs(PictureInPictureParams params) {
7915        if (params.hasSetActions()) {
7916            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
7917                    params.getActions().size());
7918        }
7919        if (params.hasSetAspectRatio()) {
7920            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
7921            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
7922            MetricsLogger.action(lm);
7923        }
7924    }
7925
7926    /**
7927     * Checks the state of the system and the activity associated with the given {@param token} to
7928     * verify that picture-in-picture is supported for that activity.
7929     *
7930     * @return the activity record for the given {@param token} if all the checks pass.
7931     */
7932    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
7933            IBinder token, PictureInPictureParams params) {
7934        if (!mSupportsPictureInPicture) {
7935            throw new IllegalStateException(caller
7936                    + ": Device doesn't support picture-in-picture mode.");
7937        }
7938
7939        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7940        if (r == null) {
7941            throw new IllegalStateException(caller
7942                    + ": Can't find activity for token=" + token);
7943        }
7944
7945        if (!r.supportsPictureInPicture()) {
7946            throw new IllegalStateException(caller
7947                    + ": Current activity does not support picture-in-picture.");
7948        }
7949
7950        if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
7951            throw new IllegalStateException(caller
7952                    + ": Activities on the home, assistant, or recents stack not supported");
7953        }
7954
7955        if (params.hasSetAspectRatio()
7956                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
7957                        params.getAspectRatio())) {
7958            final float minAspectRatio = mContext.getResources().getFloat(
7959                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
7960            final float maxAspectRatio = mContext.getResources().getFloat(
7961                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
7962            throw new IllegalArgumentException(String.format(caller
7963                    + ": Aspect ratio is too extreme (must be between %f and %f).",
7964                            minAspectRatio, maxAspectRatio));
7965        }
7966
7967        // Truncate the number of actions if necessary
7968        params.truncateActions(getMaxNumPictureInPictureActions(token));
7969
7970        return r;
7971    }
7972
7973    // =========================================================
7974    // PROCESS INFO
7975    // =========================================================
7976
7977    static class ProcessInfoService extends IProcessInfoService.Stub {
7978        final ActivityManagerService mActivityManagerService;
7979        ProcessInfoService(ActivityManagerService activityManagerService) {
7980            mActivityManagerService = activityManagerService;
7981        }
7982
7983        @Override
7984        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7985            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7986                    /*in*/ pids, /*out*/ states, null);
7987        }
7988
7989        @Override
7990        public void getProcessStatesAndOomScoresFromPids(
7991                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7992            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7993                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7994        }
7995    }
7996
7997    /**
7998     * For each PID in the given input array, write the current process state
7999     * for that process into the states array, or -1 to indicate that no
8000     * process with the given PID exists. If scores array is provided, write
8001     * the oom score for the process into the scores array, with INVALID_ADJ
8002     * indicating the PID doesn't exist.
8003     */
8004    public void getProcessStatesAndOomScoresForPIDs(
8005            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8006        if (scores != null) {
8007            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8008                    "getProcessStatesAndOomScoresForPIDs()");
8009        }
8010
8011        if (pids == null) {
8012            throw new NullPointerException("pids");
8013        } else if (states == null) {
8014            throw new NullPointerException("states");
8015        } else if (pids.length != states.length) {
8016            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8017        } else if (scores != null && pids.length != scores.length) {
8018            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8019        }
8020
8021        synchronized (mPidsSelfLocked) {
8022            for (int i = 0; i < pids.length; i++) {
8023                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8024                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8025                        pr.curProcState;
8026                if (scores != null) {
8027                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8028                }
8029            }
8030        }
8031    }
8032
8033    // =========================================================
8034    // PERMISSIONS
8035    // =========================================================
8036
8037    static class PermissionController extends IPermissionController.Stub {
8038        ActivityManagerService mActivityManagerService;
8039        PermissionController(ActivityManagerService activityManagerService) {
8040            mActivityManagerService = activityManagerService;
8041        }
8042
8043        @Override
8044        public boolean checkPermission(String permission, int pid, int uid) {
8045            return mActivityManagerService.checkPermission(permission, pid,
8046                    uid) == PackageManager.PERMISSION_GRANTED;
8047        }
8048
8049        @Override
8050        public String[] getPackagesForUid(int uid) {
8051            return mActivityManagerService.mContext.getPackageManager()
8052                    .getPackagesForUid(uid);
8053        }
8054
8055        @Override
8056        public boolean isRuntimePermission(String permission) {
8057            try {
8058                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8059                        .getPermissionInfo(permission, 0);
8060                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8061                        == PermissionInfo.PROTECTION_DANGEROUS;
8062            } catch (NameNotFoundException nnfe) {
8063                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8064            }
8065            return false;
8066        }
8067    }
8068
8069    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8070        @Override
8071        public int checkComponentPermission(String permission, int pid, int uid,
8072                int owningUid, boolean exported) {
8073            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8074                    owningUid, exported);
8075        }
8076
8077        @Override
8078        public Object getAMSLock() {
8079            return ActivityManagerService.this;
8080        }
8081    }
8082
8083    /**
8084     * This can be called with or without the global lock held.
8085     */
8086    int checkComponentPermission(String permission, int pid, int uid,
8087            int owningUid, boolean exported) {
8088        if (pid == MY_PID) {
8089            return PackageManager.PERMISSION_GRANTED;
8090        }
8091        return ActivityManager.checkComponentPermission(permission, uid,
8092                owningUid, exported);
8093    }
8094
8095    /**
8096     * As the only public entry point for permissions checking, this method
8097     * can enforce the semantic that requesting a check on a null global
8098     * permission is automatically denied.  (Internally a null permission
8099     * string is used when calling {@link #checkComponentPermission} in cases
8100     * when only uid-based security is needed.)
8101     *
8102     * This can be called with or without the global lock held.
8103     */
8104    @Override
8105    public int checkPermission(String permission, int pid, int uid) {
8106        if (permission == null) {
8107            return PackageManager.PERMISSION_DENIED;
8108        }
8109        return checkComponentPermission(permission, pid, uid, -1, true);
8110    }
8111
8112    @Override
8113    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8114        if (permission == null) {
8115            return PackageManager.PERMISSION_DENIED;
8116        }
8117
8118        // We might be performing an operation on behalf of an indirect binder
8119        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8120        // client identity accordingly before proceeding.
8121        Identity tlsIdentity = sCallerIdentity.get();
8122        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8123            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8124                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8125            uid = tlsIdentity.uid;
8126            pid = tlsIdentity.pid;
8127        }
8128
8129        return checkComponentPermission(permission, pid, uid, -1, true);
8130    }
8131
8132    /**
8133     * Binder IPC calls go through the public entry point.
8134     * This can be called with or without the global lock held.
8135     */
8136    int checkCallingPermission(String permission) {
8137        return checkPermission(permission,
8138                Binder.getCallingPid(),
8139                UserHandle.getAppId(Binder.getCallingUid()));
8140    }
8141
8142    /**
8143     * This can be called with or without the global lock held.
8144     */
8145    void enforceCallingPermission(String permission, String func) {
8146        if (checkCallingPermission(permission)
8147                == PackageManager.PERMISSION_GRANTED) {
8148            return;
8149        }
8150
8151        String msg = "Permission Denial: " + func + " from pid="
8152                + Binder.getCallingPid()
8153                + ", uid=" + Binder.getCallingUid()
8154                + " requires " + permission;
8155        Slog.w(TAG, msg);
8156        throw new SecurityException(msg);
8157    }
8158
8159    /**
8160     * Determine if UID is holding permissions required to access {@link Uri} in
8161     * the given {@link ProviderInfo}. Final permission checking is always done
8162     * in {@link ContentProvider}.
8163     */
8164    private final boolean checkHoldingPermissionsLocked(
8165            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8166        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8167                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8168        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8169            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8170                    != PERMISSION_GRANTED) {
8171                return false;
8172            }
8173        }
8174        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8175    }
8176
8177    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8178            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8179        if (pi.applicationInfo.uid == uid) {
8180            return true;
8181        } else if (!pi.exported) {
8182            return false;
8183        }
8184
8185        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8186        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8187        try {
8188            // check if target holds top-level <provider> permissions
8189            if (!readMet && pi.readPermission != null && considerUidPermissions
8190                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8191                readMet = true;
8192            }
8193            if (!writeMet && pi.writePermission != null && considerUidPermissions
8194                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8195                writeMet = true;
8196            }
8197
8198            // track if unprotected read/write is allowed; any denied
8199            // <path-permission> below removes this ability
8200            boolean allowDefaultRead = pi.readPermission == null;
8201            boolean allowDefaultWrite = pi.writePermission == null;
8202
8203            // check if target holds any <path-permission> that match uri
8204            final PathPermission[] pps = pi.pathPermissions;
8205            if (pps != null) {
8206                final String path = grantUri.uri.getPath();
8207                int i = pps.length;
8208                while (i > 0 && (!readMet || !writeMet)) {
8209                    i--;
8210                    PathPermission pp = pps[i];
8211                    if (pp.match(path)) {
8212                        if (!readMet) {
8213                            final String pprperm = pp.getReadPermission();
8214                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8215                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8216                                    + ": match=" + pp.match(path)
8217                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8218                            if (pprperm != null) {
8219                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8220                                        == PERMISSION_GRANTED) {
8221                                    readMet = true;
8222                                } else {
8223                                    allowDefaultRead = false;
8224                                }
8225                            }
8226                        }
8227                        if (!writeMet) {
8228                            final String ppwperm = pp.getWritePermission();
8229                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8230                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8231                                    + ": match=" + pp.match(path)
8232                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8233                            if (ppwperm != null) {
8234                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8235                                        == PERMISSION_GRANTED) {
8236                                    writeMet = true;
8237                                } else {
8238                                    allowDefaultWrite = false;
8239                                }
8240                            }
8241                        }
8242                    }
8243                }
8244            }
8245
8246            // grant unprotected <provider> read/write, if not blocked by
8247            // <path-permission> above
8248            if (allowDefaultRead) readMet = true;
8249            if (allowDefaultWrite) writeMet = true;
8250
8251        } catch (RemoteException e) {
8252            return false;
8253        }
8254
8255        return readMet && writeMet;
8256    }
8257
8258    public boolean isAppStartModeDisabled(int uid, String packageName) {
8259        synchronized (this) {
8260            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8261                    == ActivityManager.APP_START_MODE_DISABLED;
8262        }
8263    }
8264
8265    // Unified app-op and target sdk check
8266    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8267        // Apps that target O+ are always subject to background check
8268        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8269            if (DEBUG_BACKGROUND_CHECK) {
8270                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8271            }
8272            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8273        }
8274        // ...and legacy apps get an AppOp check
8275        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8276                uid, packageName);
8277        if (DEBUG_BACKGROUND_CHECK) {
8278            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8279        }
8280        switch (appop) {
8281            case AppOpsManager.MODE_ALLOWED:
8282                return ActivityManager.APP_START_MODE_NORMAL;
8283            case AppOpsManager.MODE_IGNORED:
8284                return ActivityManager.APP_START_MODE_DELAYED;
8285            default:
8286                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8287        }
8288    }
8289
8290    // Service launch is available to apps with run-in-background exemptions but
8291    // some other background operations are not.  If we're doing a check
8292    // of service-launch policy, allow those callers to proceed unrestricted.
8293    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8294        // Persistent app?
8295        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8296            if (DEBUG_BACKGROUND_CHECK) {
8297                Slog.i(TAG, "App " + uid + "/" + packageName
8298                        + " is persistent; not restricted in background");
8299            }
8300            return ActivityManager.APP_START_MODE_NORMAL;
8301        }
8302
8303        // Non-persistent but background whitelisted?
8304        if (uidOnBackgroundWhitelist(uid)) {
8305            if (DEBUG_BACKGROUND_CHECK) {
8306                Slog.i(TAG, "App " + uid + "/" + packageName
8307                        + " on background whitelist; not restricted in background");
8308            }
8309            return ActivityManager.APP_START_MODE_NORMAL;
8310        }
8311
8312        // Is this app on the battery whitelist?
8313        if (isOnDeviceIdleWhitelistLocked(uid)) {
8314            if (DEBUG_BACKGROUND_CHECK) {
8315                Slog.i(TAG, "App " + uid + "/" + packageName
8316                        + " on idle whitelist; not restricted in background");
8317            }
8318            return ActivityManager.APP_START_MODE_NORMAL;
8319        }
8320
8321        // None of the service-policy criteria apply, so we apply the common criteria
8322        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8323    }
8324
8325    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8326            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8327        UidRecord uidRec = mActiveUids.get(uid);
8328        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8329                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8330                + (uidRec != null ? uidRec.idle : false));
8331        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8332            boolean ephemeral;
8333            if (uidRec == null) {
8334                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8335                        UserHandle.getUserId(uid), packageName);
8336            } else {
8337                ephemeral = uidRec.ephemeral;
8338            }
8339
8340            if (ephemeral) {
8341                // We are hard-core about ephemeral apps not running in the background.
8342                return ActivityManager.APP_START_MODE_DISABLED;
8343            } else {
8344                if (disabledOnly) {
8345                    // The caller is only interested in whether app starts are completely
8346                    // disabled for the given package (that is, it is an instant app).  So
8347                    // we don't need to go further, which is all just seeing if we should
8348                    // apply a "delayed" mode for a regular app.
8349                    return ActivityManager.APP_START_MODE_NORMAL;
8350                }
8351                final int startMode = (alwaysRestrict)
8352                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8353                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8354                                packageTargetSdk);
8355                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8356                        + " pkg=" + packageName + " startMode=" + startMode
8357                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8358                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8359                    // This is an old app that has been forced into a "compatible as possible"
8360                    // mode of background check.  To increase compatibility, we will allow other
8361                    // foreground apps to cause its services to start.
8362                    if (callingPid >= 0) {
8363                        ProcessRecord proc;
8364                        synchronized (mPidsSelfLocked) {
8365                            proc = mPidsSelfLocked.get(callingPid);
8366                        }
8367                        if (proc != null && proc.curProcState
8368                                < ActivityManager.PROCESS_STATE_RECEIVER) {
8369                            // Whoever is instigating this is in the foreground, so we will allow it
8370                            // to go through.
8371                            return ActivityManager.APP_START_MODE_NORMAL;
8372                        }
8373                    }
8374                }
8375                return startMode;
8376            }
8377        }
8378        return ActivityManager.APP_START_MODE_NORMAL;
8379    }
8380
8381    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8382        final int appId = UserHandle.getAppId(uid);
8383        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8384                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8385                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8386    }
8387
8388    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8389        ProviderInfo pi = null;
8390        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8391        if (cpr != null) {
8392            pi = cpr.info;
8393        } else {
8394            try {
8395                pi = AppGlobals.getPackageManager().resolveContentProvider(
8396                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8397                        userHandle);
8398            } catch (RemoteException ex) {
8399            }
8400        }
8401        return pi;
8402    }
8403
8404    void grantEphemeralAccessLocked(int userId, Intent intent,
8405            int targetAppId, int ephemeralAppId) {
8406        getPackageManagerInternalLocked().
8407                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8408    }
8409
8410    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8411        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8412        if (targetUris != null) {
8413            return targetUris.get(grantUri);
8414        }
8415        return null;
8416    }
8417
8418    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8419            String targetPkg, int targetUid, GrantUri grantUri) {
8420        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8421        if (targetUris == null) {
8422            targetUris = Maps.newArrayMap();
8423            mGrantedUriPermissions.put(targetUid, targetUris);
8424        }
8425
8426        UriPermission perm = targetUris.get(grantUri);
8427        if (perm == null) {
8428            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8429            targetUris.put(grantUri, perm);
8430        }
8431
8432        return perm;
8433    }
8434
8435    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8436            final int modeFlags) {
8437        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8438        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8439                : UriPermission.STRENGTH_OWNED;
8440
8441        // Root gets to do everything.
8442        if (uid == 0) {
8443            return true;
8444        }
8445
8446        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8447        if (perms == null) return false;
8448
8449        // First look for exact match
8450        final UriPermission exactPerm = perms.get(grantUri);
8451        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8452            return true;
8453        }
8454
8455        // No exact match, look for prefixes
8456        final int N = perms.size();
8457        for (int i = 0; i < N; i++) {
8458            final UriPermission perm = perms.valueAt(i);
8459            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8460                    && perm.getStrength(modeFlags) >= minStrength) {
8461                return true;
8462            }
8463        }
8464
8465        return false;
8466    }
8467
8468    /**
8469     * @param uri This uri must NOT contain an embedded userId.
8470     * @param userId The userId in which the uri is to be resolved.
8471     */
8472    @Override
8473    public int checkUriPermission(Uri uri, int pid, int uid,
8474            final int modeFlags, int userId, IBinder callerToken) {
8475        enforceNotIsolatedCaller("checkUriPermission");
8476
8477        // Another redirected-binder-call permissions check as in
8478        // {@link checkPermissionWithToken}.
8479        Identity tlsIdentity = sCallerIdentity.get();
8480        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8481            uid = tlsIdentity.uid;
8482            pid = tlsIdentity.pid;
8483        }
8484
8485        // Our own process gets to do everything.
8486        if (pid == MY_PID) {
8487            return PackageManager.PERMISSION_GRANTED;
8488        }
8489        synchronized (this) {
8490            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8491                    ? PackageManager.PERMISSION_GRANTED
8492                    : PackageManager.PERMISSION_DENIED;
8493        }
8494    }
8495
8496    /**
8497     * Check if the targetPkg can be granted permission to access uri by
8498     * the callingUid using the given modeFlags.  Throws a security exception
8499     * if callingUid is not allowed to do this.  Returns the uid of the target
8500     * if the URI permission grant should be performed; returns -1 if it is not
8501     * needed (for example targetPkg already has permission to access the URI).
8502     * If you already know the uid of the target, you can supply it in
8503     * lastTargetUid else set that to -1.
8504     */
8505    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8506            final int modeFlags, int lastTargetUid) {
8507        if (!Intent.isAccessUriMode(modeFlags)) {
8508            return -1;
8509        }
8510
8511        if (targetPkg != null) {
8512            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8513                    "Checking grant " + targetPkg + " permission to " + grantUri);
8514        }
8515
8516        final IPackageManager pm = AppGlobals.getPackageManager();
8517
8518        // If this is not a content: uri, we can't do anything with it.
8519        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8520            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8521                    "Can't grant URI permission for non-content URI: " + grantUri);
8522            return -1;
8523        }
8524
8525        final String authority = grantUri.uri.getAuthority();
8526        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8527                MATCH_DEBUG_TRIAGED_MISSING);
8528        if (pi == null) {
8529            Slog.w(TAG, "No content provider found for permission check: " +
8530                    grantUri.uri.toSafeString());
8531            return -1;
8532        }
8533
8534        int targetUid = lastTargetUid;
8535        if (targetUid < 0 && targetPkg != null) {
8536            try {
8537                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8538                        UserHandle.getUserId(callingUid));
8539                if (targetUid < 0) {
8540                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8541                            "Can't grant URI permission no uid for: " + targetPkg);
8542                    return -1;
8543                }
8544            } catch (RemoteException ex) {
8545                return -1;
8546            }
8547        }
8548
8549        // If we're extending a persistable grant, then we always need to create
8550        // the grant data structure so that take/release APIs work
8551        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8552            return targetUid;
8553        }
8554
8555        if (targetUid >= 0) {
8556            // First...  does the target actually need this permission?
8557            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8558                // No need to grant the target this permission.
8559                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8560                        "Target " + targetPkg + " already has full permission to " + grantUri);
8561                return -1;
8562            }
8563        } else {
8564            // First...  there is no target package, so can anyone access it?
8565            boolean allowed = pi.exported;
8566            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8567                if (pi.readPermission != null) {
8568                    allowed = false;
8569                }
8570            }
8571            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8572                if (pi.writePermission != null) {
8573                    allowed = false;
8574                }
8575            }
8576            if (allowed) {
8577                return -1;
8578            }
8579        }
8580
8581        /* There is a special cross user grant if:
8582         * - The target is on another user.
8583         * - Apps on the current user can access the uri without any uid permissions.
8584         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8585         * grant uri permissions.
8586         */
8587        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8588                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8589                modeFlags, false /*without considering the uid permissions*/);
8590
8591        // Second...  is the provider allowing granting of URI permissions?
8592        if (!specialCrossUserGrant) {
8593            if (!pi.grantUriPermissions) {
8594                throw new SecurityException("Provider " + pi.packageName
8595                        + "/" + pi.name
8596                        + " does not allow granting of Uri permissions (uri "
8597                        + grantUri + ")");
8598            }
8599            if (pi.uriPermissionPatterns != null) {
8600                final int N = pi.uriPermissionPatterns.length;
8601                boolean allowed = false;
8602                for (int i=0; i<N; i++) {
8603                    if (pi.uriPermissionPatterns[i] != null
8604                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8605                        allowed = true;
8606                        break;
8607                    }
8608                }
8609                if (!allowed) {
8610                    throw new SecurityException("Provider " + pi.packageName
8611                            + "/" + pi.name
8612                            + " does not allow granting of permission to path of Uri "
8613                            + grantUri);
8614                }
8615            }
8616        }
8617
8618        // Third...  does the caller itself have permission to access
8619        // this uri?
8620        final int callingAppId = UserHandle.getAppId(callingUid);
8621        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8622            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8623                // Exempted authority for cropping user photos in Settings app
8624            } else {
8625                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8626                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8627                return -1;
8628            }
8629        }
8630        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8631            // Require they hold a strong enough Uri permission
8632            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8633                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8634                    throw new SecurityException(
8635                            "UID " + callingUid + " does not have permission to " + grantUri
8636                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8637                                    + "or related APIs");
8638                } else {
8639                    throw new SecurityException(
8640                            "UID " + callingUid + " does not have permission to " + grantUri);
8641                }
8642            }
8643        }
8644        return targetUid;
8645    }
8646
8647    /**
8648     * @param uri This uri must NOT contain an embedded userId.
8649     * @param userId The userId in which the uri is to be resolved.
8650     */
8651    @Override
8652    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8653            final int modeFlags, int userId) {
8654        enforceNotIsolatedCaller("checkGrantUriPermission");
8655        synchronized(this) {
8656            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8657                    new GrantUri(userId, uri, false), modeFlags, -1);
8658        }
8659    }
8660
8661    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8662            final int modeFlags, UriPermissionOwner owner) {
8663        if (!Intent.isAccessUriMode(modeFlags)) {
8664            return;
8665        }
8666
8667        // So here we are: the caller has the assumed permission
8668        // to the uri, and the target doesn't.  Let's now give this to
8669        // the target.
8670
8671        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8672                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8673
8674        final String authority = grantUri.uri.getAuthority();
8675        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8676                MATCH_DEBUG_TRIAGED_MISSING);
8677        if (pi == null) {
8678            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8679            return;
8680        }
8681
8682        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8683            grantUri.prefix = true;
8684        }
8685        final UriPermission perm = findOrCreateUriPermissionLocked(
8686                pi.packageName, targetPkg, targetUid, grantUri);
8687        perm.grantModes(modeFlags, owner);
8688    }
8689
8690    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8691            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8692        if (targetPkg == null) {
8693            throw new NullPointerException("targetPkg");
8694        }
8695        int targetUid;
8696        final IPackageManager pm = AppGlobals.getPackageManager();
8697        try {
8698            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8699        } catch (RemoteException ex) {
8700            return;
8701        }
8702
8703        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8704                targetUid);
8705        if (targetUid < 0) {
8706            return;
8707        }
8708
8709        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8710                owner);
8711    }
8712
8713    static class NeededUriGrants extends ArrayList<GrantUri> {
8714        final String targetPkg;
8715        final int targetUid;
8716        final int flags;
8717
8718        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8719            this.targetPkg = targetPkg;
8720            this.targetUid = targetUid;
8721            this.flags = flags;
8722        }
8723    }
8724
8725    /**
8726     * Like checkGrantUriPermissionLocked, but takes an Intent.
8727     */
8728    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8729            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8730        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8731                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8732                + " clip=" + (intent != null ? intent.getClipData() : null)
8733                + " from " + intent + "; flags=0x"
8734                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8735
8736        if (targetPkg == null) {
8737            throw new NullPointerException("targetPkg");
8738        }
8739
8740        if (intent == null) {
8741            return null;
8742        }
8743        Uri data = intent.getData();
8744        ClipData clip = intent.getClipData();
8745        if (data == null && clip == null) {
8746            return null;
8747        }
8748        // Default userId for uris in the intent (if they don't specify it themselves)
8749        int contentUserHint = intent.getContentUserHint();
8750        if (contentUserHint == UserHandle.USER_CURRENT) {
8751            contentUserHint = UserHandle.getUserId(callingUid);
8752        }
8753        final IPackageManager pm = AppGlobals.getPackageManager();
8754        int targetUid;
8755        if (needed != null) {
8756            targetUid = needed.targetUid;
8757        } else {
8758            try {
8759                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8760                        targetUserId);
8761            } catch (RemoteException ex) {
8762                return null;
8763            }
8764            if (targetUid < 0) {
8765                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8766                        "Can't grant URI permission no uid for: " + targetPkg
8767                        + " on user " + targetUserId);
8768                return null;
8769            }
8770        }
8771        if (data != null) {
8772            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8773            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8774                    targetUid);
8775            if (targetUid > 0) {
8776                if (needed == null) {
8777                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8778                }
8779                needed.add(grantUri);
8780            }
8781        }
8782        if (clip != null) {
8783            for (int i=0; i<clip.getItemCount(); i++) {
8784                Uri uri = clip.getItemAt(i).getUri();
8785                if (uri != null) {
8786                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8787                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8788                            targetUid);
8789                    if (targetUid > 0) {
8790                        if (needed == null) {
8791                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8792                        }
8793                        needed.add(grantUri);
8794                    }
8795                } else {
8796                    Intent clipIntent = clip.getItemAt(i).getIntent();
8797                    if (clipIntent != null) {
8798                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8799                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8800                        if (newNeeded != null) {
8801                            needed = newNeeded;
8802                        }
8803                    }
8804                }
8805            }
8806        }
8807
8808        return needed;
8809    }
8810
8811    /**
8812     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8813     */
8814    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8815            UriPermissionOwner owner) {
8816        if (needed != null) {
8817            for (int i=0; i<needed.size(); i++) {
8818                GrantUri grantUri = needed.get(i);
8819                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8820                        grantUri, needed.flags, owner);
8821            }
8822        }
8823    }
8824
8825    void grantUriPermissionFromIntentLocked(int callingUid,
8826            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8827        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8828                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8829        if (needed == null) {
8830            return;
8831        }
8832
8833        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8834    }
8835
8836    /**
8837     * @param uri This uri must NOT contain an embedded userId.
8838     * @param userId The userId in which the uri is to be resolved.
8839     */
8840    @Override
8841    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8842            final int modeFlags, int userId) {
8843        enforceNotIsolatedCaller("grantUriPermission");
8844        GrantUri grantUri = new GrantUri(userId, uri, false);
8845        synchronized(this) {
8846            final ProcessRecord r = getRecordForAppLocked(caller);
8847            if (r == null) {
8848                throw new SecurityException("Unable to find app for caller "
8849                        + caller
8850                        + " when granting permission to uri " + grantUri);
8851            }
8852            if (targetPkg == null) {
8853                throw new IllegalArgumentException("null target");
8854            }
8855            if (grantUri == null) {
8856                throw new IllegalArgumentException("null uri");
8857            }
8858
8859            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8860                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8861                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8862                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8863
8864            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8865                    UserHandle.getUserId(r.uid));
8866        }
8867    }
8868
8869    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8870        if (perm.modeFlags == 0) {
8871            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8872                    perm.targetUid);
8873            if (perms != null) {
8874                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8875                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8876
8877                perms.remove(perm.uri);
8878                if (perms.isEmpty()) {
8879                    mGrantedUriPermissions.remove(perm.targetUid);
8880                }
8881            }
8882        }
8883    }
8884
8885    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
8886            final int modeFlags) {
8887        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8888                "Revoking all granted permissions to " + grantUri);
8889
8890        final IPackageManager pm = AppGlobals.getPackageManager();
8891        final String authority = grantUri.uri.getAuthority();
8892        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8893                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8894        if (pi == null) {
8895            Slog.w(TAG, "No content provider found for permission revoke: "
8896                    + grantUri.toSafeString());
8897            return;
8898        }
8899
8900        // Does the caller have this permission on the URI?
8901        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8902            // If they don't have direct access to the URI, then revoke any
8903            // ownerless URI permissions that have been granted to them.
8904            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8905            if (perms != null) {
8906                boolean persistChanged = false;
8907                for (int i = perms.size()-1; i >= 0; i--) {
8908                    final UriPermission perm = perms.valueAt(i);
8909                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
8910                        continue;
8911                    }
8912                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8913                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8914                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8915                                "Revoking non-owned " + perm.targetUid
8916                                + " permission to " + perm.uri);
8917                        persistChanged |= perm.revokeModes(
8918                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8919                        if (perm.modeFlags == 0) {
8920                            perms.removeAt(i);
8921                        }
8922                    }
8923                }
8924                if (perms.isEmpty()) {
8925                    mGrantedUriPermissions.remove(callingUid);
8926                }
8927                if (persistChanged) {
8928                    schedulePersistUriGrants();
8929                }
8930            }
8931            return;
8932        }
8933
8934        boolean persistChanged = false;
8935
8936        // Go through all of the permissions and remove any that match.
8937        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
8938            final int targetUid = mGrantedUriPermissions.keyAt(i);
8939            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8940
8941            for (int j = perms.size()-1; j >= 0; j--) {
8942                final UriPermission perm = perms.valueAt(j);
8943                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
8944                    continue;
8945                }
8946                if (perm.uri.sourceUserId == grantUri.sourceUserId
8947                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8948                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8949                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8950                    persistChanged |= perm.revokeModes(
8951                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
8952                            targetPackage == null);
8953                    if (perm.modeFlags == 0) {
8954                        perms.removeAt(j);
8955                    }
8956                }
8957            }
8958
8959            if (perms.isEmpty()) {
8960                mGrantedUriPermissions.removeAt(i);
8961            }
8962        }
8963
8964        if (persistChanged) {
8965            schedulePersistUriGrants();
8966        }
8967    }
8968
8969    /**
8970     * @param uri This uri must NOT contain an embedded userId.
8971     * @param userId The userId in which the uri is to be resolved.
8972     */
8973    @Override
8974    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
8975            final int modeFlags, int userId) {
8976        enforceNotIsolatedCaller("revokeUriPermission");
8977        synchronized(this) {
8978            final ProcessRecord r = getRecordForAppLocked(caller);
8979            if (r == null) {
8980                throw new SecurityException("Unable to find app for caller "
8981                        + caller
8982                        + " when revoking permission to uri " + uri);
8983            }
8984            if (uri == null) {
8985                Slog.w(TAG, "revokeUriPermission: null uri");
8986                return;
8987            }
8988
8989            if (!Intent.isAccessUriMode(modeFlags)) {
8990                return;
8991            }
8992
8993            final String authority = uri.getAuthority();
8994            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8995                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8996            if (pi == null) {
8997                Slog.w(TAG, "No content provider found for permission revoke: "
8998                        + uri.toSafeString());
8999                return;
9000            }
9001
9002            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9003                    modeFlags);
9004        }
9005    }
9006
9007    /**
9008     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9009     * given package.
9010     *
9011     * @param packageName Package name to match, or {@code null} to apply to all
9012     *            packages.
9013     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9014     *            to all users.
9015     * @param persistable If persistable grants should be removed.
9016     */
9017    private void removeUriPermissionsForPackageLocked(
9018            String packageName, int userHandle, boolean persistable) {
9019        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9020            throw new IllegalArgumentException("Must narrow by either package or user");
9021        }
9022
9023        boolean persistChanged = false;
9024
9025        int N = mGrantedUriPermissions.size();
9026        for (int i = 0; i < N; i++) {
9027            final int targetUid = mGrantedUriPermissions.keyAt(i);
9028            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9029
9030            // Only inspect grants matching user
9031            if (userHandle == UserHandle.USER_ALL
9032                    || userHandle == UserHandle.getUserId(targetUid)) {
9033                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9034                    final UriPermission perm = it.next();
9035
9036                    // Only inspect grants matching package
9037                    if (packageName == null || perm.sourcePkg.equals(packageName)
9038                            || perm.targetPkg.equals(packageName)) {
9039                        // Hacky solution as part of fixing a security bug; ignore
9040                        // grants associated with DownloadManager so we don't have
9041                        // to immediately launch it to regrant the permissions
9042                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9043                                && !persistable) continue;
9044
9045                        persistChanged |= perm.revokeModes(persistable
9046                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9047
9048                        // Only remove when no modes remain; any persisted grants
9049                        // will keep this alive.
9050                        if (perm.modeFlags == 0) {
9051                            it.remove();
9052                        }
9053                    }
9054                }
9055
9056                if (perms.isEmpty()) {
9057                    mGrantedUriPermissions.remove(targetUid);
9058                    N--;
9059                    i--;
9060                }
9061            }
9062        }
9063
9064        if (persistChanged) {
9065            schedulePersistUriGrants();
9066        }
9067    }
9068
9069    @Override
9070    public IBinder newUriPermissionOwner(String name) {
9071        enforceNotIsolatedCaller("newUriPermissionOwner");
9072        synchronized(this) {
9073            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9074            return owner.getExternalTokenLocked();
9075        }
9076    }
9077
9078    @Override
9079    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9080        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9081        synchronized(this) {
9082            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9083            if (r == null) {
9084                throw new IllegalArgumentException("Activity does not exist; token="
9085                        + activityToken);
9086            }
9087            return r.getUriPermissionsLocked().getExternalTokenLocked();
9088        }
9089    }
9090    /**
9091     * @param uri This uri must NOT contain an embedded userId.
9092     * @param sourceUserId The userId in which the uri is to be resolved.
9093     * @param targetUserId The userId of the app that receives the grant.
9094     */
9095    @Override
9096    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9097            final int modeFlags, int sourceUserId, int targetUserId) {
9098        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9099                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9100                "grantUriPermissionFromOwner", null);
9101        synchronized(this) {
9102            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9103            if (owner == null) {
9104                throw new IllegalArgumentException("Unknown owner: " + token);
9105            }
9106            if (fromUid != Binder.getCallingUid()) {
9107                if (Binder.getCallingUid() != myUid()) {
9108                    // Only system code can grant URI permissions on behalf
9109                    // of other users.
9110                    throw new SecurityException("nice try");
9111                }
9112            }
9113            if (targetPkg == null) {
9114                throw new IllegalArgumentException("null target");
9115            }
9116            if (uri == null) {
9117                throw new IllegalArgumentException("null uri");
9118            }
9119
9120            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9121                    modeFlags, owner, targetUserId);
9122        }
9123    }
9124
9125    /**
9126     * @param uri This uri must NOT contain an embedded userId.
9127     * @param userId The userId in which the uri is to be resolved.
9128     */
9129    @Override
9130    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9131        synchronized(this) {
9132            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9133            if (owner == null) {
9134                throw new IllegalArgumentException("Unknown owner: " + token);
9135            }
9136
9137            if (uri == null) {
9138                owner.removeUriPermissionsLocked(mode);
9139            } else {
9140                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9141                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9142            }
9143        }
9144    }
9145
9146    private void schedulePersistUriGrants() {
9147        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9148            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9149                    10 * DateUtils.SECOND_IN_MILLIS);
9150        }
9151    }
9152
9153    private void writeGrantedUriPermissions() {
9154        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9155
9156        // Snapshot permissions so we can persist without lock
9157        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9158        synchronized (this) {
9159            final int size = mGrantedUriPermissions.size();
9160            for (int i = 0; i < size; i++) {
9161                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9162                for (UriPermission perm : perms.values()) {
9163                    if (perm.persistedModeFlags != 0) {
9164                        persist.add(perm.snapshot());
9165                    }
9166                }
9167            }
9168        }
9169
9170        FileOutputStream fos = null;
9171        try {
9172            fos = mGrantFile.startWrite();
9173
9174            XmlSerializer out = new FastXmlSerializer();
9175            out.setOutput(fos, StandardCharsets.UTF_8.name());
9176            out.startDocument(null, true);
9177            out.startTag(null, TAG_URI_GRANTS);
9178            for (UriPermission.Snapshot perm : persist) {
9179                out.startTag(null, TAG_URI_GRANT);
9180                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9181                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9182                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9183                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9184                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9185                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9186                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9187                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9188                out.endTag(null, TAG_URI_GRANT);
9189            }
9190            out.endTag(null, TAG_URI_GRANTS);
9191            out.endDocument();
9192
9193            mGrantFile.finishWrite(fos);
9194        } catch (IOException e) {
9195            if (fos != null) {
9196                mGrantFile.failWrite(fos);
9197            }
9198        }
9199    }
9200
9201    private void readGrantedUriPermissionsLocked() {
9202        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9203
9204        final long now = System.currentTimeMillis();
9205
9206        FileInputStream fis = null;
9207        try {
9208            fis = mGrantFile.openRead();
9209            final XmlPullParser in = Xml.newPullParser();
9210            in.setInput(fis, StandardCharsets.UTF_8.name());
9211
9212            int type;
9213            while ((type = in.next()) != END_DOCUMENT) {
9214                final String tag = in.getName();
9215                if (type == START_TAG) {
9216                    if (TAG_URI_GRANT.equals(tag)) {
9217                        final int sourceUserId;
9218                        final int targetUserId;
9219                        final int userHandle = readIntAttribute(in,
9220                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9221                        if (userHandle != UserHandle.USER_NULL) {
9222                            // For backwards compatibility.
9223                            sourceUserId = userHandle;
9224                            targetUserId = userHandle;
9225                        } else {
9226                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9227                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9228                        }
9229                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9230                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9231                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9232                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9233                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9234                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9235
9236                        // Sanity check that provider still belongs to source package
9237                        // Both direct boot aware and unaware packages are fine as we
9238                        // will do filtering at query time to avoid multiple parsing.
9239                        final ProviderInfo pi = getProviderInfoLocked(
9240                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9241                                        | MATCH_DIRECT_BOOT_UNAWARE);
9242                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9243                            int targetUid = -1;
9244                            try {
9245                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9246                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9247                            } catch (RemoteException e) {
9248                            }
9249                            if (targetUid != -1) {
9250                                final UriPermission perm = findOrCreateUriPermissionLocked(
9251                                        sourcePkg, targetPkg, targetUid,
9252                                        new GrantUri(sourceUserId, uri, prefix));
9253                                perm.initPersistedModes(modeFlags, createdTime);
9254                            }
9255                        } else {
9256                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9257                                    + " but instead found " + pi);
9258                        }
9259                    }
9260                }
9261            }
9262        } catch (FileNotFoundException e) {
9263            // Missing grants is okay
9264        } catch (IOException e) {
9265            Slog.wtf(TAG, "Failed reading Uri grants", e);
9266        } catch (XmlPullParserException e) {
9267            Slog.wtf(TAG, "Failed reading Uri grants", e);
9268        } finally {
9269            IoUtils.closeQuietly(fis);
9270        }
9271    }
9272
9273    /**
9274     * @param uri This uri must NOT contain an embedded userId.
9275     * @param userId The userId in which the uri is to be resolved.
9276     */
9277    @Override
9278    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9279        enforceNotIsolatedCaller("takePersistableUriPermission");
9280
9281        Preconditions.checkFlagsArgument(modeFlags,
9282                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9283
9284        synchronized (this) {
9285            final int callingUid = Binder.getCallingUid();
9286            boolean persistChanged = false;
9287            GrantUri grantUri = new GrantUri(userId, uri, false);
9288
9289            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9290                    new GrantUri(userId, uri, false));
9291            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9292                    new GrantUri(userId, uri, true));
9293
9294            final boolean exactValid = (exactPerm != null)
9295                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9296            final boolean prefixValid = (prefixPerm != null)
9297                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9298
9299            if (!(exactValid || prefixValid)) {
9300                throw new SecurityException("No persistable permission grants found for UID "
9301                        + callingUid + " and Uri " + grantUri.toSafeString());
9302            }
9303
9304            if (exactValid) {
9305                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9306            }
9307            if (prefixValid) {
9308                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9309            }
9310
9311            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9312
9313            if (persistChanged) {
9314                schedulePersistUriGrants();
9315            }
9316        }
9317    }
9318
9319    /**
9320     * @param uri This uri must NOT contain an embedded userId.
9321     * @param userId The userId in which the uri is to be resolved.
9322     */
9323    @Override
9324    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9325        enforceNotIsolatedCaller("releasePersistableUriPermission");
9326
9327        Preconditions.checkFlagsArgument(modeFlags,
9328                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9329
9330        synchronized (this) {
9331            final int callingUid = Binder.getCallingUid();
9332            boolean persistChanged = false;
9333
9334            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9335                    new GrantUri(userId, uri, false));
9336            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9337                    new GrantUri(userId, uri, true));
9338            if (exactPerm == null && prefixPerm == null) {
9339                throw new SecurityException("No permission grants found for UID " + callingUid
9340                        + " and Uri " + uri.toSafeString());
9341            }
9342
9343            if (exactPerm != null) {
9344                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9345                removeUriPermissionIfNeededLocked(exactPerm);
9346            }
9347            if (prefixPerm != null) {
9348                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9349                removeUriPermissionIfNeededLocked(prefixPerm);
9350            }
9351
9352            if (persistChanged) {
9353                schedulePersistUriGrants();
9354            }
9355        }
9356    }
9357
9358    /**
9359     * Prune any older {@link UriPermission} for the given UID until outstanding
9360     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9361     *
9362     * @return if any mutations occured that require persisting.
9363     */
9364    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9365        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9366        if (perms == null) return false;
9367        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9368
9369        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9370        for (UriPermission perm : perms.values()) {
9371            if (perm.persistedModeFlags != 0) {
9372                persisted.add(perm);
9373            }
9374        }
9375
9376        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9377        if (trimCount <= 0) return false;
9378
9379        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9380        for (int i = 0; i < trimCount; i++) {
9381            final UriPermission perm = persisted.get(i);
9382
9383            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9384                    "Trimming grant created at " + perm.persistedCreateTime);
9385
9386            perm.releasePersistableModes(~0);
9387            removeUriPermissionIfNeededLocked(perm);
9388        }
9389
9390        return true;
9391    }
9392
9393    @Override
9394    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9395            String packageName, boolean incoming) {
9396        enforceNotIsolatedCaller("getPersistedUriPermissions");
9397        Preconditions.checkNotNull(packageName, "packageName");
9398
9399        final int callingUid = Binder.getCallingUid();
9400        final int callingUserId = UserHandle.getUserId(callingUid);
9401        final IPackageManager pm = AppGlobals.getPackageManager();
9402        try {
9403            final int packageUid = pm.getPackageUid(packageName,
9404                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9405            if (packageUid != callingUid) {
9406                throw new SecurityException(
9407                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9408            }
9409        } catch (RemoteException e) {
9410            throw new SecurityException("Failed to verify package name ownership");
9411        }
9412
9413        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9414        synchronized (this) {
9415            if (incoming) {
9416                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9417                        callingUid);
9418                if (perms == null) {
9419                    Slog.w(TAG, "No permission grants found for " + packageName);
9420                } else {
9421                    for (UriPermission perm : perms.values()) {
9422                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9423                            result.add(perm.buildPersistedPublicApiObject());
9424                        }
9425                    }
9426                }
9427            } else {
9428                final int size = mGrantedUriPermissions.size();
9429                for (int i = 0; i < size; i++) {
9430                    final ArrayMap<GrantUri, UriPermission> perms =
9431                            mGrantedUriPermissions.valueAt(i);
9432                    for (UriPermission perm : perms.values()) {
9433                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9434                            result.add(perm.buildPersistedPublicApiObject());
9435                        }
9436                    }
9437                }
9438            }
9439        }
9440        return new ParceledListSlice<android.content.UriPermission>(result);
9441    }
9442
9443    @Override
9444    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9445            String packageName, int userId) {
9446        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9447                "getGrantedUriPermissions");
9448
9449        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9450        synchronized (this) {
9451            final int size = mGrantedUriPermissions.size();
9452            for (int i = 0; i < size; i++) {
9453                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9454                for (UriPermission perm : perms.values()) {
9455                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9456                            && perm.persistedModeFlags != 0) {
9457                        result.add(perm.buildPersistedPublicApiObject());
9458                    }
9459                }
9460            }
9461        }
9462        return new ParceledListSlice<android.content.UriPermission>(result);
9463    }
9464
9465    @Override
9466    public void clearGrantedUriPermissions(String packageName, int userId) {
9467        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9468                "clearGrantedUriPermissions");
9469        removeUriPermissionsForPackageLocked(packageName, userId, true);
9470    }
9471
9472    @Override
9473    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9474        synchronized (this) {
9475            ProcessRecord app =
9476                who != null ? getRecordForAppLocked(who) : null;
9477            if (app == null) return;
9478
9479            Message msg = Message.obtain();
9480            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9481            msg.obj = app;
9482            msg.arg1 = waiting ? 1 : 0;
9483            mUiHandler.sendMessage(msg);
9484        }
9485    }
9486
9487    @Override
9488    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9489        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9490        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9491        outInfo.availMem = getFreeMemory();
9492        outInfo.totalMem = getTotalMemory();
9493        outInfo.threshold = homeAppMem;
9494        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9495        outInfo.hiddenAppThreshold = cachedAppMem;
9496        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9497                ProcessList.SERVICE_ADJ);
9498        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9499                ProcessList.VISIBLE_APP_ADJ);
9500        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9501                ProcessList.FOREGROUND_APP_ADJ);
9502    }
9503
9504    // =========================================================
9505    // TASK MANAGEMENT
9506    // =========================================================
9507
9508    @Override
9509    public List<IBinder> getAppTasks(String callingPackage) {
9510        int callingUid = Binder.getCallingUid();
9511        long ident = Binder.clearCallingIdentity();
9512
9513        synchronized(this) {
9514            ArrayList<IBinder> list = new ArrayList<IBinder>();
9515            try {
9516                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9517
9518                final int N = mRecentTasks.size();
9519                for (int i = 0; i < N; i++) {
9520                    TaskRecord tr = mRecentTasks.get(i);
9521                    // Skip tasks that do not match the caller.  We don't need to verify
9522                    // callingPackage, because we are also limiting to callingUid and know
9523                    // that will limit to the correct security sandbox.
9524                    if (tr.effectiveUid != callingUid) {
9525                        continue;
9526                    }
9527                    Intent intent = tr.getBaseIntent();
9528                    if (intent == null ||
9529                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9530                        continue;
9531                    }
9532                    ActivityManager.RecentTaskInfo taskInfo =
9533                            createRecentTaskInfoFromTaskRecord(tr);
9534                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9535                    list.add(taskImpl.asBinder());
9536                }
9537            } finally {
9538                Binder.restoreCallingIdentity(ident);
9539            }
9540            return list;
9541        }
9542    }
9543
9544    @Override
9545    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9546        final int callingUid = Binder.getCallingUid();
9547        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9548
9549        synchronized(this) {
9550            if (DEBUG_ALL) Slog.v(
9551                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9552
9553            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9554                    callingUid);
9555
9556            // TODO: Improve with MRU list from all ActivityStacks.
9557            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9558        }
9559
9560        return list;
9561    }
9562
9563    /**
9564     * Creates a new RecentTaskInfo from a TaskRecord.
9565     */
9566    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9567        // Update the task description to reflect any changes in the task stack
9568        tr.updateTaskDescription();
9569
9570        // Compose the recent task info
9571        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9572        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9573        rti.persistentId = tr.taskId;
9574        rti.baseIntent = new Intent(tr.getBaseIntent());
9575        rti.origActivity = tr.origActivity;
9576        rti.realActivity = tr.realActivity;
9577        rti.description = tr.lastDescription;
9578        rti.stackId = tr.getStackId();
9579        rti.userId = tr.userId;
9580        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9581        rti.firstActiveTime = tr.firstActiveTime;
9582        rti.lastActiveTime = tr.lastActiveTime;
9583        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9584        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9585        rti.numActivities = 0;
9586        if (tr.mBounds != null) {
9587            rti.bounds = new Rect(tr.mBounds);
9588        }
9589        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9590        rti.resizeMode = tr.mResizeMode;
9591
9592        ActivityRecord base = null;
9593        ActivityRecord top = null;
9594        ActivityRecord tmp;
9595
9596        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9597            tmp = tr.mActivities.get(i);
9598            if (tmp.finishing) {
9599                continue;
9600            }
9601            base = tmp;
9602            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9603                top = base;
9604            }
9605            rti.numActivities++;
9606        }
9607
9608        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9609        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9610
9611        return rti;
9612    }
9613
9614    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9615        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9616                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9617        if (!allowed) {
9618            if (checkPermission(android.Manifest.permission.GET_TASKS,
9619                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9620                // Temporary compatibility: some existing apps on the system image may
9621                // still be requesting the old permission and not switched to the new
9622                // one; if so, we'll still allow them full access.  This means we need
9623                // to see if they are holding the old permission and are a system app.
9624                try {
9625                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9626                        allowed = true;
9627                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9628                                + " is using old GET_TASKS but privileged; allowing");
9629                    }
9630                } catch (RemoteException e) {
9631                }
9632            }
9633        }
9634        if (!allowed) {
9635            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9636                    + " does not hold REAL_GET_TASKS; limiting output");
9637        }
9638        return allowed;
9639    }
9640
9641    @Override
9642    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9643            int userId) {
9644        final int callingUid = Binder.getCallingUid();
9645        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9646                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9647
9648        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9649        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9650        synchronized (this) {
9651            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9652                    callingUid);
9653            final boolean detailed = checkCallingPermission(
9654                    android.Manifest.permission.GET_DETAILED_TASKS)
9655                    == PackageManager.PERMISSION_GRANTED;
9656
9657            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9658                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9659                return ParceledListSlice.emptyList();
9660            }
9661            mRecentTasks.loadUserRecentsLocked(userId);
9662
9663            final int recentsCount = mRecentTasks.size();
9664            ArrayList<ActivityManager.RecentTaskInfo> res =
9665                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9666
9667            final Set<Integer> includedUsers;
9668            if (includeProfiles) {
9669                includedUsers = mUserController.getProfileIds(userId);
9670            } else {
9671                includedUsers = new HashSet<>();
9672            }
9673            includedUsers.add(Integer.valueOf(userId));
9674
9675            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9676                TaskRecord tr = mRecentTasks.get(i);
9677                // Only add calling user or related users recent tasks
9678                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9679                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9680                    continue;
9681                }
9682
9683                if (tr.realActivitySuspended) {
9684                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9685                    continue;
9686                }
9687
9688                // Return the entry if desired by the caller.  We always return
9689                // the first entry, because callers always expect this to be the
9690                // foreground app.  We may filter others if the caller has
9691                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9692                // we should exclude the entry.
9693
9694                if (i == 0
9695                        || withExcluded
9696                        || (tr.intent == null)
9697                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9698                                == 0)) {
9699                    if (!allowed) {
9700                        // If the caller doesn't have the GET_TASKS permission, then only
9701                        // allow them to see a small subset of tasks -- their own and home.
9702                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9703                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9704                            continue;
9705                        }
9706                    }
9707                    final ActivityStack stack = tr.getStack();
9708                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9709                        if (stack != null && stack.isHomeOrRecentsStack()) {
9710                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9711                                    "Skipping, home or recents stack task: " + tr);
9712                            continue;
9713                        }
9714                    }
9715                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9716                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9717                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9718                                    "Skipping, top task in docked stack: " + tr);
9719                            continue;
9720                        }
9721                    }
9722                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9723                        if (stack != null && stack.isPinnedStack()) {
9724                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9725                                    "Skipping, pinned stack task: " + tr);
9726                            continue;
9727                        }
9728                    }
9729                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9730                        // Don't include auto remove tasks that are finished or finishing.
9731                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9732                                "Skipping, auto-remove without activity: " + tr);
9733                        continue;
9734                    }
9735                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9736                            && !tr.isAvailable) {
9737                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9738                                "Skipping, unavail real act: " + tr);
9739                        continue;
9740                    }
9741
9742                    if (!tr.mUserSetupComplete) {
9743                        // Don't include task launched while user is not done setting-up.
9744                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9745                                "Skipping, user setup not complete: " + tr);
9746                        continue;
9747                    }
9748
9749                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9750                    if (!detailed) {
9751                        rti.baseIntent.replaceExtras((Bundle)null);
9752                    }
9753
9754                    res.add(rti);
9755                    maxNum--;
9756                }
9757            }
9758            return new ParceledListSlice<>(res);
9759        }
9760    }
9761
9762    @Override
9763    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9764        synchronized (this) {
9765            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9766                    "getTaskThumbnail()");
9767            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9768                    id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9769            if (tr != null) {
9770                return tr.getTaskThumbnailLocked();
9771            }
9772        }
9773        return null;
9774    }
9775
9776    @Override
9777    public ActivityManager.TaskDescription getTaskDescription(int id) {
9778        synchronized (this) {
9779            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9780                    "getTaskDescription()");
9781            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9782                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9783            if (tr != null) {
9784                return tr.lastTaskDescription;
9785            }
9786        }
9787        return null;
9788    }
9789
9790    @Override
9791    public int addAppTask(IBinder activityToken, Intent intent,
9792            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9793        final int callingUid = Binder.getCallingUid();
9794        final long callingIdent = Binder.clearCallingIdentity();
9795
9796        try {
9797            synchronized (this) {
9798                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9799                if (r == null) {
9800                    throw new IllegalArgumentException("Activity does not exist; token="
9801                            + activityToken);
9802                }
9803                ComponentName comp = intent.getComponent();
9804                if (comp == null) {
9805                    throw new IllegalArgumentException("Intent " + intent
9806                            + " must specify explicit component");
9807                }
9808                if (thumbnail.getWidth() != mThumbnailWidth
9809                        || thumbnail.getHeight() != mThumbnailHeight) {
9810                    throw new IllegalArgumentException("Bad thumbnail size: got "
9811                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9812                            + mThumbnailWidth + "x" + mThumbnailHeight);
9813                }
9814                if (intent.getSelector() != null) {
9815                    intent.setSelector(null);
9816                }
9817                if (intent.getSourceBounds() != null) {
9818                    intent.setSourceBounds(null);
9819                }
9820                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9821                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9822                        // The caller has added this as an auto-remove task...  that makes no
9823                        // sense, so turn off auto-remove.
9824                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9825                    }
9826                }
9827                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9828                    mLastAddedTaskActivity = null;
9829                }
9830                ActivityInfo ainfo = mLastAddedTaskActivity;
9831                if (ainfo == null) {
9832                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9833                            comp, 0, UserHandle.getUserId(callingUid));
9834                    if (ainfo.applicationInfo.uid != callingUid) {
9835                        throw new SecurityException(
9836                                "Can't add task for another application: target uid="
9837                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9838                    }
9839                }
9840
9841                TaskRecord task = new TaskRecord(this,
9842                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9843                        ainfo, intent, description, new TaskThumbnailInfo());
9844
9845                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9846                if (trimIdx >= 0) {
9847                    // If this would have caused a trim, then we'll abort because that
9848                    // means it would be added at the end of the list but then just removed.
9849                    return INVALID_TASK_ID;
9850                }
9851
9852                final int N = mRecentTasks.size();
9853                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9854                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9855                    tr.removedFromRecents();
9856                }
9857
9858                task.inRecents = true;
9859                mRecentTasks.add(task);
9860                r.getStack().addTask(task, false, "addAppTask");
9861
9862                task.setLastThumbnailLocked(thumbnail);
9863                task.freeLastThumbnail();
9864                return task.taskId;
9865            }
9866        } finally {
9867            Binder.restoreCallingIdentity(callingIdent);
9868        }
9869    }
9870
9871    @Override
9872    public Point getAppTaskThumbnailSize() {
9873        synchronized (this) {
9874            return new Point(mThumbnailWidth,  mThumbnailHeight);
9875        }
9876    }
9877
9878    @Override
9879    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9880        synchronized (this) {
9881            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9882            if (r != null) {
9883                r.setTaskDescription(td);
9884                final TaskRecord task = r.getTask();
9885                task.updateTaskDescription();
9886                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
9887            }
9888        }
9889    }
9890
9891    @Override
9892    public void setTaskResizeable(int taskId, int resizeableMode) {
9893        synchronized (this) {
9894            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9895                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9896            if (task == null) {
9897                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9898                return;
9899            }
9900            task.setResizeMode(resizeableMode);
9901        }
9902    }
9903
9904    @Override
9905    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9906        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9907        long ident = Binder.clearCallingIdentity();
9908        try {
9909            synchronized (this) {
9910                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9911                if (task == null) {
9912                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9913                    return;
9914                }
9915                // Place the task in the right stack if it isn't there already based on
9916                // the requested bounds.
9917                // The stack transition logic is:
9918                // - a null bounds on a freeform task moves that task to fullscreen
9919                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9920                //   that task to freeform
9921                // - otherwise the task is not moved
9922                int stackId = task.getStackId();
9923                if (!StackId.isTaskResizeAllowed(stackId)) {
9924                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9925                }
9926                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9927                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9928                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9929                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9930                }
9931
9932                // Reparent the task to the right stack if necessary
9933                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9934                if (stackId != task.getStackId()) {
9935                    // Defer resume until the task is resized below
9936                    task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
9937                            DEFER_RESUME, "resizeTask");
9938                    preserveWindow = false;
9939                }
9940
9941                // After reparenting (which only resizes the task to the stack bounds), resize the
9942                // task to the actual bounds provided
9943                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
9944            }
9945        } finally {
9946            Binder.restoreCallingIdentity(ident);
9947        }
9948    }
9949
9950    @Override
9951    public Rect getTaskBounds(int taskId) {
9952        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9953        long ident = Binder.clearCallingIdentity();
9954        Rect rect = new Rect();
9955        try {
9956            synchronized (this) {
9957                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
9958                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9959                if (task == null) {
9960                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9961                    return rect;
9962                }
9963                if (task.getStack() != null) {
9964                    // Return the bounds from window manager since it will be adjusted for various
9965                    // things like the presense of a docked stack for tasks that aren't resizeable.
9966                    task.getWindowContainerBounds(rect);
9967                } else {
9968                    // Task isn't in window manager yet since it isn't associated with a stack.
9969                    // Return the persist value from activity manager
9970                    if (task.mBounds != null) {
9971                        rect.set(task.mBounds);
9972                    } else if (task.mLastNonFullscreenBounds != null) {
9973                        rect.set(task.mLastNonFullscreenBounds);
9974                    }
9975                }
9976            }
9977        } finally {
9978            Binder.restoreCallingIdentity(ident);
9979        }
9980        return rect;
9981    }
9982
9983    @Override
9984    public void cancelTaskWindowTransition(int taskId) {
9985        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
9986        final long ident = Binder.clearCallingIdentity();
9987        try {
9988            synchronized (this) {
9989                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
9990                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
9991                if (task == null) {
9992                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
9993                    return;
9994                }
9995                task.cancelWindowTransition();
9996            }
9997        } finally {
9998            Binder.restoreCallingIdentity(ident);
9999        }
10000    }
10001
10002    @Override
10003    public void cancelTaskThumbnailTransition(int taskId) {
10004        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10005        final long ident = Binder.clearCallingIdentity();
10006        try {
10007            synchronized (this) {
10008                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10009                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10010                if (task == null) {
10011                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10012                    return;
10013                }
10014                task.cancelThumbnailTransition();
10015            }
10016        } finally {
10017            Binder.restoreCallingIdentity(ident);
10018        }
10019    }
10020
10021    @Override
10022    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10023        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10024        final long ident = Binder.clearCallingIdentity();
10025        try {
10026            final TaskRecord task;
10027            synchronized (this) {
10028                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10029                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10030                if (task == null) {
10031                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10032                    return null;
10033                }
10034            }
10035            // Don't call this while holding the lock as this operation might hit the disk.
10036            return task.getSnapshot(reducedResolution);
10037        } finally {
10038            Binder.restoreCallingIdentity(ident);
10039        }
10040    }
10041
10042    @Override
10043    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10044        if (userId != UserHandle.getCallingUserId()) {
10045            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10046                    "getTaskDescriptionIcon");
10047        }
10048        final File passedIconFile = new File(filePath);
10049        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10050                passedIconFile.getName());
10051        if (!legitIconFile.getPath().equals(filePath)
10052                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10053            throw new IllegalArgumentException("Bad file path: " + filePath
10054                    + " passed for userId " + userId);
10055        }
10056        return mRecentTasks.getTaskDescriptionIcon(filePath);
10057    }
10058
10059    @Override
10060    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10061            throws RemoteException {
10062        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10063        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10064                activityOptions.getCustomInPlaceResId() == 0) {
10065            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10066                    "with valid animation");
10067        }
10068        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10069        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10070                activityOptions.getCustomInPlaceResId());
10071        mWindowManager.executeAppTransition();
10072    }
10073
10074    private void removeTasksByPackageNameLocked(String packageName, int userId) {
10075        // Remove all tasks with activities in the specified package from the list of recent tasks
10076        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10077            TaskRecord tr = mRecentTasks.get(i);
10078            if (tr.userId != userId) continue;
10079
10080            ComponentName cn = tr.intent.getComponent();
10081            if (cn != null && cn.getPackageName().equals(packageName)) {
10082                // If the package name matches, remove the task.
10083                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10084            }
10085        }
10086    }
10087
10088    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10089            int userId) {
10090
10091        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10092            TaskRecord tr = mRecentTasks.get(i);
10093            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10094                continue;
10095            }
10096
10097            ComponentName cn = tr.intent.getComponent();
10098            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10099                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10100            if (sameComponent) {
10101                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10102            }
10103        }
10104    }
10105
10106    @Override
10107    public void removeStack(int stackId) {
10108        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10109        if (StackId.isHomeOrRecentsStack(stackId)) {
10110            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10111        }
10112
10113        synchronized (this) {
10114            final long ident = Binder.clearCallingIdentity();
10115            try {
10116                mStackSupervisor.removeStackLocked(stackId);
10117            } finally {
10118                Binder.restoreCallingIdentity(ident);
10119            }
10120        }
10121    }
10122
10123    @Override
10124    public void moveStackToDisplay(int stackId, int displayId) {
10125        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
10126
10127        synchronized (this) {
10128            final long ident = Binder.clearCallingIdentity();
10129            try {
10130                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10131                        + " to displayId=" + displayId);
10132                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10133            } finally {
10134                Binder.restoreCallingIdentity(ident);
10135            }
10136        }
10137    }
10138
10139    @Override
10140    public boolean removeTask(int taskId) {
10141        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10142        synchronized (this) {
10143            final long ident = Binder.clearCallingIdentity();
10144            try {
10145                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10146            } finally {
10147                Binder.restoreCallingIdentity(ident);
10148            }
10149        }
10150    }
10151
10152    /**
10153     * TODO: Add mController hook
10154     */
10155    @Override
10156    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10157        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10158
10159        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10160        synchronized(this) {
10161            moveTaskToFrontLocked(taskId, flags, bOptions);
10162        }
10163    }
10164
10165    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
10166        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10167
10168        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10169                Binder.getCallingUid(), -1, -1, "Task to front")) {
10170            ActivityOptions.abort(options);
10171            return;
10172        }
10173        final long origId = Binder.clearCallingIdentity();
10174        try {
10175            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10176            if (task == null) {
10177                Slog.d(TAG, "Could not find task for id: "+ taskId);
10178                return;
10179            }
10180            if (mStackSupervisor.isLockTaskModeViolation(task)) {
10181                mStackSupervisor.showLockTaskToast();
10182                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10183                return;
10184            }
10185            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10186            if (prev != null) {
10187                task.setTaskToReturnTo(prev);
10188            }
10189            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10190                    false /* forceNonResizable */);
10191
10192            final ActivityRecord topActivity = task.getTopActivity();
10193            if (topActivity != null) {
10194
10195                // We are reshowing a task, use a starting window to hide the initial draw delay
10196                // so the transition can start earlier.
10197                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10198                        true /* taskSwitch */);
10199            }
10200        } finally {
10201            Binder.restoreCallingIdentity(origId);
10202        }
10203        ActivityOptions.abort(options);
10204    }
10205
10206    /**
10207     * Attempts to move a task backwards in z-order (the order of activities within the task is
10208     * unchanged).
10209     *
10210     * There are several possible results of this call:
10211     * - if the task is locked, then we will show the lock toast
10212     * - if there is a task behind the provided task, then that task is made visible and resumed as
10213     *   this task is moved to the back
10214     * - otherwise, if there are no other tasks in the stack:
10215     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10216     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10217     *       (depending on whether it is visible)
10218     *     - otherwise, we simply return home and hide this task
10219     *
10220     * @param token A reference to the activity we wish to move
10221     * @param nonRoot If false then this only works if the activity is the root
10222     *                of a task; if true it will work for any activity in a task.
10223     * @return Returns true if the move completed, false if not.
10224     */
10225    @Override
10226    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10227        enforceNotIsolatedCaller("moveActivityTaskToBack");
10228        synchronized(this) {
10229            final long origId = Binder.clearCallingIdentity();
10230            try {
10231                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10232                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10233                if (task != null) {
10234                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10235                }
10236            } finally {
10237                Binder.restoreCallingIdentity(origId);
10238            }
10239        }
10240        return false;
10241    }
10242
10243    @Override
10244    public void moveTaskBackwards(int task) {
10245        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10246                "moveTaskBackwards()");
10247
10248        synchronized(this) {
10249            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10250                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10251                return;
10252            }
10253            final long origId = Binder.clearCallingIdentity();
10254            moveTaskBackwardsLocked(task);
10255            Binder.restoreCallingIdentity(origId);
10256        }
10257    }
10258
10259    private final void moveTaskBackwardsLocked(int task) {
10260        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10261    }
10262
10263    @Override
10264    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10265            IActivityContainerCallback callback) throws RemoteException {
10266        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10267        synchronized (this) {
10268            if (parentActivityToken == null) {
10269                throw new IllegalArgumentException("parent token must not be null");
10270            }
10271            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10272            if (r == null) {
10273                return null;
10274            }
10275            if (callback == null) {
10276                throw new IllegalArgumentException("callback must not be null");
10277            }
10278            return mStackSupervisor.createVirtualActivityContainer(r, callback);
10279        }
10280    }
10281
10282    @Override
10283    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10284        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10285        synchronized (this) {
10286            final int stackId = mStackSupervisor.getNextStackId();
10287            final ActivityStack stack =
10288                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10289            if (stack == null) {
10290                return null;
10291            }
10292            return stack.mActivityContainer;
10293        }
10294    }
10295
10296    @Override
10297    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10298        synchronized (this) {
10299            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10300            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10301                return stack.mActivityContainer.getDisplayId();
10302            }
10303            return DEFAULT_DISPLAY;
10304        }
10305    }
10306
10307    @Override
10308    public int getActivityStackId(IBinder token) throws RemoteException {
10309        synchronized (this) {
10310            ActivityStack stack = ActivityRecord.getStackLocked(token);
10311            if (stack == null) {
10312                return INVALID_STACK_ID;
10313            }
10314            return stack.mStackId;
10315        }
10316    }
10317
10318    @Override
10319    public void exitFreeformMode(IBinder token) throws RemoteException {
10320        synchronized (this) {
10321            long ident = Binder.clearCallingIdentity();
10322            try {
10323                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10324                if (r == null) {
10325                    throw new IllegalArgumentException(
10326                            "exitFreeformMode: No activity record matching token=" + token);
10327                }
10328
10329                final ActivityStack stack = r.getStack();
10330                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10331                    throw new IllegalStateException(
10332                            "exitFreeformMode: You can only go fullscreen from freeform.");
10333                }
10334
10335                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10336                r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10337                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10338            } finally {
10339                Binder.restoreCallingIdentity(ident);
10340            }
10341        }
10342    }
10343
10344    @Override
10345    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10346        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10347        if (StackId.isHomeOrRecentsStack(stackId)) {
10348            throw new IllegalArgumentException(
10349                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10350        }
10351        synchronized (this) {
10352            long ident = Binder.clearCallingIdentity();
10353            try {
10354                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10355                if (task == null) {
10356                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10357                    return;
10358                }
10359
10360                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10361                        + " to stackId=" + stackId + " toTop=" + toTop);
10362                if (stackId == DOCKED_STACK_ID) {
10363                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10364                            null /* initialBounds */);
10365                }
10366                task.reparent(stackId, toTop,
10367                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10368            } finally {
10369                Binder.restoreCallingIdentity(ident);
10370            }
10371        }
10372    }
10373
10374    @Override
10375    public void swapDockedAndFullscreenStack() throws RemoteException {
10376        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10377        synchronized (this) {
10378            long ident = Binder.clearCallingIdentity();
10379            try {
10380                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10381                        FULLSCREEN_WORKSPACE_STACK_ID);
10382                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10383                        : null;
10384                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10385                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10386                        : null;
10387                if (topTask == null || tasks == null || tasks.size() == 0) {
10388                    Slog.w(TAG,
10389                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10390                    return;
10391                }
10392
10393                // TODO: App transition
10394                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10395
10396                // Defer the resume until we move all the docked tasks to the fullscreen stack below
10397                topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10398                        DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10399                final int size = tasks.size();
10400                for (int i = 0; i < size; i++) {
10401                    final int id = tasks.get(i).taskId;
10402                    if (id == topTask.taskId) {
10403                        continue;
10404                    }
10405
10406                    // Defer the resume until after all the tasks have been moved
10407                    tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10408                            REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10409                            "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10410                }
10411
10412                // Because we deferred the resume to avoid conflicts with stack switches while
10413                // resuming, we need to do it after all the tasks are moved.
10414                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10415                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10416
10417                mWindowManager.executeAppTransition();
10418            } finally {
10419                Binder.restoreCallingIdentity(ident);
10420            }
10421        }
10422    }
10423
10424    /**
10425     * Moves the input task to the docked stack.
10426     *
10427     * @param taskId Id of task to move.
10428     * @param createMode The mode the docked stack should be created in if it doesn't exist
10429     *                   already. See
10430     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10431     *                   and
10432     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10433     * @param toTop If the task and stack should be moved to the top.
10434     * @param animate Whether we should play an animation for the moving the task
10435     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10436     *                      docked stack. Pass {@code null} to use default bounds.
10437     */
10438    @Override
10439    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10440            Rect initialBounds) {
10441        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10442        synchronized (this) {
10443            long ident = Binder.clearCallingIdentity();
10444            try {
10445                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10446                if (task == null) {
10447                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10448                    return false;
10449                }
10450
10451                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10452                        + " to createMode=" + createMode + " toTop=" + toTop);
10453                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10454
10455                // Defer resuming until we move the home stack to the front below
10456                final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10457                        REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10458                        "moveTaskToDockedStack");
10459                if (moved) {
10460                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10461                }
10462                return moved;
10463            } finally {
10464                Binder.restoreCallingIdentity(ident);
10465            }
10466        }
10467    }
10468
10469    /**
10470     * Moves the top activity in the input stackId to the pinned stack.
10471     *
10472     * @param stackId Id of stack to move the top activity to pinned stack.
10473     * @param bounds Bounds to use for pinned stack.
10474     *
10475     * @return True if the top activity of the input stack was successfully moved to the pinned
10476     *          stack.
10477     */
10478    @Override
10479    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10480        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10481        synchronized (this) {
10482            if (!mSupportsPictureInPicture) {
10483                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10484                        + "Device doesn't support picture-in-picture mode");
10485            }
10486
10487            long ident = Binder.clearCallingIdentity();
10488            try {
10489                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10490            } finally {
10491                Binder.restoreCallingIdentity(ident);
10492            }
10493        }
10494    }
10495
10496    @Override
10497    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10498            boolean preserveWindows, boolean animate, int animationDuration) {
10499        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10500        long ident = Binder.clearCallingIdentity();
10501        try {
10502            synchronized (this) {
10503                if (animate) {
10504                    if (stackId == PINNED_STACK_ID) {
10505                        final PinnedActivityStack pinnedStack =
10506                                mStackSupervisor.getStack(PINNED_STACK_ID);
10507                        if (pinnedStack != null) {
10508                            pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10509                                    destBounds, animationDuration,
10510                                    false /* schedulePipModeChangedOnAnimationEnd */);
10511                        }
10512                    } else {
10513                        throw new IllegalArgumentException("Stack: " + stackId
10514                                + " doesn't support animated resize.");
10515                    }
10516                } else {
10517                    mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10518                            null /* tempTaskInsetBounds */, preserveWindows,
10519                            allowResizeInDockedMode, !DEFER_RESUME);
10520                }
10521            }
10522        } finally {
10523            Binder.restoreCallingIdentity(ident);
10524        }
10525    }
10526
10527    @Override
10528    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10529            Rect tempDockedTaskInsetBounds,
10530            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10531        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10532                "resizeDockedStack()");
10533        long ident = Binder.clearCallingIdentity();
10534        try {
10535            synchronized (this) {
10536                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10537                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10538                        PRESERVE_WINDOWS);
10539            }
10540        } finally {
10541            Binder.restoreCallingIdentity(ident);
10542        }
10543    }
10544
10545    @Override
10546    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10547        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10548                "resizePinnedStack()");
10549        final long ident = Binder.clearCallingIdentity();
10550        try {
10551            synchronized (this) {
10552                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10553            }
10554        } finally {
10555            Binder.restoreCallingIdentity(ident);
10556        }
10557    }
10558
10559    /**
10560     * Try to place task to provided position. The final position might be different depending on
10561     * current user and stacks state. The task will be moved to target stack if it's currently in
10562     * different stack.
10563     */
10564    @Override
10565    public void positionTaskInStack(int taskId, int stackId, int position) {
10566        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10567        if (StackId.isHomeOrRecentsStack(stackId)) {
10568            throw new IllegalArgumentException(
10569                    "positionTaskInStack: Attempt to change the position of task "
10570                    + taskId + " in/to home/recents stack");
10571        }
10572        synchronized (this) {
10573            long ident = Binder.clearCallingIdentity();
10574            try {
10575                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10576                        + taskId + " in stackId=" + stackId + " at position=" + position);
10577                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10578                if (task == null) {
10579                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10580                            + taskId);
10581                }
10582
10583                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10584                        !ON_TOP);
10585
10586                // TODO: Have the callers of this API call a separate reparent method if that is
10587                // what they intended to do vs. having this method also do reparenting.
10588                if (task.getStack() == stack) {
10589                    // Change position in current stack.
10590                    stack.positionChildAt(task, position);
10591                } else {
10592                    // Reparent to new stack.
10593                    task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10594                            !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10595                }
10596            } finally {
10597                Binder.restoreCallingIdentity(ident);
10598            }
10599        }
10600    }
10601
10602    @Override
10603    public List<StackInfo> getAllStackInfos() {
10604        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10605        long ident = Binder.clearCallingIdentity();
10606        try {
10607            synchronized (this) {
10608                return mStackSupervisor.getAllStackInfosLocked();
10609            }
10610        } finally {
10611            Binder.restoreCallingIdentity(ident);
10612        }
10613    }
10614
10615    @Override
10616    public StackInfo getStackInfo(int stackId) {
10617        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10618        long ident = Binder.clearCallingIdentity();
10619        try {
10620            synchronized (this) {
10621                return mStackSupervisor.getStackInfoLocked(stackId);
10622            }
10623        } finally {
10624            Binder.restoreCallingIdentity(ident);
10625        }
10626    }
10627
10628    @Override
10629    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10630        synchronized(this) {
10631            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10632        }
10633    }
10634
10635    @Override
10636    public void updateDeviceOwner(String packageName) {
10637        final int callingUid = Binder.getCallingUid();
10638        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10639            throw new SecurityException("updateDeviceOwner called from non-system process");
10640        }
10641        synchronized (this) {
10642            mDeviceOwnerName = packageName;
10643        }
10644    }
10645
10646    @Override
10647    public void updateLockTaskPackages(int userId, String[] packages) {
10648        final int callingUid = Binder.getCallingUid();
10649        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10650            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10651                    "updateLockTaskPackages()");
10652        }
10653        synchronized (this) {
10654            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10655                    Arrays.toString(packages));
10656            mLockTaskPackages.put(userId, packages);
10657            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10658        }
10659    }
10660
10661
10662    void startLockTaskModeLocked(TaskRecord task) {
10663        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10664        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10665            return;
10666        }
10667
10668        // When a task is locked, dismiss the pinned stack if it exists
10669        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10670                PINNED_STACK_ID);
10671        if (pinnedStack != null) {
10672            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10673        }
10674
10675        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10676        // is initiated by system after the pinning request was shown and locked mode is initiated
10677        // by an authorized app directly
10678        final int callingUid = Binder.getCallingUid();
10679        boolean isSystemInitiated = callingUid == SYSTEM_UID;
10680        long ident = Binder.clearCallingIdentity();
10681        try {
10682            if (!isSystemInitiated) {
10683                task.mLockTaskUid = callingUid;
10684                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10685                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10686                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10687                    StatusBarManagerInternal statusBarManager =
10688                            LocalServices.getService(StatusBarManagerInternal.class);
10689                    if (statusBarManager != null) {
10690                        statusBarManager.showScreenPinningRequest(task.taskId);
10691                    }
10692                    return;
10693                }
10694
10695                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10696                if (stack == null || task != stack.topTask()) {
10697                    throw new IllegalArgumentException("Invalid task, not in foreground");
10698                }
10699            }
10700            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10701                    "Locking fully");
10702            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10703                    ActivityManager.LOCK_TASK_MODE_PINNED :
10704                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10705                    "startLockTask", true);
10706        } finally {
10707            Binder.restoreCallingIdentity(ident);
10708        }
10709    }
10710
10711    @Override
10712    public void startLockTaskModeById(int taskId) {
10713        synchronized (this) {
10714            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10715            if (task != null) {
10716                startLockTaskModeLocked(task);
10717            }
10718        }
10719    }
10720
10721    @Override
10722    public void startLockTaskModeByToken(IBinder token) {
10723        synchronized (this) {
10724            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10725            if (r == null) {
10726                return;
10727            }
10728            final TaskRecord task = r.getTask();
10729            if (task != null) {
10730                startLockTaskModeLocked(task);
10731            }
10732        }
10733    }
10734
10735    @Override
10736    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10737        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10738        // This makes inner call to look as if it was initiated by system.
10739        long ident = Binder.clearCallingIdentity();
10740        try {
10741            synchronized (this) {
10742                startLockTaskModeById(taskId);
10743            }
10744        } finally {
10745            Binder.restoreCallingIdentity(ident);
10746        }
10747    }
10748
10749    @Override
10750    public void stopLockTaskMode() {
10751        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10752        if (lockTask == null) {
10753            // Our work here is done.
10754            return;
10755        }
10756
10757        final int callingUid = Binder.getCallingUid();
10758        final int lockTaskUid = lockTask.mLockTaskUid;
10759        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10760        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10761            // Done.
10762            return;
10763        } else {
10764            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10765            // It is possible lockTaskMode was started by the system process because
10766            // android:lockTaskMode is set to a locking value in the application manifest
10767            // instead of the app calling startLockTaskMode. In this case
10768            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10769            // {@link TaskRecord.effectiveUid} instead. Also caller with
10770            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10771            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10772                    && callingUid != lockTaskUid
10773                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10774                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10775                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10776            }
10777        }
10778        long ident = Binder.clearCallingIdentity();
10779        try {
10780            Log.d(TAG, "stopLockTaskMode");
10781            // Stop lock task
10782            synchronized (this) {
10783                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10784                        "stopLockTask", true);
10785            }
10786            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10787            if (tm != null) {
10788                tm.showInCallScreen(false);
10789            }
10790        } finally {
10791            Binder.restoreCallingIdentity(ident);
10792        }
10793    }
10794
10795    /**
10796     * This API should be called by SystemUI only when user perform certain action to dismiss
10797     * lock task mode. We should only dismiss pinned lock task mode in this case.
10798     */
10799    @Override
10800    public void stopSystemLockTaskMode() throws RemoteException {
10801        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10802            stopLockTaskMode();
10803        } else {
10804            mStackSupervisor.showLockTaskToast();
10805        }
10806    }
10807
10808    @Override
10809    public boolean isInLockTaskMode() {
10810        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10811    }
10812
10813    @Override
10814    public int getLockTaskModeState() {
10815        synchronized (this) {
10816            return mStackSupervisor.getLockTaskModeState();
10817        }
10818    }
10819
10820    @Override
10821    public void showLockTaskEscapeMessage(IBinder token) {
10822        synchronized (this) {
10823            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10824            if (r == null) {
10825                return;
10826            }
10827            mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
10828        }
10829    }
10830
10831    @Override
10832    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
10833            throws RemoteException {
10834        synchronized (this) {
10835            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10836            if (r == null) {
10837                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
10838                        + token);
10839                return;
10840            }
10841            final long origId = Binder.clearCallingIdentity();
10842            try {
10843                r.setDisablePreviewScreenshots(disable);
10844            } finally {
10845                Binder.restoreCallingIdentity(origId);
10846            }
10847        }
10848    }
10849
10850    // =========================================================
10851    // CONTENT PROVIDERS
10852    // =========================================================
10853
10854    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10855        List<ProviderInfo> providers = null;
10856        try {
10857            providers = AppGlobals.getPackageManager()
10858                    .queryContentProviders(app.processName, app.uid,
10859                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10860                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
10861                    .getList();
10862        } catch (RemoteException ex) {
10863        }
10864        if (DEBUG_MU) Slog.v(TAG_MU,
10865                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10866        int userId = app.userId;
10867        if (providers != null) {
10868            int N = providers.size();
10869            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10870            for (int i=0; i<N; i++) {
10871                // TODO: keep logic in sync with installEncryptionUnawareProviders
10872                ProviderInfo cpi =
10873                    (ProviderInfo)providers.get(i);
10874                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10875                        cpi.name, cpi.flags);
10876                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10877                    // This is a singleton provider, but a user besides the
10878                    // default user is asking to initialize a process it runs
10879                    // in...  well, no, it doesn't actually run in this process,
10880                    // it runs in the process of the default user.  Get rid of it.
10881                    providers.remove(i);
10882                    N--;
10883                    i--;
10884                    continue;
10885                }
10886
10887                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10888                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10889                if (cpr == null) {
10890                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10891                    mProviderMap.putProviderByClass(comp, cpr);
10892                }
10893                if (DEBUG_MU) Slog.v(TAG_MU,
10894                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10895                app.pubProviders.put(cpi.name, cpr);
10896                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10897                    // Don't add this if it is a platform component that is marked
10898                    // to run in multiple processes, because this is actually
10899                    // part of the framework so doesn't make sense to track as a
10900                    // separate apk in the process.
10901                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10902                            mProcessStats);
10903                }
10904                notifyPackageUse(cpi.applicationInfo.packageName,
10905                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10906            }
10907        }
10908        return providers;
10909    }
10910
10911    /**
10912     * Check if the calling UID has a possible chance at accessing the provider
10913     * at the given authority and user.
10914     */
10915    public String checkContentProviderAccess(String authority, int userId) {
10916        if (userId == UserHandle.USER_ALL) {
10917            mContext.enforceCallingOrSelfPermission(
10918                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10919            userId = UserHandle.getCallingUserId();
10920        }
10921
10922        ProviderInfo cpi = null;
10923        try {
10924            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10925                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10926                            | PackageManager.MATCH_DISABLED_COMPONENTS
10927                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10928                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10929                    userId);
10930        } catch (RemoteException ignored) {
10931        }
10932        if (cpi == null) {
10933            return "Failed to find provider " + authority + " for user " + userId
10934                    + "; expected to find a valid ContentProvider for this authority";
10935        }
10936
10937        ProcessRecord r = null;
10938        synchronized (mPidsSelfLocked) {
10939            r = mPidsSelfLocked.get(Binder.getCallingPid());
10940        }
10941        if (r == null) {
10942            return "Failed to find PID " + Binder.getCallingPid();
10943        }
10944
10945        synchronized (this) {
10946            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10947        }
10948    }
10949
10950    /**
10951     * Check if {@link ProcessRecord} has a possible chance at accessing the
10952     * given {@link ProviderInfo}. Final permission checking is always done
10953     * in {@link ContentProvider}.
10954     */
10955    private final String checkContentProviderPermissionLocked(
10956            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10957        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10958        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10959        boolean checkedGrants = false;
10960        if (checkUser) {
10961            // Looking for cross-user grants before enforcing the typical cross-users permissions
10962            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10963            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10964                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10965                    return null;
10966                }
10967                checkedGrants = true;
10968            }
10969            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10970                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10971            if (userId != tmpTargetUserId) {
10972                // When we actually went to determine the final targer user ID, this ended
10973                // up different than our initial check for the authority.  This is because
10974                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10975                // SELF.  So we need to re-check the grants again.
10976                checkedGrants = false;
10977            }
10978        }
10979        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10980                cpi.applicationInfo.uid, cpi.exported)
10981                == PackageManager.PERMISSION_GRANTED) {
10982            return null;
10983        }
10984        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10985                cpi.applicationInfo.uid, cpi.exported)
10986                == PackageManager.PERMISSION_GRANTED) {
10987            return null;
10988        }
10989
10990        PathPermission[] pps = cpi.pathPermissions;
10991        if (pps != null) {
10992            int i = pps.length;
10993            while (i > 0) {
10994                i--;
10995                PathPermission pp = pps[i];
10996                String pprperm = pp.getReadPermission();
10997                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10998                        cpi.applicationInfo.uid, cpi.exported)
10999                        == PackageManager.PERMISSION_GRANTED) {
11000                    return null;
11001                }
11002                String ppwperm = pp.getWritePermission();
11003                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11004                        cpi.applicationInfo.uid, cpi.exported)
11005                        == PackageManager.PERMISSION_GRANTED) {
11006                    return null;
11007                }
11008            }
11009        }
11010        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11011            return null;
11012        }
11013
11014        final String suffix;
11015        if (!cpi.exported) {
11016            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11017        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11018            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11019        } else {
11020            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11021        }
11022        final String msg = "Permission Denial: opening provider " + cpi.name
11023                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11024                + ", uid=" + callingUid + ")" + suffix;
11025        Slog.w(TAG, msg);
11026        return msg;
11027    }
11028
11029    /**
11030     * Returns if the ContentProvider has granted a uri to callingUid
11031     */
11032    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11033        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11034        if (perms != null) {
11035            for (int i=perms.size()-1; i>=0; i--) {
11036                GrantUri grantUri = perms.keyAt(i);
11037                if (grantUri.sourceUserId == userId || !checkUser) {
11038                    if (matchesProvider(grantUri.uri, cpi)) {
11039                        return true;
11040                    }
11041                }
11042            }
11043        }
11044        return false;
11045    }
11046
11047    /**
11048     * Returns true if the uri authority is one of the authorities specified in the provider.
11049     */
11050    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11051        String uriAuth = uri.getAuthority();
11052        String cpiAuth = cpi.authority;
11053        if (cpiAuth.indexOf(';') == -1) {
11054            return cpiAuth.equals(uriAuth);
11055        }
11056        String[] cpiAuths = cpiAuth.split(";");
11057        int length = cpiAuths.length;
11058        for (int i = 0; i < length; i++) {
11059            if (cpiAuths[i].equals(uriAuth)) return true;
11060        }
11061        return false;
11062    }
11063
11064    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11065            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11066        if (r != null) {
11067            for (int i=0; i<r.conProviders.size(); i++) {
11068                ContentProviderConnection conn = r.conProviders.get(i);
11069                if (conn.provider == cpr) {
11070                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11071                            "Adding provider requested by "
11072                            + r.processName + " from process "
11073                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11074                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11075                    if (stable) {
11076                        conn.stableCount++;
11077                        conn.numStableIncs++;
11078                    } else {
11079                        conn.unstableCount++;
11080                        conn.numUnstableIncs++;
11081                    }
11082                    return conn;
11083                }
11084            }
11085            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11086            if (stable) {
11087                conn.stableCount = 1;
11088                conn.numStableIncs = 1;
11089            } else {
11090                conn.unstableCount = 1;
11091                conn.numUnstableIncs = 1;
11092            }
11093            cpr.connections.add(conn);
11094            r.conProviders.add(conn);
11095            startAssociationLocked(r.uid, r.processName, r.curProcState,
11096                    cpr.uid, cpr.name, cpr.info.processName);
11097            return conn;
11098        }
11099        cpr.addExternalProcessHandleLocked(externalProcessToken);
11100        return null;
11101    }
11102
11103    boolean decProviderCountLocked(ContentProviderConnection conn,
11104            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11105        if (conn != null) {
11106            cpr = conn.provider;
11107            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11108                    "Removing provider requested by "
11109                    + conn.client.processName + " from process "
11110                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11111                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11112            if (stable) {
11113                conn.stableCount--;
11114            } else {
11115                conn.unstableCount--;
11116            }
11117            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11118                cpr.connections.remove(conn);
11119                conn.client.conProviders.remove(conn);
11120                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11121                    // The client is more important than last activity -- note the time this
11122                    // is happening, so we keep the old provider process around a bit as last
11123                    // activity to avoid thrashing it.
11124                    if (cpr.proc != null) {
11125                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11126                    }
11127                }
11128                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11129                return true;
11130            }
11131            return false;
11132        }
11133        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11134        return false;
11135    }
11136
11137    private void checkTime(long startTime, String where) {
11138        long now = SystemClock.uptimeMillis();
11139        if ((now-startTime) > 50) {
11140            // If we are taking more than 50ms, log about it.
11141            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11142        }
11143    }
11144
11145    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11146            PROC_SPACE_TERM,
11147            PROC_SPACE_TERM|PROC_PARENS,
11148            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11149    };
11150
11151    private final long[] mProcessStateStatsLongs = new long[1];
11152
11153    boolean isProcessAliveLocked(ProcessRecord proc) {
11154        if (proc.procStatFile == null) {
11155            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11156        }
11157        mProcessStateStatsLongs[0] = 0;
11158        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11159                mProcessStateStatsLongs, null)) {
11160            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11161            return false;
11162        }
11163        final long state = mProcessStateStatsLongs[0];
11164        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11165                + (char)state);
11166        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11167    }
11168
11169    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11170            String name, IBinder token, boolean stable, int userId) {
11171        ContentProviderRecord cpr;
11172        ContentProviderConnection conn = null;
11173        ProviderInfo cpi = null;
11174
11175        synchronized(this) {
11176            long startTime = SystemClock.uptimeMillis();
11177
11178            ProcessRecord r = null;
11179            if (caller != null) {
11180                r = getRecordForAppLocked(caller);
11181                if (r == null) {
11182                    throw new SecurityException(
11183                            "Unable to find app for caller " + caller
11184                          + " (pid=" + Binder.getCallingPid()
11185                          + ") when getting content provider " + name);
11186                }
11187            }
11188
11189            boolean checkCrossUser = true;
11190
11191            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11192
11193            // First check if this content provider has been published...
11194            cpr = mProviderMap.getProviderByName(name, userId);
11195            // If that didn't work, check if it exists for user 0 and then
11196            // verify that it's a singleton provider before using it.
11197            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11198                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11199                if (cpr != null) {
11200                    cpi = cpr.info;
11201                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11202                            cpi.name, cpi.flags)
11203                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11204                        userId = UserHandle.USER_SYSTEM;
11205                        checkCrossUser = false;
11206                    } else {
11207                        cpr = null;
11208                        cpi = null;
11209                    }
11210                }
11211            }
11212
11213            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11214            if (providerRunning) {
11215                cpi = cpr.info;
11216                String msg;
11217                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11218                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11219                        != null) {
11220                    throw new SecurityException(msg);
11221                }
11222                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11223
11224                if (r != null && cpr.canRunHere(r)) {
11225                    // This provider has been published or is in the process
11226                    // of being published...  but it is also allowed to run
11227                    // in the caller's process, so don't make a connection
11228                    // and just let the caller instantiate its own instance.
11229                    ContentProviderHolder holder = cpr.newHolder(null);
11230                    // don't give caller the provider object, it needs
11231                    // to make its own.
11232                    holder.provider = null;
11233                    return holder;
11234                }
11235                // Don't expose providers between normal apps and instant apps
11236                try {
11237                    if (AppGlobals.getPackageManager()
11238                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11239                        return null;
11240                    }
11241                } catch (RemoteException e) {
11242                }
11243
11244                final long origId = Binder.clearCallingIdentity();
11245
11246                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11247
11248                // In this case the provider instance already exists, so we can
11249                // return it right away.
11250                conn = incProviderCountLocked(r, cpr, token, stable);
11251                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11252                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11253                        // If this is a perceptible app accessing the provider,
11254                        // make sure to count it as being accessed and thus
11255                        // back up on the LRU list.  This is good because
11256                        // content providers are often expensive to start.
11257                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11258                        updateLruProcessLocked(cpr.proc, false, null);
11259                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11260                    }
11261                }
11262
11263                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11264                final int verifiedAdj = cpr.proc.verifiedAdj;
11265                boolean success = updateOomAdjLocked(cpr.proc);
11266                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11267                // if the process has been successfully adjusted.  So to reduce races with
11268                // it, we will check whether the process still exists.  Note that this doesn't
11269                // completely get rid of races with LMK killing the process, but should make
11270                // them much smaller.
11271                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11272                    success = false;
11273                }
11274                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11275                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11276                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11277                // NOTE: there is still a race here where a signal could be
11278                // pending on the process even though we managed to update its
11279                // adj level.  Not sure what to do about this, but at least
11280                // the race is now smaller.
11281                if (!success) {
11282                    // Uh oh...  it looks like the provider's process
11283                    // has been killed on us.  We need to wait for a new
11284                    // process to be started, and make sure its death
11285                    // doesn't kill our process.
11286                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11287                            + " is crashing; detaching " + r);
11288                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11289                    checkTime(startTime, "getContentProviderImpl: before appDied");
11290                    appDiedLocked(cpr.proc);
11291                    checkTime(startTime, "getContentProviderImpl: after appDied");
11292                    if (!lastRef) {
11293                        // This wasn't the last ref our process had on
11294                        // the provider...  we have now been killed, bail.
11295                        return null;
11296                    }
11297                    providerRunning = false;
11298                    conn = null;
11299                } else {
11300                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11301                }
11302
11303                Binder.restoreCallingIdentity(origId);
11304            }
11305
11306            if (!providerRunning) {
11307                try {
11308                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11309                    cpi = AppGlobals.getPackageManager().
11310                        resolveContentProvider(name,
11311                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11312                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11313                } catch (RemoteException ex) {
11314                }
11315                if (cpi == null) {
11316                    return null;
11317                }
11318                // If the provider is a singleton AND
11319                // (it's a call within the same user || the provider is a
11320                // privileged app)
11321                // Then allow connecting to the singleton provider
11322                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11323                        cpi.name, cpi.flags)
11324                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11325                if (singleton) {
11326                    userId = UserHandle.USER_SYSTEM;
11327                }
11328                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11329                checkTime(startTime, "getContentProviderImpl: got app info for user");
11330
11331                String msg;
11332                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11333                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11334                        != null) {
11335                    throw new SecurityException(msg);
11336                }
11337                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11338
11339                if (!mProcessesReady
11340                        && !cpi.processName.equals("system")) {
11341                    // If this content provider does not run in the system
11342                    // process, and the system is not yet ready to run other
11343                    // processes, then fail fast instead of hanging.
11344                    throw new IllegalArgumentException(
11345                            "Attempt to launch content provider before system ready");
11346                }
11347
11348                // Make sure that the user who owns this provider is running.  If not,
11349                // we don't want to allow it to run.
11350                if (!mUserController.isUserRunningLocked(userId, 0)) {
11351                    Slog.w(TAG, "Unable to launch app "
11352                            + cpi.applicationInfo.packageName + "/"
11353                            + cpi.applicationInfo.uid + " for provider "
11354                            + name + ": user " + userId + " is stopped");
11355                    return null;
11356                }
11357
11358                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11359                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11360                cpr = mProviderMap.getProviderByClass(comp, userId);
11361                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11362                final boolean firstClass = cpr == null;
11363                if (firstClass) {
11364                    final long ident = Binder.clearCallingIdentity();
11365
11366                    // If permissions need a review before any of the app components can run,
11367                    // we return no provider and launch a review activity if the calling app
11368                    // is in the foreground.
11369                    if (mPermissionReviewRequired) {
11370                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11371                            return null;
11372                        }
11373                    }
11374
11375                    try {
11376                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11377                        ApplicationInfo ai =
11378                            AppGlobals.getPackageManager().
11379                                getApplicationInfo(
11380                                        cpi.applicationInfo.packageName,
11381                                        STOCK_PM_FLAGS, userId);
11382                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11383                        if (ai == null) {
11384                            Slog.w(TAG, "No package info for content provider "
11385                                    + cpi.name);
11386                            return null;
11387                        }
11388                        ai = getAppInfoForUser(ai, userId);
11389                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11390                    } catch (RemoteException ex) {
11391                        // pm is in same process, this will never happen.
11392                    } finally {
11393                        Binder.restoreCallingIdentity(ident);
11394                    }
11395                }
11396
11397                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11398
11399                if (r != null && cpr.canRunHere(r)) {
11400                    // If this is a multiprocess provider, then just return its
11401                    // info and allow the caller to instantiate it.  Only do
11402                    // this if the provider is the same user as the caller's
11403                    // process, or can run as root (so can be in any process).
11404                    return cpr.newHolder(null);
11405                }
11406
11407                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11408                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11409                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11410
11411                // This is single process, and our app is now connecting to it.
11412                // See if we are already in the process of launching this
11413                // provider.
11414                final int N = mLaunchingProviders.size();
11415                int i;
11416                for (i = 0; i < N; i++) {
11417                    if (mLaunchingProviders.get(i) == cpr) {
11418                        break;
11419                    }
11420                }
11421
11422                // If the provider is not already being launched, then get it
11423                // started.
11424                if (i >= N) {
11425                    final long origId = Binder.clearCallingIdentity();
11426
11427                    try {
11428                        // Content provider is now in use, its package can't be stopped.
11429                        try {
11430                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11431                            AppGlobals.getPackageManager().setPackageStoppedState(
11432                                    cpr.appInfo.packageName, false, userId);
11433                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11434                        } catch (RemoteException e) {
11435                        } catch (IllegalArgumentException e) {
11436                            Slog.w(TAG, "Failed trying to unstop package "
11437                                    + cpr.appInfo.packageName + ": " + e);
11438                        }
11439
11440                        // Use existing process if already started
11441                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11442                        ProcessRecord proc = getProcessRecordLocked(
11443                                cpi.processName, cpr.appInfo.uid, false);
11444                        if (proc != null && proc.thread != null && !proc.killed) {
11445                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11446                                    "Installing in existing process " + proc);
11447                            if (!proc.pubProviders.containsKey(cpi.name)) {
11448                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11449                                proc.pubProviders.put(cpi.name, cpr);
11450                                try {
11451                                    proc.thread.scheduleInstallProvider(cpi);
11452                                } catch (RemoteException e) {
11453                                }
11454                            }
11455                        } else {
11456                            checkTime(startTime, "getContentProviderImpl: before start process");
11457                            proc = startProcessLocked(cpi.processName,
11458                                    cpr.appInfo, false, 0, "content provider",
11459                                    new ComponentName(cpi.applicationInfo.packageName,
11460                                            cpi.name), false, false, false);
11461                            checkTime(startTime, "getContentProviderImpl: after start process");
11462                            if (proc == null) {
11463                                Slog.w(TAG, "Unable to launch app "
11464                                        + cpi.applicationInfo.packageName + "/"
11465                                        + cpi.applicationInfo.uid + " for provider "
11466                                        + name + ": process is bad");
11467                                return null;
11468                            }
11469                        }
11470                        cpr.launchingApp = proc;
11471                        mLaunchingProviders.add(cpr);
11472                    } finally {
11473                        Binder.restoreCallingIdentity(origId);
11474                    }
11475                }
11476
11477                checkTime(startTime, "getContentProviderImpl: updating data structures");
11478
11479                // Make sure the provider is published (the same provider class
11480                // may be published under multiple names).
11481                if (firstClass) {
11482                    mProviderMap.putProviderByClass(comp, cpr);
11483                }
11484
11485                mProviderMap.putProviderByName(name, cpr);
11486                conn = incProviderCountLocked(r, cpr, token, stable);
11487                if (conn != null) {
11488                    conn.waiting = true;
11489                }
11490            }
11491            checkTime(startTime, "getContentProviderImpl: done!");
11492
11493            grantEphemeralAccessLocked(userId, null /*intent*/,
11494                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11495        }
11496
11497        // Wait for the provider to be published...
11498        synchronized (cpr) {
11499            while (cpr.provider == null) {
11500                if (cpr.launchingApp == null) {
11501                    Slog.w(TAG, "Unable to launch app "
11502                            + cpi.applicationInfo.packageName + "/"
11503                            + cpi.applicationInfo.uid + " for provider "
11504                            + name + ": launching app became null");
11505                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11506                            UserHandle.getUserId(cpi.applicationInfo.uid),
11507                            cpi.applicationInfo.packageName,
11508                            cpi.applicationInfo.uid, name);
11509                    return null;
11510                }
11511                try {
11512                    if (DEBUG_MU) Slog.v(TAG_MU,
11513                            "Waiting to start provider " + cpr
11514                            + " launchingApp=" + cpr.launchingApp);
11515                    if (conn != null) {
11516                        conn.waiting = true;
11517                    }
11518                    cpr.wait();
11519                } catch (InterruptedException ex) {
11520                } finally {
11521                    if (conn != null) {
11522                        conn.waiting = false;
11523                    }
11524                }
11525            }
11526        }
11527        return cpr != null ? cpr.newHolder(conn) : null;
11528    }
11529
11530    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11531            ProcessRecord r, final int userId) {
11532        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11533                cpi.packageName, userId)) {
11534
11535            final boolean callerForeground = r == null || r.setSchedGroup
11536                    != ProcessList.SCHED_GROUP_BACKGROUND;
11537
11538            // Show a permission review UI only for starting from a foreground app
11539            if (!callerForeground) {
11540                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11541                        + cpi.packageName + " requires a permissions review");
11542                return false;
11543            }
11544
11545            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11546            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11547                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11548            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11549
11550            if (DEBUG_PERMISSIONS_REVIEW) {
11551                Slog.i(TAG, "u" + userId + " Launching permission review "
11552                        + "for package " + cpi.packageName);
11553            }
11554
11555            final UserHandle userHandle = new UserHandle(userId);
11556            mHandler.post(new Runnable() {
11557                @Override
11558                public void run() {
11559                    mContext.startActivityAsUser(intent, userHandle);
11560                }
11561            });
11562
11563            return false;
11564        }
11565
11566        return true;
11567    }
11568
11569    PackageManagerInternal getPackageManagerInternalLocked() {
11570        if (mPackageManagerInt == null) {
11571            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11572        }
11573        return mPackageManagerInt;
11574    }
11575
11576    @Override
11577    public final ContentProviderHolder getContentProvider(
11578            IApplicationThread caller, String name, int userId, boolean stable) {
11579        enforceNotIsolatedCaller("getContentProvider");
11580        if (caller == null) {
11581            String msg = "null IApplicationThread when getting content provider "
11582                    + name;
11583            Slog.w(TAG, msg);
11584            throw new SecurityException(msg);
11585        }
11586        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11587        // with cross-user grant.
11588        return getContentProviderImpl(caller, name, null, stable, userId);
11589    }
11590
11591    public ContentProviderHolder getContentProviderExternal(
11592            String name, int userId, IBinder token) {
11593        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11594            "Do not have permission in call getContentProviderExternal()");
11595        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11596                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11597        return getContentProviderExternalUnchecked(name, token, userId);
11598    }
11599
11600    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11601            IBinder token, int userId) {
11602        return getContentProviderImpl(null, name, token, true, userId);
11603    }
11604
11605    /**
11606     * Drop a content provider from a ProcessRecord's bookkeeping
11607     */
11608    public void removeContentProvider(IBinder connection, boolean stable) {
11609        enforceNotIsolatedCaller("removeContentProvider");
11610        long ident = Binder.clearCallingIdentity();
11611        try {
11612            synchronized (this) {
11613                ContentProviderConnection conn;
11614                try {
11615                    conn = (ContentProviderConnection)connection;
11616                } catch (ClassCastException e) {
11617                    String msg ="removeContentProvider: " + connection
11618                            + " not a ContentProviderConnection";
11619                    Slog.w(TAG, msg);
11620                    throw new IllegalArgumentException(msg);
11621                }
11622                if (conn == null) {
11623                    throw new NullPointerException("connection is null");
11624                }
11625                if (decProviderCountLocked(conn, null, null, stable)) {
11626                    updateOomAdjLocked();
11627                }
11628            }
11629        } finally {
11630            Binder.restoreCallingIdentity(ident);
11631        }
11632    }
11633
11634    public void removeContentProviderExternal(String name, IBinder token) {
11635        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11636            "Do not have permission in call removeContentProviderExternal()");
11637        int userId = UserHandle.getCallingUserId();
11638        long ident = Binder.clearCallingIdentity();
11639        try {
11640            removeContentProviderExternalUnchecked(name, token, userId);
11641        } finally {
11642            Binder.restoreCallingIdentity(ident);
11643        }
11644    }
11645
11646    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11647        synchronized (this) {
11648            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11649            if(cpr == null) {
11650                //remove from mProvidersByClass
11651                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11652                return;
11653            }
11654
11655            //update content provider record entry info
11656            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11657            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11658            if (localCpr.hasExternalProcessHandles()) {
11659                if (localCpr.removeExternalProcessHandleLocked(token)) {
11660                    updateOomAdjLocked();
11661                } else {
11662                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11663                            + " with no external reference for token: "
11664                            + token + ".");
11665                }
11666            } else {
11667                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11668                        + " with no external references.");
11669            }
11670        }
11671    }
11672
11673    public final void publishContentProviders(IApplicationThread caller,
11674            List<ContentProviderHolder> providers) {
11675        if (providers == null) {
11676            return;
11677        }
11678
11679        enforceNotIsolatedCaller("publishContentProviders");
11680        synchronized (this) {
11681            final ProcessRecord r = getRecordForAppLocked(caller);
11682            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11683            if (r == null) {
11684                throw new SecurityException(
11685                        "Unable to find app for caller " + caller
11686                      + " (pid=" + Binder.getCallingPid()
11687                      + ") when publishing content providers");
11688            }
11689
11690            final long origId = Binder.clearCallingIdentity();
11691
11692            final int N = providers.size();
11693            for (int i = 0; i < N; i++) {
11694                ContentProviderHolder src = providers.get(i);
11695                if (src == null || src.info == null || src.provider == null) {
11696                    continue;
11697                }
11698                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11699                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11700                if (dst != null) {
11701                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11702                    mProviderMap.putProviderByClass(comp, dst);
11703                    String names[] = dst.info.authority.split(";");
11704                    for (int j = 0; j < names.length; j++) {
11705                        mProviderMap.putProviderByName(names[j], dst);
11706                    }
11707
11708                    int launchingCount = mLaunchingProviders.size();
11709                    int j;
11710                    boolean wasInLaunchingProviders = false;
11711                    for (j = 0; j < launchingCount; j++) {
11712                        if (mLaunchingProviders.get(j) == dst) {
11713                            mLaunchingProviders.remove(j);
11714                            wasInLaunchingProviders = true;
11715                            j--;
11716                            launchingCount--;
11717                        }
11718                    }
11719                    if (wasInLaunchingProviders) {
11720                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11721                    }
11722                    synchronized (dst) {
11723                        dst.provider = src.provider;
11724                        dst.proc = r;
11725                        dst.notifyAll();
11726                    }
11727                    updateOomAdjLocked(r);
11728                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11729                            src.info.authority);
11730                }
11731            }
11732
11733            Binder.restoreCallingIdentity(origId);
11734        }
11735    }
11736
11737    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11738        ContentProviderConnection conn;
11739        try {
11740            conn = (ContentProviderConnection)connection;
11741        } catch (ClassCastException e) {
11742            String msg ="refContentProvider: " + connection
11743                    + " not a ContentProviderConnection";
11744            Slog.w(TAG, msg);
11745            throw new IllegalArgumentException(msg);
11746        }
11747        if (conn == null) {
11748            throw new NullPointerException("connection is null");
11749        }
11750
11751        synchronized (this) {
11752            if (stable > 0) {
11753                conn.numStableIncs += stable;
11754            }
11755            stable = conn.stableCount + stable;
11756            if (stable < 0) {
11757                throw new IllegalStateException("stableCount < 0: " + stable);
11758            }
11759
11760            if (unstable > 0) {
11761                conn.numUnstableIncs += unstable;
11762            }
11763            unstable = conn.unstableCount + unstable;
11764            if (unstable < 0) {
11765                throw new IllegalStateException("unstableCount < 0: " + unstable);
11766            }
11767
11768            if ((stable+unstable) <= 0) {
11769                throw new IllegalStateException("ref counts can't go to zero here: stable="
11770                        + stable + " unstable=" + unstable);
11771            }
11772            conn.stableCount = stable;
11773            conn.unstableCount = unstable;
11774            return !conn.dead;
11775        }
11776    }
11777
11778    public void unstableProviderDied(IBinder connection) {
11779        ContentProviderConnection conn;
11780        try {
11781            conn = (ContentProviderConnection)connection;
11782        } catch (ClassCastException e) {
11783            String msg ="refContentProvider: " + connection
11784                    + " not a ContentProviderConnection";
11785            Slog.w(TAG, msg);
11786            throw new IllegalArgumentException(msg);
11787        }
11788        if (conn == null) {
11789            throw new NullPointerException("connection is null");
11790        }
11791
11792        // Safely retrieve the content provider associated with the connection.
11793        IContentProvider provider;
11794        synchronized (this) {
11795            provider = conn.provider.provider;
11796        }
11797
11798        if (provider == null) {
11799            // Um, yeah, we're way ahead of you.
11800            return;
11801        }
11802
11803        // Make sure the caller is being honest with us.
11804        if (provider.asBinder().pingBinder()) {
11805            // Er, no, still looks good to us.
11806            synchronized (this) {
11807                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11808                        + " says " + conn + " died, but we don't agree");
11809                return;
11810            }
11811        }
11812
11813        // Well look at that!  It's dead!
11814        synchronized (this) {
11815            if (conn.provider.provider != provider) {
11816                // But something changed...  good enough.
11817                return;
11818            }
11819
11820            ProcessRecord proc = conn.provider.proc;
11821            if (proc == null || proc.thread == null) {
11822                // Seems like the process is already cleaned up.
11823                return;
11824            }
11825
11826            // As far as we're concerned, this is just like receiving a
11827            // death notification...  just a bit prematurely.
11828            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11829                    + ") early provider death");
11830            final long ident = Binder.clearCallingIdentity();
11831            try {
11832                appDiedLocked(proc);
11833            } finally {
11834                Binder.restoreCallingIdentity(ident);
11835            }
11836        }
11837    }
11838
11839    @Override
11840    public void appNotRespondingViaProvider(IBinder connection) {
11841        enforceCallingPermission(
11842                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11843
11844        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11845        if (conn == null) {
11846            Slog.w(TAG, "ContentProviderConnection is null");
11847            return;
11848        }
11849
11850        final ProcessRecord host = conn.provider.proc;
11851        if (host == null) {
11852            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11853            return;
11854        }
11855
11856        mHandler.post(new Runnable() {
11857            @Override
11858            public void run() {
11859                mAppErrors.appNotResponding(host, null, null, false,
11860                        "ContentProvider not responding");
11861            }
11862        });
11863    }
11864
11865    public final void installSystemProviders() {
11866        List<ProviderInfo> providers;
11867        synchronized (this) {
11868            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
11869            providers = generateApplicationProvidersLocked(app);
11870            if (providers != null) {
11871                for (int i=providers.size()-1; i>=0; i--) {
11872                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11873                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11874                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11875                                + ": not system .apk");
11876                        providers.remove(i);
11877                    }
11878                }
11879            }
11880        }
11881        if (providers != null) {
11882            mSystemThread.installSystemProviders(providers);
11883        }
11884
11885        mConstants.start(mContext.getContentResolver());
11886        mCoreSettingsObserver = new CoreSettingsObserver(this);
11887        mFontScaleSettingObserver = new FontScaleSettingObserver();
11888
11889        // Now that the settings provider is published we can consider sending
11890        // in a rescue party.
11891        RescueParty.onSettingsProviderPublished(mContext);
11892
11893        //mUsageStatsService.monitorPackages();
11894    }
11895
11896    private void startPersistentApps(int matchFlags) {
11897        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11898
11899        synchronized (this) {
11900            try {
11901                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11902                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11903                for (ApplicationInfo app : apps) {
11904                    if (!"android".equals(app.packageName)) {
11905                        addAppLocked(app, null, false, null /* ABI override */);
11906                    }
11907                }
11908            } catch (RemoteException ex) {
11909            }
11910        }
11911    }
11912
11913    /**
11914     * When a user is unlocked, we need to install encryption-unaware providers
11915     * belonging to any running apps.
11916     */
11917    private void installEncryptionUnawareProviders(int userId) {
11918        // We're only interested in providers that are encryption unaware, and
11919        // we don't care about uninstalled apps, since there's no way they're
11920        // running at this point.
11921        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11922
11923        synchronized (this) {
11924            final int NP = mProcessNames.getMap().size();
11925            for (int ip = 0; ip < NP; ip++) {
11926                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11927                final int NA = apps.size();
11928                for (int ia = 0; ia < NA; ia++) {
11929                    final ProcessRecord app = apps.valueAt(ia);
11930                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11931
11932                    final int NG = app.pkgList.size();
11933                    for (int ig = 0; ig < NG; ig++) {
11934                        try {
11935                            final String pkgName = app.pkgList.keyAt(ig);
11936                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11937                                    .getPackageInfo(pkgName, matchFlags, userId);
11938                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11939                                for (ProviderInfo pi : pkgInfo.providers) {
11940                                    // TODO: keep in sync with generateApplicationProvidersLocked
11941                                    final boolean processMatch = Objects.equals(pi.processName,
11942                                            app.processName) || pi.multiprocess;
11943                                    final boolean userMatch = isSingleton(pi.processName,
11944                                            pi.applicationInfo, pi.name, pi.flags)
11945                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11946                                    if (processMatch && userMatch) {
11947                                        Log.v(TAG, "Installing " + pi);
11948                                        app.thread.scheduleInstallProvider(pi);
11949                                    } else {
11950                                        Log.v(TAG, "Skipping " + pi);
11951                                    }
11952                                }
11953                            }
11954                        } catch (RemoteException ignored) {
11955                        }
11956                    }
11957                }
11958            }
11959        }
11960    }
11961
11962    /**
11963     * Allows apps to retrieve the MIME type of a URI.
11964     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11965     * users, then it does not need permission to access the ContentProvider.
11966     * Either, it needs cross-user uri grants.
11967     *
11968     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11969     *
11970     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11971     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11972     */
11973    public String getProviderMimeType(Uri uri, int userId) {
11974        enforceNotIsolatedCaller("getProviderMimeType");
11975        final String name = uri.getAuthority();
11976        int callingUid = Binder.getCallingUid();
11977        int callingPid = Binder.getCallingPid();
11978        long ident = 0;
11979        boolean clearedIdentity = false;
11980        synchronized (this) {
11981            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11982        }
11983        if (canClearIdentity(callingPid, callingUid, userId)) {
11984            clearedIdentity = true;
11985            ident = Binder.clearCallingIdentity();
11986        }
11987        ContentProviderHolder holder = null;
11988        try {
11989            holder = getContentProviderExternalUnchecked(name, null, userId);
11990            if (holder != null) {
11991                return holder.provider.getType(uri);
11992            }
11993        } catch (RemoteException e) {
11994            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11995            return null;
11996        } catch (Exception e) {
11997            Log.w(TAG, "Exception while determining type of " + uri, e);
11998            return null;
11999        } finally {
12000            // We need to clear the identity to call removeContentProviderExternalUnchecked
12001            if (!clearedIdentity) {
12002                ident = Binder.clearCallingIdentity();
12003            }
12004            try {
12005                if (holder != null) {
12006                    removeContentProviderExternalUnchecked(name, null, userId);
12007                }
12008            } finally {
12009                Binder.restoreCallingIdentity(ident);
12010            }
12011        }
12012
12013        return null;
12014    }
12015
12016    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12017        if (UserHandle.getUserId(callingUid) == userId) {
12018            return true;
12019        }
12020        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12021                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12022                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12023                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12024                return true;
12025        }
12026        return false;
12027    }
12028
12029    // =========================================================
12030    // GLOBAL MANAGEMENT
12031    // =========================================================
12032
12033    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12034            boolean isolated, int isolatedUid) {
12035        String proc = customProcess != null ? customProcess : info.processName;
12036        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12037        final int userId = UserHandle.getUserId(info.uid);
12038        int uid = info.uid;
12039        if (isolated) {
12040            if (isolatedUid == 0) {
12041                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12042                while (true) {
12043                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12044                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12045                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12046                    }
12047                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12048                    mNextIsolatedProcessUid++;
12049                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12050                        // No process for this uid, use it.
12051                        break;
12052                    }
12053                    stepsLeft--;
12054                    if (stepsLeft <= 0) {
12055                        return null;
12056                    }
12057                }
12058            } else {
12059                // Special case for startIsolatedProcess (internal only), where
12060                // the uid of the isolated process is specified by the caller.
12061                uid = isolatedUid;
12062            }
12063            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12064
12065            // Register the isolated UID with this application so BatteryStats knows to
12066            // attribute resource usage to the application.
12067            //
12068            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12069            // about the process state of the isolated UID *before* it is registered with the
12070            // owning application.
12071            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12072        }
12073        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12074        if (!mBooted && !mBooting
12075                && userId == UserHandle.USER_SYSTEM
12076                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12077            r.persistent = true;
12078            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12079        }
12080        addProcessNameLocked(r);
12081        return r;
12082    }
12083
12084    private boolean uidOnBackgroundWhitelist(final int uid) {
12085        final int appId = UserHandle.getAppId(uid);
12086        final int[] whitelist = mBackgroundAppIdWhitelist;
12087        final int N = whitelist.length;
12088        for (int i = 0; i < N; i++) {
12089            if (appId == whitelist[i]) {
12090                return true;
12091            }
12092        }
12093        return false;
12094    }
12095
12096    @Override
12097    public void backgroundWhitelistUid(final int uid) {
12098        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12099            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12100        }
12101
12102        if (DEBUG_BACKGROUND_CHECK) {
12103            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12104        }
12105        synchronized (this) {
12106            final int N = mBackgroundAppIdWhitelist.length;
12107            int[] newList = new int[N+1];
12108            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12109            newList[N] = UserHandle.getAppId(uid);
12110            mBackgroundAppIdWhitelist = newList;
12111        }
12112    }
12113
12114    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12115            String abiOverride) {
12116        ProcessRecord app;
12117        if (!isolated) {
12118            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12119                    info.uid, true);
12120        } else {
12121            app = null;
12122        }
12123
12124        if (app == null) {
12125            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12126            updateLruProcessLocked(app, false, null);
12127            updateOomAdjLocked();
12128        }
12129
12130        // This package really, really can not be stopped.
12131        try {
12132            AppGlobals.getPackageManager().setPackageStoppedState(
12133                    info.packageName, false, UserHandle.getUserId(app.uid));
12134        } catch (RemoteException e) {
12135        } catch (IllegalArgumentException e) {
12136            Slog.w(TAG, "Failed trying to unstop package "
12137                    + info.packageName + ": " + e);
12138        }
12139
12140        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12141            app.persistent = true;
12142            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12143        }
12144        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12145            mPersistentStartingProcesses.add(app);
12146            startProcessLocked(app, "added application",
12147                    customProcess != null ? customProcess : app.processName, abiOverride,
12148                    null /* entryPoint */, null /* entryPointArgs */);
12149        }
12150
12151        return app;
12152    }
12153
12154    public void unhandledBack() {
12155        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12156                "unhandledBack()");
12157
12158        synchronized(this) {
12159            final long origId = Binder.clearCallingIdentity();
12160            try {
12161                getFocusedStack().unhandledBackLocked();
12162            } finally {
12163                Binder.restoreCallingIdentity(origId);
12164            }
12165        }
12166    }
12167
12168    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12169        enforceNotIsolatedCaller("openContentUri");
12170        final int userId = UserHandle.getCallingUserId();
12171        final Uri uri = Uri.parse(uriString);
12172        String name = uri.getAuthority();
12173        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12174        ParcelFileDescriptor pfd = null;
12175        if (cph != null) {
12176            // We record the binder invoker's uid in thread-local storage before
12177            // going to the content provider to open the file.  Later, in the code
12178            // that handles all permissions checks, we look for this uid and use
12179            // that rather than the Activity Manager's own uid.  The effect is that
12180            // we do the check against the caller's permissions even though it looks
12181            // to the content provider like the Activity Manager itself is making
12182            // the request.
12183            Binder token = new Binder();
12184            sCallerIdentity.set(new Identity(
12185                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12186            try {
12187                pfd = cph.provider.openFile(null, uri, "r", null, token);
12188            } catch (FileNotFoundException e) {
12189                // do nothing; pfd will be returned null
12190            } finally {
12191                // Ensure that whatever happens, we clean up the identity state
12192                sCallerIdentity.remove();
12193                // Ensure we're done with the provider.
12194                removeContentProviderExternalUnchecked(name, null, userId);
12195            }
12196        } else {
12197            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12198        }
12199        return pfd;
12200    }
12201
12202    // Actually is sleeping or shutting down or whatever else in the future
12203    // is an inactive state.
12204    boolean isSleepingOrShuttingDownLocked() {
12205        return isSleepingLocked() || mShuttingDown;
12206    }
12207
12208    boolean isShuttingDownLocked() {
12209        return mShuttingDown;
12210    }
12211
12212    boolean isSleepingLocked() {
12213        return mSleeping;
12214    }
12215
12216    void onWakefulnessChanged(int wakefulness) {
12217        synchronized(this) {
12218            mWakefulness = wakefulness;
12219            updateSleepIfNeededLocked();
12220        }
12221    }
12222
12223    void finishRunningVoiceLocked() {
12224        if (mRunningVoice != null) {
12225            mRunningVoice = null;
12226            mVoiceWakeLock.release();
12227            updateSleepIfNeededLocked();
12228        }
12229    }
12230
12231    void startTimeTrackingFocusedActivityLocked() {
12232        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12233        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12234            mCurAppTimeTracker.start(resumedActivity.packageName);
12235        }
12236    }
12237
12238    void updateSleepIfNeededLocked() {
12239        final boolean shouldSleep = shouldSleepLocked();
12240        if (mSleeping && !shouldSleep) {
12241            mSleeping = false;
12242            startTimeTrackingFocusedActivityLocked();
12243            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12244            mStackSupervisor.comeOutOfSleepIfNeededLocked();
12245            sendNotifyVrManagerOfSleepState(false);
12246            updateOomAdjLocked();
12247        } else if (!mSleeping && shouldSleep) {
12248            mSleeping = true;
12249            if (mCurAppTimeTracker != null) {
12250                mCurAppTimeTracker.stop();
12251            }
12252            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12253            mStackSupervisor.goingToSleepLocked();
12254            sendNotifyVrManagerOfSleepState(true);
12255            updateOomAdjLocked();
12256
12257            // Initialize the wake times of all processes.
12258            checkExcessivePowerUsageLocked(false);
12259            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12260            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12261            mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_DELAY);
12262        }
12263
12264        // Also update state in a special way for running foreground services UI.
12265        switch (mWakefulness) {
12266            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12267            case PowerManagerInternal.WAKEFULNESS_DREAMING:
12268            case PowerManagerInternal.WAKEFULNESS_DOZING:
12269                mServices.updateScreenStateLocked(false);
12270                break;
12271            case PowerManagerInternal.WAKEFULNESS_AWAKE:
12272            default:
12273                mServices.updateScreenStateLocked(true);
12274                break;
12275        }
12276    }
12277
12278    private boolean shouldSleepLocked() {
12279        // Resume applications while running a voice interactor.
12280        if (mRunningVoice != null) {
12281            return false;
12282        }
12283
12284        // TODO: Transform the lock screen state into a sleep token instead.
12285        switch (mWakefulness) {
12286            case PowerManagerInternal.WAKEFULNESS_AWAKE:
12287            case PowerManagerInternal.WAKEFULNESS_DREAMING:
12288            case PowerManagerInternal.WAKEFULNESS_DOZING:
12289                // Pause applications whenever the lock screen is shown or any sleep
12290                // tokens have been acquired.
12291                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12292            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12293            default:
12294                // If we're asleep then pause applications unconditionally.
12295                return true;
12296        }
12297    }
12298
12299    /** Pokes the task persister. */
12300    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12301        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12302    }
12303
12304    /**
12305     * Notifies all listeners when the pinned stack animation starts.
12306     */
12307    @Override
12308    public void notifyPinnedStackAnimationStarted() {
12309        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12310    }
12311
12312    /**
12313     * Notifies all listeners when the pinned stack animation ends.
12314     */
12315    @Override
12316    public void notifyPinnedStackAnimationEnded() {
12317        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12318    }
12319
12320    @Override
12321    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12322        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12323    }
12324
12325    @Override
12326    public boolean shutdown(int timeout) {
12327        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12328                != PackageManager.PERMISSION_GRANTED) {
12329            throw new SecurityException("Requires permission "
12330                    + android.Manifest.permission.SHUTDOWN);
12331        }
12332
12333        boolean timedout = false;
12334
12335        synchronized(this) {
12336            mShuttingDown = true;
12337            updateEventDispatchingLocked();
12338            timedout = mStackSupervisor.shutdownLocked(timeout);
12339        }
12340
12341        mAppOpsService.shutdown();
12342        if (mUsageStatsService != null) {
12343            mUsageStatsService.prepareShutdown();
12344        }
12345        mBatteryStatsService.shutdown();
12346        synchronized (this) {
12347            mProcessStats.shutdownLocked();
12348            notifyTaskPersisterLocked(null, true);
12349        }
12350
12351        return timedout;
12352    }
12353
12354    public final void activitySlept(IBinder token) {
12355        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12356
12357        final long origId = Binder.clearCallingIdentity();
12358
12359        synchronized (this) {
12360            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12361            if (r != null) {
12362                mStackSupervisor.activitySleptLocked(r);
12363            }
12364        }
12365
12366        Binder.restoreCallingIdentity(origId);
12367    }
12368
12369    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12370        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12371        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12372        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12373            boolean wasRunningVoice = mRunningVoice != null;
12374            mRunningVoice = session;
12375            if (!wasRunningVoice) {
12376                mVoiceWakeLock.acquire();
12377                updateSleepIfNeededLocked();
12378            }
12379        }
12380    }
12381
12382    private void updateEventDispatchingLocked() {
12383        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12384    }
12385
12386    @Override
12387    public void setLockScreenShown(boolean showing) {
12388        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12389                != PackageManager.PERMISSION_GRANTED) {
12390            throw new SecurityException("Requires permission "
12391                    + android.Manifest.permission.DEVICE_POWER);
12392        }
12393
12394        synchronized(this) {
12395            long ident = Binder.clearCallingIdentity();
12396            try {
12397                mKeyguardController.setKeyguardShown(showing);
12398            } finally {
12399                Binder.restoreCallingIdentity(ident);
12400            }
12401        }
12402    }
12403
12404    @Override
12405    public void notifyLockedProfile(@UserIdInt int userId) {
12406        try {
12407            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12408                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12409            }
12410        } catch (RemoteException ex) {
12411            throw new SecurityException("Fail to check is caller a privileged app", ex);
12412        }
12413
12414        synchronized (this) {
12415            final long ident = Binder.clearCallingIdentity();
12416            try {
12417                if (mUserController.shouldConfirmCredentials(userId)) {
12418                    if (mKeyguardController.isKeyguardLocked()) {
12419                        // Showing launcher to avoid user entering credential twice.
12420                        final int currentUserId = mUserController.getCurrentUserIdLocked();
12421                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12422                    }
12423                    mStackSupervisor.lockAllProfileTasks(userId);
12424                }
12425            } finally {
12426                Binder.restoreCallingIdentity(ident);
12427            }
12428        }
12429    }
12430
12431    @Override
12432    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12433        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12434        synchronized (this) {
12435            final long ident = Binder.clearCallingIdentity();
12436            try {
12437                mActivityStarter.startConfirmCredentialIntent(intent, options);
12438            } finally {
12439                Binder.restoreCallingIdentity(ident);
12440            }
12441        }
12442    }
12443
12444    @Override
12445    public void stopAppSwitches() {
12446        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12447                != PackageManager.PERMISSION_GRANTED) {
12448            throw new SecurityException("viewquires permission "
12449                    + android.Manifest.permission.STOP_APP_SWITCHES);
12450        }
12451
12452        synchronized(this) {
12453            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12454                    + APP_SWITCH_DELAY_TIME;
12455            mDidAppSwitch = false;
12456            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12457            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12458            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12459        }
12460    }
12461
12462    public void resumeAppSwitches() {
12463        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12464                != PackageManager.PERMISSION_GRANTED) {
12465            throw new SecurityException("Requires permission "
12466                    + android.Manifest.permission.STOP_APP_SWITCHES);
12467        }
12468
12469        synchronized(this) {
12470            // Note that we don't execute any pending app switches... we will
12471            // let those wait until either the timeout, or the next start
12472            // activity request.
12473            mAppSwitchesAllowedTime = 0;
12474        }
12475    }
12476
12477    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12478            int callingPid, int callingUid, String name) {
12479        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12480            return true;
12481        }
12482
12483        int perm = checkComponentPermission(
12484                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12485                sourceUid, -1, true);
12486        if (perm == PackageManager.PERMISSION_GRANTED) {
12487            return true;
12488        }
12489
12490        // If the actual IPC caller is different from the logical source, then
12491        // also see if they are allowed to control app switches.
12492        if (callingUid != -1 && callingUid != sourceUid) {
12493            perm = checkComponentPermission(
12494                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12495                    callingUid, -1, true);
12496            if (perm == PackageManager.PERMISSION_GRANTED) {
12497                return true;
12498            }
12499        }
12500
12501        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12502        return false;
12503    }
12504
12505    public void setDebugApp(String packageName, boolean waitForDebugger,
12506            boolean persistent) {
12507        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12508                "setDebugApp()");
12509
12510        long ident = Binder.clearCallingIdentity();
12511        try {
12512            // Note that this is not really thread safe if there are multiple
12513            // callers into it at the same time, but that's not a situation we
12514            // care about.
12515            if (persistent) {
12516                final ContentResolver resolver = mContext.getContentResolver();
12517                Settings.Global.putString(
12518                    resolver, Settings.Global.DEBUG_APP,
12519                    packageName);
12520                Settings.Global.putInt(
12521                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12522                    waitForDebugger ? 1 : 0);
12523            }
12524
12525            synchronized (this) {
12526                if (!persistent) {
12527                    mOrigDebugApp = mDebugApp;
12528                    mOrigWaitForDebugger = mWaitForDebugger;
12529                }
12530                mDebugApp = packageName;
12531                mWaitForDebugger = waitForDebugger;
12532                mDebugTransient = !persistent;
12533                if (packageName != null) {
12534                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12535                            false, UserHandle.USER_ALL, "set debug app");
12536                }
12537            }
12538        } finally {
12539            Binder.restoreCallingIdentity(ident);
12540        }
12541    }
12542
12543    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12544        synchronized (this) {
12545            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12546            if (!isDebuggable) {
12547                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12548                    throw new SecurityException("Process not debuggable: " + app.packageName);
12549                }
12550            }
12551
12552            mTrackAllocationApp = processName;
12553        }
12554    }
12555
12556    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12557        synchronized (this) {
12558            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12559            if (!isDebuggable) {
12560                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12561                    throw new SecurityException("Process not debuggable: " + app.packageName);
12562                }
12563            }
12564            mProfileApp = processName;
12565            mProfileFile = profilerInfo.profileFile;
12566            if (mProfileFd != null) {
12567                try {
12568                    mProfileFd.close();
12569                } catch (IOException e) {
12570                }
12571                mProfileFd = null;
12572            }
12573            mProfileFd = profilerInfo.profileFd;
12574            mSamplingInterval = profilerInfo.samplingInterval;
12575            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12576            mStreamingOutput = profilerInfo.streamingOutput;
12577            mProfileType = 0;
12578        }
12579    }
12580
12581    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12582        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12583        if (!isDebuggable) {
12584            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12585                throw new SecurityException("Process not debuggable: " + app.packageName);
12586            }
12587        }
12588        mNativeDebuggingApp = processName;
12589    }
12590
12591    @Override
12592    public void setAlwaysFinish(boolean enabled) {
12593        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12594                "setAlwaysFinish()");
12595
12596        long ident = Binder.clearCallingIdentity();
12597        try {
12598            Settings.Global.putInt(
12599                    mContext.getContentResolver(),
12600                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12601
12602            synchronized (this) {
12603                mAlwaysFinishActivities = enabled;
12604            }
12605        } finally {
12606            Binder.restoreCallingIdentity(ident);
12607        }
12608    }
12609
12610    @Override
12611    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12612        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12613                "setActivityController()");
12614        synchronized (this) {
12615            mController = controller;
12616            mControllerIsAMonkey = imAMonkey;
12617            Watchdog.getInstance().setActivityController(controller);
12618        }
12619    }
12620
12621    @Override
12622    public void setUserIsMonkey(boolean userIsMonkey) {
12623        synchronized (this) {
12624            synchronized (mPidsSelfLocked) {
12625                final int callingPid = Binder.getCallingPid();
12626                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12627                if (proc == null) {
12628                    throw new SecurityException("Unknown process: " + callingPid);
12629                }
12630                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12631                    throw new SecurityException("Only an instrumentation process "
12632                            + "with a UiAutomation can call setUserIsMonkey");
12633                }
12634            }
12635            mUserIsMonkey = userIsMonkey;
12636        }
12637    }
12638
12639    @Override
12640    public boolean isUserAMonkey() {
12641        synchronized (this) {
12642            // If there is a controller also implies the user is a monkey.
12643            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12644        }
12645    }
12646
12647    /**
12648     * @deprecated This method is only used by a few internal components and it will soon be
12649     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12650     * No new code should be calling it.
12651     */
12652    @Deprecated
12653    @Override
12654    public void requestBugReport(int bugreportType) {
12655        String extraOptions = null;
12656        switch (bugreportType) {
12657            case ActivityManager.BUGREPORT_OPTION_FULL:
12658                // Default options.
12659                break;
12660            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12661                extraOptions = "bugreportplus";
12662                break;
12663            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12664                extraOptions = "bugreportremote";
12665                break;
12666            case ActivityManager.BUGREPORT_OPTION_WEAR:
12667                extraOptions = "bugreportwear";
12668                break;
12669            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12670                extraOptions = "bugreporttelephony";
12671                break;
12672            default:
12673                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12674                        + bugreportType);
12675        }
12676        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12677        if (extraOptions != null) {
12678            SystemProperties.set("dumpstate.options", extraOptions);
12679        }
12680        SystemProperties.set("ctl.start", "bugreport");
12681    }
12682
12683    /**
12684     * @deprecated This method is only used by a few internal components and it will soon be
12685     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12686     * No new code should be calling it.
12687     */
12688    @Deprecated
12689    @Override
12690    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12691
12692        if (!TextUtils.isEmpty(shareTitle)) {
12693            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12694                String errorStr = "shareTitle should be less than " +
12695                        MAX_BUGREPORT_TITLE_SIZE + " characters";
12696                throw new IllegalArgumentException(errorStr);
12697            } else {
12698                if (!TextUtils.isEmpty(shareDescription)) {
12699                    int length;
12700                    try {
12701                        length = shareDescription.getBytes("UTF-8").length;
12702                    } catch (UnsupportedEncodingException e) {
12703                        String errorStr = "shareDescription: UnsupportedEncodingException";
12704                        throw new IllegalArgumentException(errorStr);
12705                    }
12706                    if (length > SystemProperties.PROP_VALUE_MAX) {
12707                        String errorStr = "shareTitle should be less than " +
12708                                SystemProperties.PROP_VALUE_MAX + " bytes";
12709                        throw new IllegalArgumentException(errorStr);
12710                    } else {
12711                        SystemProperties.set("dumpstate.options.description", shareDescription);
12712                    }
12713                }
12714                SystemProperties.set("dumpstate.options.title", shareTitle);
12715            }
12716        }
12717
12718        Slog.d(TAG, "Bugreport notification title " + shareTitle
12719                + " description " + shareDescription);
12720        requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12721    }
12722
12723    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12724        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12725    }
12726
12727    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12728        if (r != null && (r.instr != null || r.usingWrapper)) {
12729            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12730        }
12731        return KEY_DISPATCHING_TIMEOUT;
12732    }
12733
12734    @Override
12735    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12736        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12737                != PackageManager.PERMISSION_GRANTED) {
12738            throw new SecurityException("Requires permission "
12739                    + android.Manifest.permission.FILTER_EVENTS);
12740        }
12741        ProcessRecord proc;
12742        long timeout;
12743        synchronized (this) {
12744            synchronized (mPidsSelfLocked) {
12745                proc = mPidsSelfLocked.get(pid);
12746            }
12747            timeout = getInputDispatchingTimeoutLocked(proc);
12748        }
12749
12750        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12751            return -1;
12752        }
12753
12754        return timeout;
12755    }
12756
12757    /**
12758     * Handle input dispatching timeouts.
12759     * Returns whether input dispatching should be aborted or not.
12760     */
12761    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12762            final ActivityRecord activity, final ActivityRecord parent,
12763            final boolean aboveSystem, String reason) {
12764        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12765                != PackageManager.PERMISSION_GRANTED) {
12766            throw new SecurityException("Requires permission "
12767                    + android.Manifest.permission.FILTER_EVENTS);
12768        }
12769
12770        final String annotation;
12771        if (reason == null) {
12772            annotation = "Input dispatching timed out";
12773        } else {
12774            annotation = "Input dispatching timed out (" + reason + ")";
12775        }
12776
12777        if (proc != null) {
12778            synchronized (this) {
12779                if (proc.debugging) {
12780                    return false;
12781                }
12782
12783                if (mDidDexOpt) {
12784                    // Give more time since we were dexopting.
12785                    mDidDexOpt = false;
12786                    return false;
12787                }
12788
12789                if (proc.instr != null) {
12790                    Bundle info = new Bundle();
12791                    info.putString("shortMsg", "keyDispatchingTimedOut");
12792                    info.putString("longMsg", annotation);
12793                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12794                    return true;
12795                }
12796            }
12797            mHandler.post(new Runnable() {
12798                @Override
12799                public void run() {
12800                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12801                }
12802            });
12803        }
12804
12805        return true;
12806    }
12807
12808    @Override
12809    public Bundle getAssistContextExtras(int requestType) {
12810        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12811                null, null, true /* focused */, true /* newSessionId */,
12812                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12813        if (pae == null) {
12814            return null;
12815        }
12816        synchronized (pae) {
12817            while (!pae.haveResult) {
12818                try {
12819                    pae.wait();
12820                } catch (InterruptedException e) {
12821                }
12822            }
12823        }
12824        synchronized (this) {
12825            buildAssistBundleLocked(pae, pae.result);
12826            mPendingAssistExtras.remove(pae);
12827            mUiHandler.removeCallbacks(pae);
12828        }
12829        return pae.extras;
12830    }
12831
12832    @Override
12833    public boolean isAssistDataAllowedOnCurrentActivity() {
12834        int userId;
12835        synchronized (this) {
12836            final ActivityStack focusedStack = getFocusedStack();
12837            if (focusedStack == null || focusedStack.isAssistantStack()) {
12838                return false;
12839            }
12840
12841            final ActivityRecord activity = focusedStack.topActivity();
12842            if (activity == null) {
12843                return false;
12844            }
12845            userId = activity.userId;
12846        }
12847        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12848                Context.DEVICE_POLICY_SERVICE);
12849        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12850    }
12851
12852    @Override
12853    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12854        long ident = Binder.clearCallingIdentity();
12855        try {
12856            synchronized (this) {
12857                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12858                ActivityRecord top = getFocusedStack().topActivity();
12859                if (top != caller) {
12860                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12861                            + " is not current top " + top);
12862                    return false;
12863                }
12864                if (!top.nowVisible) {
12865                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12866                            + " is not visible");
12867                    return false;
12868                }
12869            }
12870            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
12871                    token);
12872        } finally {
12873            Binder.restoreCallingIdentity(ident);
12874        }
12875    }
12876
12877    @Override
12878    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12879            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
12880        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12881                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
12882                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
12883    }
12884
12885    @Override
12886    public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
12887            IBinder activityToken, int flags) {
12888        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
12889                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
12890                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
12891    }
12892
12893    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12894            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12895            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
12896            int flags) {
12897        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12898                "enqueueAssistContext()");
12899
12900        synchronized (this) {
12901            ActivityRecord activity = getFocusedStack().topActivity();
12902            if (activity == null) {
12903                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12904                return null;
12905            }
12906            if (activity.app == null || activity.app.thread == null) {
12907                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12908                return null;
12909            }
12910            if (focused) {
12911                if (activityToken != null) {
12912                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12913                    if (activity != caller) {
12914                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12915                                + " is not current top " + activity);
12916                        return null;
12917                    }
12918                }
12919            } else {
12920                activity = ActivityRecord.forTokenLocked(activityToken);
12921                if (activity == null) {
12922                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12923                            + " couldn't be found");
12924                    return null;
12925                }
12926            }
12927
12928            PendingAssistExtras pae;
12929            Bundle extras = new Bundle();
12930            if (args != null) {
12931                extras.putAll(args);
12932            }
12933            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12934            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12935
12936            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12937                    userHandle);
12938            pae.isHome = activity.isHomeActivity();
12939
12940            // Increment the sessionId if necessary
12941            if (newSessionId) {
12942                mViSessionId++;
12943            }
12944            try {
12945                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
12946                        mViSessionId, flags);
12947                mPendingAssistExtras.add(pae);
12948                mUiHandler.postDelayed(pae, timeout);
12949            } catch (RemoteException e) {
12950                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12951                return null;
12952            }
12953            return pae;
12954        }
12955    }
12956
12957    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12958        IResultReceiver receiver;
12959        synchronized (this) {
12960            mPendingAssistExtras.remove(pae);
12961            receiver = pae.receiver;
12962        }
12963        if (receiver != null) {
12964            // Caller wants result sent back to them.
12965            Bundle sendBundle = new Bundle();
12966            // At least return the receiver extras
12967            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12968                    pae.receiverExtras);
12969            try {
12970                pae.receiver.send(0, sendBundle);
12971            } catch (RemoteException e) {
12972            }
12973        }
12974    }
12975
12976    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12977        if (result != null) {
12978            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12979        }
12980        if (pae.hint != null) {
12981            pae.extras.putBoolean(pae.hint, true);
12982        }
12983    }
12984
12985    /** Called from an app when assist data is ready. */
12986    @Override
12987    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12988            AssistContent content, Uri referrer) {
12989        PendingAssistExtras pae = (PendingAssistExtras)token;
12990        synchronized (pae) {
12991            pae.result = extras;
12992            pae.structure = structure;
12993            pae.content = content;
12994            if (referrer != null) {
12995                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12996            }
12997            if (structure != null) {
12998                structure.setHomeActivity(pae.isHome);
12999            }
13000            pae.haveResult = true;
13001            pae.notifyAll();
13002            if (pae.intent == null && pae.receiver == null) {
13003                // Caller is just waiting for the result.
13004                return;
13005            }
13006        }
13007
13008        // We are now ready to launch the assist activity.
13009        IResultReceiver sendReceiver = null;
13010        Bundle sendBundle = null;
13011        synchronized (this) {
13012            buildAssistBundleLocked(pae, extras);
13013            boolean exists = mPendingAssistExtras.remove(pae);
13014            mUiHandler.removeCallbacks(pae);
13015            if (!exists) {
13016                // Timed out.
13017                return;
13018            }
13019            if ((sendReceiver=pae.receiver) != null) {
13020                // Caller wants result sent back to them.
13021                sendBundle = new Bundle();
13022                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13023                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13024                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13025                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13026                        pae.receiverExtras);
13027            }
13028        }
13029        if (sendReceiver != null) {
13030            try {
13031                sendReceiver.send(0, sendBundle);
13032            } catch (RemoteException e) {
13033            }
13034            return;
13035        }
13036
13037        long ident = Binder.clearCallingIdentity();
13038        try {
13039            pae.intent.replaceExtras(pae.extras);
13040            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13041                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
13042                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13043            closeSystemDialogs("assist");
13044            try {
13045                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13046            } catch (ActivityNotFoundException e) {
13047                Slog.w(TAG, "No activity to handle assist action.", e);
13048            }
13049        } finally {
13050            Binder.restoreCallingIdentity(ident);
13051        }
13052    }
13053
13054    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13055            Bundle args) {
13056        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13057                true /* focused */, true /* newSessionId */, userHandle, args,
13058                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13059    }
13060
13061    public void registerProcessObserver(IProcessObserver observer) {
13062        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13063                "registerProcessObserver()");
13064        synchronized (this) {
13065            mProcessObservers.register(observer);
13066        }
13067    }
13068
13069    @Override
13070    public void unregisterProcessObserver(IProcessObserver observer) {
13071        synchronized (this) {
13072            mProcessObservers.unregister(observer);
13073        }
13074    }
13075
13076    @Override
13077    public int getUidProcessState(int uid, String callingPackage) {
13078        if (!hasUsageStatsPermission(callingPackage)) {
13079            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13080                    "getUidProcessState");
13081        }
13082
13083        synchronized (this) {
13084            UidRecord uidRec = mActiveUids.get(uid);
13085            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13086        }
13087    }
13088
13089    @Override
13090    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13091            String callingPackage) {
13092        if (!hasUsageStatsPermission(callingPackage)) {
13093            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13094                    "registerUidObserver");
13095        }
13096        synchronized (this) {
13097            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13098                    callingPackage, which, cutpoint));
13099        }
13100    }
13101
13102    @Override
13103    public void unregisterUidObserver(IUidObserver observer) {
13104        synchronized (this) {
13105            mUidObservers.unregister(observer);
13106        }
13107    }
13108
13109    @Override
13110    public boolean convertFromTranslucent(IBinder token) {
13111        final long origId = Binder.clearCallingIdentity();
13112        try {
13113            synchronized (this) {
13114                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13115                if (r == null) {
13116                    return false;
13117                }
13118                final boolean translucentChanged = r.changeWindowTranslucency(true);
13119                if (translucentChanged) {
13120                    r.getStack().releaseBackgroundResources(r);
13121                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13122                }
13123                mWindowManager.setAppFullscreen(token, true);
13124                return translucentChanged;
13125            }
13126        } finally {
13127            Binder.restoreCallingIdentity(origId);
13128        }
13129    }
13130
13131    @Override
13132    public boolean convertToTranslucent(IBinder token, Bundle options) {
13133        final long origId = Binder.clearCallingIdentity();
13134        try {
13135            synchronized (this) {
13136                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13137                if (r == null) {
13138                    return false;
13139                }
13140                final TaskRecord task = r.getTask();
13141                int index = task.mActivities.lastIndexOf(r);
13142                if (index > 0) {
13143                    ActivityRecord under = task.mActivities.get(index - 1);
13144                    under.returningOptions = ActivityOptions.fromBundle(options);
13145                }
13146                final boolean translucentChanged = r.changeWindowTranslucency(false);
13147                if (translucentChanged) {
13148                    r.getStack().convertActivityToTranslucent(r);
13149                }
13150                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13151                mWindowManager.setAppFullscreen(token, false);
13152                return translucentChanged;
13153            }
13154        } finally {
13155            Binder.restoreCallingIdentity(origId);
13156        }
13157    }
13158
13159    @Override
13160    public boolean requestVisibleBehind(IBinder token, boolean visible) {
13161        final long origId = Binder.clearCallingIdentity();
13162        try {
13163            synchronized (this) {
13164                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13165                if (r != null) {
13166                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13167                }
13168            }
13169            return false;
13170        } finally {
13171            Binder.restoreCallingIdentity(origId);
13172        }
13173    }
13174
13175    @Override
13176    public boolean isBackgroundVisibleBehind(IBinder token) {
13177        final long origId = Binder.clearCallingIdentity();
13178        try {
13179            synchronized (this) {
13180                final ActivityStack stack = ActivityRecord.getStackLocked(token);
13181                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13182                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13183                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13184                return visible;
13185            }
13186        } finally {
13187            Binder.restoreCallingIdentity(origId);
13188        }
13189    }
13190
13191    @Override
13192    public Bundle getActivityOptions(IBinder token) {
13193        final long origId = Binder.clearCallingIdentity();
13194        try {
13195            synchronized (this) {
13196                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13197                if (r != null) {
13198                    final ActivityOptions activityOptions = r.pendingOptions;
13199                    r.pendingOptions = null;
13200                    return activityOptions == null ? null : activityOptions.toBundle();
13201                }
13202                return null;
13203            }
13204        } finally {
13205            Binder.restoreCallingIdentity(origId);
13206        }
13207    }
13208
13209    @Override
13210    public void setImmersive(IBinder token, boolean immersive) {
13211        synchronized(this) {
13212            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13213            if (r == null) {
13214                throw new IllegalArgumentException();
13215            }
13216            r.immersive = immersive;
13217
13218            // update associated state if we're frontmost
13219            if (r == mStackSupervisor.getResumedActivityLocked()) {
13220                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13221                applyUpdateLockStateLocked(r);
13222            }
13223        }
13224    }
13225
13226    @Override
13227    public boolean isImmersive(IBinder token) {
13228        synchronized (this) {
13229            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13230            if (r == null) {
13231                throw new IllegalArgumentException();
13232            }
13233            return r.immersive;
13234        }
13235    }
13236
13237    @Override
13238    public void setVrThread(int tid) {
13239        enforceSystemHasVrFeature();
13240        synchronized (this) {
13241            synchronized (mPidsSelfLocked) {
13242                final int pid = Binder.getCallingPid();
13243                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13244                mVrController.setVrThreadLocked(tid, pid, proc);
13245            }
13246        }
13247    }
13248
13249    @Override
13250    public void setPersistentVrThread(int tid) {
13251        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13252            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13253                    + Binder.getCallingPid()
13254                    + ", uid=" + Binder.getCallingUid()
13255                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13256            Slog.w(TAG, msg);
13257            throw new SecurityException(msg);
13258        }
13259        enforceSystemHasVrFeature();
13260        synchronized (this) {
13261            synchronized (mPidsSelfLocked) {
13262                final int pid = Binder.getCallingPid();
13263                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13264                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13265            }
13266        }
13267    }
13268
13269    /**
13270     * Schedule the given thread a normal scheduling priority.
13271     *
13272     * @param newTid the tid of the thread to adjust the scheduling of.
13273     * @param suppressLogs {@code true} if any error logging should be disabled.
13274     *
13275     * @return {@code true} if this succeeded.
13276     */
13277    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13278        try {
13279            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13280            return true;
13281        } catch (IllegalArgumentException e) {
13282            if (!suppressLogs) {
13283                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13284            }
13285        }
13286        return false;
13287    }
13288
13289    /**
13290     * Schedule the given thread an FIFO scheduling priority.
13291     *
13292     * @param newTid the tid of the thread to adjust the scheduling of.
13293     * @param suppressLogs {@code true} if any error logging should be disabled.
13294     *
13295     * @return {@code true} if this succeeded.
13296     */
13297    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13298        try {
13299            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13300            return true;
13301        } catch (IllegalArgumentException e) {
13302            if (!suppressLogs) {
13303                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13304            }
13305        }
13306        return false;
13307    }
13308
13309    /**
13310     * Check that we have the features required for VR-related API calls, and throw an exception if
13311     * not.
13312     */
13313    private void enforceSystemHasVrFeature() {
13314        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13315            throw new UnsupportedOperationException("VR mode not supported on this device!");
13316        }
13317    }
13318
13319    @Override
13320    public void setRenderThread(int tid) {
13321        synchronized (this) {
13322            ProcessRecord proc;
13323            synchronized (mPidsSelfLocked) {
13324                int pid = Binder.getCallingPid();
13325                proc = mPidsSelfLocked.get(pid);
13326                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13327                    // ensure the tid belongs to the process
13328                    if (!isThreadInProcess(pid, tid)) {
13329                        throw new IllegalArgumentException(
13330                            "Render thread does not belong to process");
13331                    }
13332                    proc.renderThreadTid = tid;
13333                    if (DEBUG_OOM_ADJ) {
13334                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13335                    }
13336                    // promote to FIFO now
13337                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13338                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13339                        if (mUseFifoUiScheduling) {
13340                            setThreadScheduler(proc.renderThreadTid,
13341                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13342                        } else {
13343                            setThreadPriority(proc.renderThreadTid, -10);
13344                        }
13345                    }
13346                } else {
13347                    if (DEBUG_OOM_ADJ) {
13348                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13349                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13350                               mUseFifoUiScheduling);
13351                    }
13352                }
13353            }
13354        }
13355    }
13356
13357    @Override
13358    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13359        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13360            throw new UnsupportedOperationException("VR mode not supported on this device!");
13361        }
13362
13363        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13364
13365        ActivityRecord r;
13366        synchronized (this) {
13367            r = ActivityRecord.isInStackLocked(token);
13368        }
13369
13370        if (r == null) {
13371            throw new IllegalArgumentException();
13372        }
13373
13374        int err;
13375        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13376                VrManagerInternal.NO_ERROR) {
13377            return err;
13378        }
13379
13380        synchronized(this) {
13381            r.requestedVrComponent = (enabled) ? packageName : null;
13382
13383            // Update associated state if this activity is currently focused
13384            if (r == mStackSupervisor.getResumedActivityLocked()) {
13385                applyUpdateVrModeLocked(r);
13386            }
13387            return 0;
13388        }
13389    }
13390
13391    @Override
13392    public boolean isVrModePackageEnabled(ComponentName packageName) {
13393        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13394            throw new UnsupportedOperationException("VR mode not supported on this device!");
13395        }
13396
13397        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13398
13399        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13400                VrManagerInternal.NO_ERROR;
13401    }
13402
13403    public boolean isTopActivityImmersive() {
13404        enforceNotIsolatedCaller("startActivity");
13405        synchronized (this) {
13406            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13407            return (r != null) ? r.immersive : false;
13408        }
13409    }
13410
13411    /**
13412     * @return whether the system should disable UI modes incompatible with VR mode.
13413     */
13414    boolean shouldDisableNonVrUiLocked() {
13415        return mVrController.shouldDisableNonVrUiLocked();
13416    }
13417
13418    @Override
13419    public boolean isTopOfTask(IBinder token) {
13420        synchronized (this) {
13421            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13422            if (r == null) {
13423                throw new IllegalArgumentException();
13424            }
13425            return r.getTask().getTopActivity() == r;
13426        }
13427    }
13428
13429    @Override
13430    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13431        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13432            String msg = "Permission Denial: setHasTopUi() from pid="
13433                    + Binder.getCallingPid()
13434                    + ", uid=" + Binder.getCallingUid()
13435                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13436            Slog.w(TAG, msg);
13437            throw new SecurityException(msg);
13438        }
13439        final int pid = Binder.getCallingPid();
13440        final long origId = Binder.clearCallingIdentity();
13441        try {
13442            synchronized (this) {
13443                boolean changed = false;
13444                ProcessRecord pr;
13445                synchronized (mPidsSelfLocked) {
13446                    pr = mPidsSelfLocked.get(pid);
13447                    if (pr == null) {
13448                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13449                        return;
13450                    }
13451                    if (pr.hasTopUi != hasTopUi) {
13452                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13453                        pr.hasTopUi = hasTopUi;
13454                        changed = true;
13455                    }
13456                }
13457                if (changed) {
13458                    updateOomAdjLocked(pr);
13459                }
13460            }
13461        } finally {
13462            Binder.restoreCallingIdentity(origId);
13463        }
13464    }
13465
13466    public final void enterSafeMode() {
13467        synchronized(this) {
13468            // It only makes sense to do this before the system is ready
13469            // and started launching other packages.
13470            if (!mSystemReady) {
13471                try {
13472                    AppGlobals.getPackageManager().enterSafeMode();
13473                } catch (RemoteException e) {
13474                }
13475            }
13476
13477            mSafeMode = true;
13478        }
13479    }
13480
13481    public final void showSafeModeOverlay() {
13482        View v = LayoutInflater.from(mContext).inflate(
13483                com.android.internal.R.layout.safe_mode, null);
13484        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13485        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13486        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13487        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13488        lp.gravity = Gravity.BOTTOM | Gravity.START;
13489        lp.format = v.getBackground().getOpacity();
13490        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13491                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13492        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13493        ((WindowManager)mContext.getSystemService(
13494                Context.WINDOW_SERVICE)).addView(v, lp);
13495    }
13496
13497    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13498        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13499            return;
13500        }
13501        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13502        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13503        synchronized (stats) {
13504            if (mBatteryStatsService.isOnBattery()) {
13505                mBatteryStatsService.enforceCallingPermission();
13506                int MY_UID = Binder.getCallingUid();
13507                final int uid;
13508                if (sender == null) {
13509                    uid = sourceUid;
13510                } else {
13511                    uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13512                }
13513                BatteryStatsImpl.Uid.Pkg pkg =
13514                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13515                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13516                pkg.noteWakeupAlarmLocked(tag);
13517            }
13518        }
13519    }
13520
13521    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13522        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13523            return;
13524        }
13525        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13526        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13527        synchronized (stats) {
13528            mBatteryStatsService.enforceCallingPermission();
13529            int MY_UID = Binder.getCallingUid();
13530            final int uid;
13531            if (sender == null) {
13532                uid = sourceUid;
13533            } else {
13534                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13535            }
13536            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13537        }
13538    }
13539
13540    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13541        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13542            return;
13543        }
13544        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13545        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13546        synchronized (stats) {
13547            mBatteryStatsService.enforceCallingPermission();
13548            int MY_UID = Binder.getCallingUid();
13549            final int uid;
13550            if (sender == null) {
13551                uid = sourceUid;
13552            } else {
13553                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13554            }
13555            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13556        }
13557    }
13558
13559    public boolean killPids(int[] pids, String pReason, boolean secure) {
13560        if (Binder.getCallingUid() != SYSTEM_UID) {
13561            throw new SecurityException("killPids only available to the system");
13562        }
13563        String reason = (pReason == null) ? "Unknown" : pReason;
13564        // XXX Note: don't acquire main activity lock here, because the window
13565        // manager calls in with its locks held.
13566
13567        boolean killed = false;
13568        synchronized (mPidsSelfLocked) {
13569            int worstType = 0;
13570            for (int i=0; i<pids.length; i++) {
13571                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13572                if (proc != null) {
13573                    int type = proc.setAdj;
13574                    if (type > worstType) {
13575                        worstType = type;
13576                    }
13577                }
13578            }
13579
13580            // If the worst oom_adj is somewhere in the cached proc LRU range,
13581            // then constrain it so we will kill all cached procs.
13582            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13583                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13584                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13585            }
13586
13587            // If this is not a secure call, don't let it kill processes that
13588            // are important.
13589            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13590                worstType = ProcessList.SERVICE_ADJ;
13591            }
13592
13593            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13594            for (int i=0; i<pids.length; i++) {
13595                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13596                if (proc == null) {
13597                    continue;
13598                }
13599                int adj = proc.setAdj;
13600                if (adj >= worstType && !proc.killedByAm) {
13601                    proc.kill(reason, true);
13602                    killed = true;
13603                }
13604            }
13605        }
13606        return killed;
13607    }
13608
13609    @Override
13610    public void killUid(int appId, int userId, String reason) {
13611        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13612        synchronized (this) {
13613            final long identity = Binder.clearCallingIdentity();
13614            try {
13615                killPackageProcessesLocked(null, appId, userId,
13616                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13617                        reason != null ? reason : "kill uid");
13618            } finally {
13619                Binder.restoreCallingIdentity(identity);
13620            }
13621        }
13622    }
13623
13624    @Override
13625    public boolean killProcessesBelowForeground(String reason) {
13626        if (Binder.getCallingUid() != SYSTEM_UID) {
13627            throw new SecurityException("killProcessesBelowForeground() only available to system");
13628        }
13629
13630        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13631    }
13632
13633    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13634        if (Binder.getCallingUid() != SYSTEM_UID) {
13635            throw new SecurityException("killProcessesBelowAdj() only available to system");
13636        }
13637
13638        boolean killed = false;
13639        synchronized (mPidsSelfLocked) {
13640            final int size = mPidsSelfLocked.size();
13641            for (int i = 0; i < size; i++) {
13642                final int pid = mPidsSelfLocked.keyAt(i);
13643                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13644                if (proc == null) continue;
13645
13646                final int adj = proc.setAdj;
13647                if (adj > belowAdj && !proc.killedByAm) {
13648                    proc.kill(reason, true);
13649                    killed = true;
13650                }
13651            }
13652        }
13653        return killed;
13654    }
13655
13656    @Override
13657    public void hang(final IBinder who, boolean allowRestart) {
13658        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13659                != PackageManager.PERMISSION_GRANTED) {
13660            throw new SecurityException("Requires permission "
13661                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13662        }
13663
13664        final IBinder.DeathRecipient death = new DeathRecipient() {
13665            @Override
13666            public void binderDied() {
13667                synchronized (this) {
13668                    notifyAll();
13669                }
13670            }
13671        };
13672
13673        try {
13674            who.linkToDeath(death, 0);
13675        } catch (RemoteException e) {
13676            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13677            return;
13678        }
13679
13680        synchronized (this) {
13681            Watchdog.getInstance().setAllowRestart(allowRestart);
13682            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13683            synchronized (death) {
13684                while (who.isBinderAlive()) {
13685                    try {
13686                        death.wait();
13687                    } catch (InterruptedException e) {
13688                    }
13689                }
13690            }
13691            Watchdog.getInstance().setAllowRestart(true);
13692        }
13693    }
13694
13695    @Override
13696    public void restart() {
13697        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13698                != PackageManager.PERMISSION_GRANTED) {
13699            throw new SecurityException("Requires permission "
13700                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13701        }
13702
13703        Log.i(TAG, "Sending shutdown broadcast...");
13704
13705        BroadcastReceiver br = new BroadcastReceiver() {
13706            @Override public void onReceive(Context context, Intent intent) {
13707                // Now the broadcast is done, finish up the low-level shutdown.
13708                Log.i(TAG, "Shutting down activity manager...");
13709                shutdown(10000);
13710                Log.i(TAG, "Shutdown complete, restarting!");
13711                killProcess(myPid());
13712                System.exit(10);
13713            }
13714        };
13715
13716        // First send the high-level shut down broadcast.
13717        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13718        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13719        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13720        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13721        mContext.sendOrderedBroadcastAsUser(intent,
13722                UserHandle.ALL, null, br, mHandler, 0, null, null);
13723        */
13724        br.onReceive(mContext, intent);
13725    }
13726
13727    private long getLowRamTimeSinceIdle(long now) {
13728        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13729    }
13730
13731    @Override
13732    public void performIdleMaintenance() {
13733        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13734                != PackageManager.PERMISSION_GRANTED) {
13735            throw new SecurityException("Requires permission "
13736                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13737        }
13738
13739        synchronized (this) {
13740            final long now = SystemClock.uptimeMillis();
13741            final long timeSinceLastIdle = now - mLastIdleTime;
13742            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13743            mLastIdleTime = now;
13744            mLowRamTimeSinceLastIdle = 0;
13745            if (mLowRamStartTime != 0) {
13746                mLowRamStartTime = now;
13747            }
13748
13749            StringBuilder sb = new StringBuilder(128);
13750            sb.append("Idle maintenance over ");
13751            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13752            sb.append(" low RAM for ");
13753            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13754            Slog.i(TAG, sb.toString());
13755
13756            // If at least 1/3 of our time since the last idle period has been spent
13757            // with RAM low, then we want to kill processes.
13758            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13759
13760            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13761                ProcessRecord proc = mLruProcesses.get(i);
13762                if (proc.notCachedSinceIdle) {
13763                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13764                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13765                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13766                        if (doKilling && proc.initialIdlePss != 0
13767                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13768                            sb = new StringBuilder(128);
13769                            sb.append("Kill");
13770                            sb.append(proc.processName);
13771                            sb.append(" in idle maint: pss=");
13772                            sb.append(proc.lastPss);
13773                            sb.append(", swapPss=");
13774                            sb.append(proc.lastSwapPss);
13775                            sb.append(", initialPss=");
13776                            sb.append(proc.initialIdlePss);
13777                            sb.append(", period=");
13778                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13779                            sb.append(", lowRamPeriod=");
13780                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13781                            Slog.wtfQuiet(TAG, sb.toString());
13782                            proc.kill("idle maint (pss " + proc.lastPss
13783                                    + " from " + proc.initialIdlePss + ")", true);
13784                        }
13785                    }
13786                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13787                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13788                    proc.notCachedSinceIdle = true;
13789                    proc.initialIdlePss = 0;
13790                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13791                            mTestPssMode, isSleepingLocked(), now);
13792                }
13793            }
13794
13795            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13796            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13797        }
13798    }
13799
13800    @Override
13801    public void sendIdleJobTrigger() {
13802        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13803                != PackageManager.PERMISSION_GRANTED) {
13804            throw new SecurityException("Requires permission "
13805                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13806        }
13807
13808        final long ident = Binder.clearCallingIdentity();
13809        try {
13810            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13811                    .setPackage("android")
13812                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13813            broadcastIntent(null, intent, null, null, 0, null, null, null,
13814                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13815        } finally {
13816            Binder.restoreCallingIdentity(ident);
13817        }
13818    }
13819
13820    private void retrieveSettings() {
13821        final ContentResolver resolver = mContext.getContentResolver();
13822        final boolean freeformWindowManagement =
13823                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13824                        || Settings.Global.getInt(
13825                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13826        final boolean supportsPictureInPicture =
13827                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13828
13829        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13830        final boolean supportsSplitScreenMultiWindow =
13831                ActivityManager.supportsSplitScreenMultiWindow();
13832        final boolean supportsMultiDisplay = mContext.getPackageManager()
13833                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
13834        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13835        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13836        final boolean alwaysFinishActivities =
13837                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13838        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13839        final boolean forceResizable = Settings.Global.getInt(
13840                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13841        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
13842                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
13843        final boolean supportsLeanbackOnly =
13844                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13845
13846        // Transfer any global setting for forcing RTL layout, into a System Property
13847        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13848
13849        final Configuration configuration = new Configuration();
13850        Settings.System.getConfiguration(resolver, configuration);
13851        if (forceRtl) {
13852            // This will take care of setting the correct layout direction flags
13853            configuration.setLayoutDirection(configuration.locale);
13854        }
13855
13856        synchronized (this) {
13857            mDebugApp = mOrigDebugApp = debugApp;
13858            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13859            mAlwaysFinishActivities = alwaysFinishActivities;
13860            mSupportsLeanbackOnly = supportsLeanbackOnly;
13861            mForceResizableActivities = forceResizable;
13862            if (supportsMultiWindow || forceResizable) {
13863                mSupportsMultiWindow = true;
13864                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13865            } else {
13866                mSupportsMultiWindow = false;
13867                mSupportsFreeformWindowManagement = false;
13868            }
13869            mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13870            mSupportsPictureInPicture = supportsPictureInPicture;
13871            mSupportsMultiDisplay = supportsMultiDisplay;
13872            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13873            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13874            // This happens before any activities are started, so we can change global configuration
13875            // in-place.
13876            updateConfigurationLocked(configuration, null, true);
13877            final Configuration globalConfig = getGlobalConfiguration();
13878            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13879
13880            // Load resources only after the current configuration has been set.
13881            final Resources res = mContext.getResources();
13882            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13883            mThumbnailWidth = res.getDimensionPixelSize(
13884                    com.android.internal.R.dimen.thumbnail_width);
13885            mThumbnailHeight = res.getDimensionPixelSize(
13886                    com.android.internal.R.dimen.thumbnail_height);
13887            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13888                    com.android.internal.R.string.config_appsNotReportingCrashes));
13889            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13890                    com.android.internal.R.bool.config_customUserSwitchUi);
13891            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13892                mFullscreenThumbnailScale = (float) res
13893                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13894                    (float) globalConfig.screenWidthDp;
13895            } else {
13896                mFullscreenThumbnailScale = res.getFraction(
13897                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13898            }
13899            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
13900        }
13901    }
13902
13903    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
13904        traceLog.traceBegin("PhaseActivityManagerReady");
13905        synchronized(this) {
13906            if (mSystemReady) {
13907                // If we're done calling all the receivers, run the next "boot phase" passed in
13908                // by the SystemServer
13909                if (goingCallback != null) {
13910                    goingCallback.run();
13911                }
13912                return;
13913            }
13914
13915            mLocalDeviceIdleController
13916                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13917            mAssistUtils = new AssistUtils(mContext);
13918            mVrController.onSystemReady();
13919            // Make sure we have the current profile info, since it is needed for security checks.
13920            mUserController.onSystemReady();
13921            mRecentTasks.onSystemReadyLocked();
13922            mAppOpsService.systemReady();
13923            mSystemReady = true;
13924        }
13925
13926        ArrayList<ProcessRecord> procsToKill = null;
13927        synchronized(mPidsSelfLocked) {
13928            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13929                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13930                if (!isAllowedWhileBooting(proc.info)){
13931                    if (procsToKill == null) {
13932                        procsToKill = new ArrayList<ProcessRecord>();
13933                    }
13934                    procsToKill.add(proc);
13935                }
13936            }
13937        }
13938
13939        synchronized(this) {
13940            if (procsToKill != null) {
13941                for (int i=procsToKill.size()-1; i>=0; i--) {
13942                    ProcessRecord proc = procsToKill.get(i);
13943                    Slog.i(TAG, "Removing system update proc: " + proc);
13944                    removeProcessLocked(proc, true, false, "system update done");
13945                }
13946            }
13947
13948            // Now that we have cleaned up any update processes, we
13949            // are ready to start launching real processes and know that
13950            // we won't trample on them any more.
13951            mProcessesReady = true;
13952        }
13953
13954        Slog.i(TAG, "System now ready");
13955        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13956            SystemClock.uptimeMillis());
13957
13958        synchronized(this) {
13959            // Make sure we have no pre-ready processes sitting around.
13960
13961            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13962                ResolveInfo ri = mContext.getPackageManager()
13963                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13964                                STOCK_PM_FLAGS);
13965                CharSequence errorMsg = null;
13966                if (ri != null) {
13967                    ActivityInfo ai = ri.activityInfo;
13968                    ApplicationInfo app = ai.applicationInfo;
13969                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13970                        mTopAction = Intent.ACTION_FACTORY_TEST;
13971                        mTopData = null;
13972                        mTopComponent = new ComponentName(app.packageName,
13973                                ai.name);
13974                    } else {
13975                        errorMsg = mContext.getResources().getText(
13976                                com.android.internal.R.string.factorytest_not_system);
13977                    }
13978                } else {
13979                    errorMsg = mContext.getResources().getText(
13980                            com.android.internal.R.string.factorytest_no_action);
13981                }
13982                if (errorMsg != null) {
13983                    mTopAction = null;
13984                    mTopData = null;
13985                    mTopComponent = null;
13986                    Message msg = Message.obtain();
13987                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13988                    msg.getData().putCharSequence("msg", errorMsg);
13989                    mUiHandler.sendMessage(msg);
13990                }
13991            }
13992        }
13993
13994        retrieveSettings();
13995        final int currentUserId;
13996        synchronized (this) {
13997            currentUserId = mUserController.getCurrentUserIdLocked();
13998            readGrantedUriPermissionsLocked();
13999        }
14000
14001        if (goingCallback != null) goingCallback.run();
14002        traceLog.traceBegin("ActivityManagerStartApps");
14003        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14004                Integer.toString(currentUserId), currentUserId);
14005        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14006                Integer.toString(currentUserId), currentUserId);
14007        mSystemServiceManager.startUser(currentUserId);
14008
14009        synchronized (this) {
14010            // Only start up encryption-aware persistent apps; once user is
14011            // unlocked we'll come back around and start unaware apps
14012            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14013
14014            // Start up initial activity.
14015            mBooting = true;
14016            // Enable home activity for system user, so that the system can always boot. We don't
14017            // do this when the system user is not setup since the setup wizard should be the one
14018            // to handle home activity in this case.
14019            if (UserManager.isSplitSystemUser() &&
14020                    Settings.Secure.getInt(mContext.getContentResolver(),
14021                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14022                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14023                try {
14024                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14025                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14026                            UserHandle.USER_SYSTEM);
14027                } catch (RemoteException e) {
14028                    throw e.rethrowAsRuntimeException();
14029                }
14030            }
14031            startHomeActivityLocked(currentUserId, "systemReady");
14032
14033            try {
14034                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14035                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14036                            + " data partition or your device will be unstable.");
14037                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14038                }
14039            } catch (RemoteException e) {
14040            }
14041
14042            if (!Build.isBuildConsistent()) {
14043                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14044                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14045            }
14046
14047            long ident = Binder.clearCallingIdentity();
14048            try {
14049                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14050                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14051                        | Intent.FLAG_RECEIVER_FOREGROUND);
14052                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14053                broadcastIntentLocked(null, null, intent,
14054                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14055                        null, false, false, MY_PID, SYSTEM_UID,
14056                        currentUserId);
14057                intent = new Intent(Intent.ACTION_USER_STARTING);
14058                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14059                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14060                broadcastIntentLocked(null, null, intent,
14061                        null, new IIntentReceiver.Stub() {
14062                            @Override
14063                            public void performReceive(Intent intent, int resultCode, String data,
14064                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14065                                    throws RemoteException {
14066                            }
14067                        }, 0, null, null,
14068                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14069                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14070            } catch (Throwable t) {
14071                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14072            } finally {
14073                Binder.restoreCallingIdentity(ident);
14074            }
14075            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14076            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14077            traceLog.traceEnd(); // ActivityManagerStartApps
14078            traceLog.traceEnd(); // PhaseActivityManagerReady
14079        }
14080    }
14081
14082    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14083        synchronized (this) {
14084            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14085        }
14086    }
14087
14088    void skipCurrentReceiverLocked(ProcessRecord app) {
14089        for (BroadcastQueue queue : mBroadcastQueues) {
14090            queue.skipCurrentReceiverLocked(app);
14091        }
14092    }
14093
14094    /**
14095     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14096     * The application process will exit immediately after this call returns.
14097     * @param app object of the crashing app, null for the system server
14098     * @param crashInfo describing the exception
14099     */
14100    public void handleApplicationCrash(IBinder app,
14101            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14102        ProcessRecord r = findAppProcess(app, "Crash");
14103        final String processName = app == null ? "system_server"
14104                : (r == null ? "unknown" : r.processName);
14105
14106        handleApplicationCrashInner("crash", r, processName, crashInfo);
14107    }
14108
14109    /* Native crash reporting uses this inner version because it needs to be somewhat
14110     * decoupled from the AM-managed cleanup lifecycle
14111     */
14112    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14113            ApplicationErrorReport.CrashInfo crashInfo) {
14114        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14115                UserHandle.getUserId(Binder.getCallingUid()), processName,
14116                r == null ? -1 : r.info.flags,
14117                crashInfo.exceptionClassName,
14118                crashInfo.exceptionMessage,
14119                crashInfo.throwFileName,
14120                crashInfo.throwLineNumber);
14121
14122        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14123
14124        mAppErrors.crashApplication(r, crashInfo);
14125    }
14126
14127    public void handleApplicationStrictModeViolation(
14128            IBinder app,
14129            int violationMask,
14130            StrictMode.ViolationInfo info) {
14131        ProcessRecord r = findAppProcess(app, "StrictMode");
14132        if (r == null) {
14133            return;
14134        }
14135
14136        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14137            Integer stackFingerprint = info.hashCode();
14138            boolean logIt = true;
14139            synchronized (mAlreadyLoggedViolatedStacks) {
14140                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14141                    logIt = false;
14142                    // TODO: sub-sample into EventLog for these, with
14143                    // the info.durationMillis?  Then we'd get
14144                    // the relative pain numbers, without logging all
14145                    // the stack traces repeatedly.  We'd want to do
14146                    // likewise in the client code, which also does
14147                    // dup suppression, before the Binder call.
14148                } else {
14149                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14150                        mAlreadyLoggedViolatedStacks.clear();
14151                    }
14152                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14153                }
14154            }
14155            if (logIt) {
14156                logStrictModeViolationToDropBox(r, info);
14157            }
14158        }
14159
14160        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14161            AppErrorResult result = new AppErrorResult();
14162            synchronized (this) {
14163                final long origId = Binder.clearCallingIdentity();
14164
14165                Message msg = Message.obtain();
14166                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14167                HashMap<String, Object> data = new HashMap<String, Object>();
14168                data.put("result", result);
14169                data.put("app", r);
14170                data.put("violationMask", violationMask);
14171                data.put("info", info);
14172                msg.obj = data;
14173                mUiHandler.sendMessage(msg);
14174
14175                Binder.restoreCallingIdentity(origId);
14176            }
14177            int res = result.get();
14178            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14179        }
14180    }
14181
14182    // Depending on the policy in effect, there could be a bunch of
14183    // these in quick succession so we try to batch these together to
14184    // minimize disk writes, number of dropbox entries, and maximize
14185    // compression, by having more fewer, larger records.
14186    private void logStrictModeViolationToDropBox(
14187            ProcessRecord process,
14188            StrictMode.ViolationInfo info) {
14189        if (info == null) {
14190            return;
14191        }
14192        final boolean isSystemApp = process == null ||
14193                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14194                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14195        final String processName = process == null ? "unknown" : process.processName;
14196        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14197        final DropBoxManager dbox = (DropBoxManager)
14198                mContext.getSystemService(Context.DROPBOX_SERVICE);
14199
14200        // Exit early if the dropbox isn't configured to accept this report type.
14201        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14202
14203        boolean bufferWasEmpty;
14204        boolean needsFlush;
14205        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14206        synchronized (sb) {
14207            bufferWasEmpty = sb.length() == 0;
14208            appendDropBoxProcessHeaders(process, processName, sb);
14209            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14210            sb.append("System-App: ").append(isSystemApp).append("\n");
14211            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14212            if (info.violationNumThisLoop != 0) {
14213                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14214            }
14215            if (info.numAnimationsRunning != 0) {
14216                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14217            }
14218            if (info.broadcastIntentAction != null) {
14219                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14220            }
14221            if (info.durationMillis != -1) {
14222                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14223            }
14224            if (info.numInstances != -1) {
14225                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14226            }
14227            if (info.tags != null) {
14228                for (String tag : info.tags) {
14229                    sb.append("Span-Tag: ").append(tag).append("\n");
14230                }
14231            }
14232            sb.append("\n");
14233            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14234                sb.append(info.crashInfo.stackTrace);
14235                sb.append("\n");
14236            }
14237            if (info.message != null) {
14238                sb.append(info.message);
14239                sb.append("\n");
14240            }
14241
14242            // Only buffer up to ~64k.  Various logging bits truncate
14243            // things at 128k.
14244            needsFlush = (sb.length() > 64 * 1024);
14245        }
14246
14247        // Flush immediately if the buffer's grown too large, or this
14248        // is a non-system app.  Non-system apps are isolated with a
14249        // different tag & policy and not batched.
14250        //
14251        // Batching is useful during internal testing with
14252        // StrictMode settings turned up high.  Without batching,
14253        // thousands of separate files could be created on boot.
14254        if (!isSystemApp || needsFlush) {
14255            new Thread("Error dump: " + dropboxTag) {
14256                @Override
14257                public void run() {
14258                    String report;
14259                    synchronized (sb) {
14260                        report = sb.toString();
14261                        sb.delete(0, sb.length());
14262                        sb.trimToSize();
14263                    }
14264                    if (report.length() != 0) {
14265                        dbox.addText(dropboxTag, report);
14266                    }
14267                }
14268            }.start();
14269            return;
14270        }
14271
14272        // System app batching:
14273        if (!bufferWasEmpty) {
14274            // An existing dropbox-writing thread is outstanding, so
14275            // we don't need to start it up.  The existing thread will
14276            // catch the buffer appends we just did.
14277            return;
14278        }
14279
14280        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14281        // (After this point, we shouldn't access AMS internal data structures.)
14282        new Thread("Error dump: " + dropboxTag) {
14283            @Override
14284            public void run() {
14285                // 5 second sleep to let stacks arrive and be batched together
14286                try {
14287                    Thread.sleep(5000);  // 5 seconds
14288                } catch (InterruptedException e) {}
14289
14290                String errorReport;
14291                synchronized (mStrictModeBuffer) {
14292                    errorReport = mStrictModeBuffer.toString();
14293                    if (errorReport.length() == 0) {
14294                        return;
14295                    }
14296                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14297                    mStrictModeBuffer.trimToSize();
14298                }
14299                dbox.addText(dropboxTag, errorReport);
14300            }
14301        }.start();
14302    }
14303
14304    /**
14305     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14306     * @param app object of the crashing app, null for the system server
14307     * @param tag reported by the caller
14308     * @param system whether this wtf is coming from the system
14309     * @param crashInfo describing the context of the error
14310     * @return true if the process should exit immediately (WTF is fatal)
14311     */
14312    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14313            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14314        final int callingUid = Binder.getCallingUid();
14315        final int callingPid = Binder.getCallingPid();
14316
14317        if (system) {
14318            // If this is coming from the system, we could very well have low-level
14319            // system locks held, so we want to do this all asynchronously.  And we
14320            // never want this to become fatal, so there is that too.
14321            mHandler.post(new Runnable() {
14322                @Override public void run() {
14323                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14324                }
14325            });
14326            return false;
14327        }
14328
14329        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14330                crashInfo);
14331
14332        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14333                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14334        final boolean isSystem = (r == null) || r.persistent;
14335
14336        if (isFatal && !isSystem) {
14337            mAppErrors.crashApplication(r, crashInfo);
14338            return true;
14339        } else {
14340            return false;
14341        }
14342    }
14343
14344    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14345            final ApplicationErrorReport.CrashInfo crashInfo) {
14346        final ProcessRecord r = findAppProcess(app, "WTF");
14347        final String processName = app == null ? "system_server"
14348                : (r == null ? "unknown" : r.processName);
14349
14350        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14351                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14352
14353        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14354
14355        return r;
14356    }
14357
14358    /**
14359     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14360     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14361     */
14362    private ProcessRecord findAppProcess(IBinder app, String reason) {
14363        if (app == null) {
14364            return null;
14365        }
14366
14367        synchronized (this) {
14368            final int NP = mProcessNames.getMap().size();
14369            for (int ip=0; ip<NP; ip++) {
14370                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14371                final int NA = apps.size();
14372                for (int ia=0; ia<NA; ia++) {
14373                    ProcessRecord p = apps.valueAt(ia);
14374                    if (p.thread != null && p.thread.asBinder() == app) {
14375                        return p;
14376                    }
14377                }
14378            }
14379
14380            Slog.w(TAG, "Can't find mystery application for " + reason
14381                    + " from pid=" + Binder.getCallingPid()
14382                    + " uid=" + Binder.getCallingUid() + ": " + app);
14383            return null;
14384        }
14385    }
14386
14387    /**
14388     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14389     * to append various headers to the dropbox log text.
14390     */
14391    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14392            StringBuilder sb) {
14393        // Watchdog thread ends up invoking this function (with
14394        // a null ProcessRecord) to add the stack file to dropbox.
14395        // Do not acquire a lock on this (am) in such cases, as it
14396        // could cause a potential deadlock, if and when watchdog
14397        // is invoked due to unavailability of lock on am and it
14398        // would prevent watchdog from killing system_server.
14399        if (process == null) {
14400            sb.append("Process: ").append(processName).append("\n");
14401            return;
14402        }
14403        // Note: ProcessRecord 'process' is guarded by the service
14404        // instance.  (notably process.pkgList, which could otherwise change
14405        // concurrently during execution of this method)
14406        synchronized (this) {
14407            sb.append("Process: ").append(processName).append("\n");
14408            sb.append("PID: ").append(process.pid).append("\n");
14409            int flags = process.info.flags;
14410            IPackageManager pm = AppGlobals.getPackageManager();
14411            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14412            for (int ip=0; ip<process.pkgList.size(); ip++) {
14413                String pkg = process.pkgList.keyAt(ip);
14414                sb.append("Package: ").append(pkg);
14415                try {
14416                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14417                    if (pi != null) {
14418                        sb.append(" v").append(pi.versionCode);
14419                        if (pi.versionName != null) {
14420                            sb.append(" (").append(pi.versionName).append(")");
14421                        }
14422                    }
14423                } catch (RemoteException e) {
14424                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14425                }
14426                sb.append("\n");
14427            }
14428        }
14429    }
14430
14431    private static String processClass(ProcessRecord process) {
14432        if (process == null || process.pid == MY_PID) {
14433            return "system_server";
14434        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14435            return "system_app";
14436        } else {
14437            return "data_app";
14438        }
14439    }
14440
14441    private volatile long mWtfClusterStart;
14442    private volatile int mWtfClusterCount;
14443
14444    /**
14445     * Write a description of an error (crash, WTF, ANR) to the drop box.
14446     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14447     * @param process which caused the error, null means the system server
14448     * @param activity which triggered the error, null if unknown
14449     * @param parent activity related to the error, null if unknown
14450     * @param subject line related to the error, null if absent
14451     * @param report in long form describing the error, null if absent
14452     * @param dataFile text file to include in the report, null if none
14453     * @param crashInfo giving an application stack trace, null if absent
14454     */
14455    public void addErrorToDropBox(String eventType,
14456            ProcessRecord process, String processName, ActivityRecord activity,
14457            ActivityRecord parent, String subject,
14458            final String report, final File dataFile,
14459            final ApplicationErrorReport.CrashInfo crashInfo) {
14460        // NOTE -- this must never acquire the ActivityManagerService lock,
14461        // otherwise the watchdog may be prevented from resetting the system.
14462
14463        // Bail early if not published yet
14464        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14465        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14466
14467        // Exit early if the dropbox isn't configured to accept this report type.
14468        final String dropboxTag = processClass(process) + "_" + eventType;
14469        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14470
14471        // Rate-limit how often we're willing to do the heavy lifting below to
14472        // collect and record logs; currently 5 logs per 10 second period.
14473        final long now = SystemClock.elapsedRealtime();
14474        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14475            mWtfClusterStart = now;
14476            mWtfClusterCount = 1;
14477        } else {
14478            if (mWtfClusterCount++ >= 5) return;
14479        }
14480
14481        final StringBuilder sb = new StringBuilder(1024);
14482        appendDropBoxProcessHeaders(process, processName, sb);
14483        if (process != null) {
14484            sb.append("Foreground: ")
14485                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14486                    .append("\n");
14487        }
14488        if (activity != null) {
14489            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14490        }
14491        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14492            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14493        }
14494        if (parent != null && parent != activity) {
14495            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14496        }
14497        if (subject != null) {
14498            sb.append("Subject: ").append(subject).append("\n");
14499        }
14500        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14501        if (Debug.isDebuggerConnected()) {
14502            sb.append("Debugger: Connected\n");
14503        }
14504        sb.append("\n");
14505
14506        // Do the rest in a worker thread to avoid blocking the caller on I/O
14507        // (After this point, we shouldn't access AMS internal data structures.)
14508        Thread worker = new Thread("Error dump: " + dropboxTag) {
14509            @Override
14510            public void run() {
14511                if (report != null) {
14512                    sb.append(report);
14513                }
14514
14515                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14516                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14517                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14518                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14519
14520                if (dataFile != null && maxDataFileSize > 0) {
14521                    try {
14522                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14523                                    "\n\n[[TRUNCATED]]"));
14524                    } catch (IOException e) {
14525                        Slog.e(TAG, "Error reading " + dataFile, e);
14526                    }
14527                }
14528                if (crashInfo != null && crashInfo.stackTrace != null) {
14529                    sb.append(crashInfo.stackTrace);
14530                }
14531
14532                if (lines > 0) {
14533                    sb.append("\n");
14534
14535                    // Merge several logcat streams, and take the last N lines
14536                    InputStreamReader input = null;
14537                    try {
14538                        java.lang.Process logcat = new ProcessBuilder(
14539                                "/system/bin/timeout", "-k", "15s", "10s",
14540                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14541                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14542                                        .redirectErrorStream(true).start();
14543
14544                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14545                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14546                        input = new InputStreamReader(logcat.getInputStream());
14547
14548                        int num;
14549                        char[] buf = new char[8192];
14550                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14551                    } catch (IOException e) {
14552                        Slog.e(TAG, "Error running logcat", e);
14553                    } finally {
14554                        if (input != null) try { input.close(); } catch (IOException e) {}
14555                    }
14556                }
14557
14558                dbox.addText(dropboxTag, sb.toString());
14559            }
14560        };
14561
14562        if (process == null) {
14563            // If process is null, we are being called from some internal code
14564            // and may be about to die -- run this synchronously.
14565            worker.run();
14566        } else {
14567            worker.start();
14568        }
14569    }
14570
14571    @Override
14572    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14573        enforceNotIsolatedCaller("getProcessesInErrorState");
14574        // assume our apps are happy - lazy create the list
14575        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14576
14577        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14578                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14579        int userId = UserHandle.getUserId(Binder.getCallingUid());
14580
14581        synchronized (this) {
14582
14583            // iterate across all processes
14584            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14585                ProcessRecord app = mLruProcesses.get(i);
14586                if (!allUsers && app.userId != userId) {
14587                    continue;
14588                }
14589                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14590                    // This one's in trouble, so we'll generate a report for it
14591                    // crashes are higher priority (in case there's a crash *and* an anr)
14592                    ActivityManager.ProcessErrorStateInfo report = null;
14593                    if (app.crashing) {
14594                        report = app.crashingReport;
14595                    } else if (app.notResponding) {
14596                        report = app.notRespondingReport;
14597                    }
14598
14599                    if (report != null) {
14600                        if (errList == null) {
14601                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14602                        }
14603                        errList.add(report);
14604                    } else {
14605                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14606                                " crashing = " + app.crashing +
14607                                " notResponding = " + app.notResponding);
14608                    }
14609                }
14610            }
14611        }
14612
14613        return errList;
14614    }
14615
14616    static int procStateToImportance(int procState, int memAdj,
14617            ActivityManager.RunningAppProcessInfo currApp,
14618            int clientTargetSdk) {
14619        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14620                procState, clientTargetSdk);
14621        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14622            currApp.lru = memAdj;
14623        } else {
14624            currApp.lru = 0;
14625        }
14626        return imp;
14627    }
14628
14629    private void fillInProcMemInfo(ProcessRecord app,
14630            ActivityManager.RunningAppProcessInfo outInfo,
14631            int clientTargetSdk) {
14632        outInfo.pid = app.pid;
14633        outInfo.uid = app.info.uid;
14634        if (mHeavyWeightProcess == app) {
14635            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14636        }
14637        if (app.persistent) {
14638            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14639        }
14640        if (app.activities.size() > 0) {
14641            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14642        }
14643        outInfo.lastTrimLevel = app.trimMemoryLevel;
14644        int adj = app.curAdj;
14645        int procState = app.curProcState;
14646        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14647        outInfo.importanceReasonCode = app.adjTypeCode;
14648        outInfo.processState = app.curProcState;
14649    }
14650
14651    @Override
14652    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14653        enforceNotIsolatedCaller("getRunningAppProcesses");
14654
14655        final int callingUid = Binder.getCallingUid();
14656        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14657
14658        // Lazy instantiation of list
14659        List<ActivityManager.RunningAppProcessInfo> runList = null;
14660        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14661                callingUid) == PackageManager.PERMISSION_GRANTED;
14662        final int userId = UserHandle.getUserId(callingUid);
14663        final boolean allUids = isGetTasksAllowed(
14664                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14665
14666        synchronized (this) {
14667            // Iterate across all processes
14668            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14669                ProcessRecord app = mLruProcesses.get(i);
14670                if ((!allUsers && app.userId != userId)
14671                        || (!allUids && app.uid != callingUid)) {
14672                    continue;
14673                }
14674                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14675                    // Generate process state info for running application
14676                    ActivityManager.RunningAppProcessInfo currApp =
14677                        new ActivityManager.RunningAppProcessInfo(app.processName,
14678                                app.pid, app.getPackageList());
14679                    fillInProcMemInfo(app, currApp, clientTargetSdk);
14680                    if (app.adjSource instanceof ProcessRecord) {
14681                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14682                        currApp.importanceReasonImportance =
14683                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14684                                        app.adjSourceProcState);
14685                    } else if (app.adjSource instanceof ActivityRecord) {
14686                        ActivityRecord r = (ActivityRecord)app.adjSource;
14687                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14688                    }
14689                    if (app.adjTarget instanceof ComponentName) {
14690                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14691                    }
14692                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14693                    //        + " lru=" + currApp.lru);
14694                    if (runList == null) {
14695                        runList = new ArrayList<>();
14696                    }
14697                    runList.add(currApp);
14698                }
14699            }
14700        }
14701        return runList;
14702    }
14703
14704    @Override
14705    public List<ApplicationInfo> getRunningExternalApplications() {
14706        enforceNotIsolatedCaller("getRunningExternalApplications");
14707        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14708        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14709        if (runningApps != null && runningApps.size() > 0) {
14710            Set<String> extList = new HashSet<String>();
14711            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14712                if (app.pkgList != null) {
14713                    for (String pkg : app.pkgList) {
14714                        extList.add(pkg);
14715                    }
14716                }
14717            }
14718            IPackageManager pm = AppGlobals.getPackageManager();
14719            for (String pkg : extList) {
14720                try {
14721                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14722                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14723                        retList.add(info);
14724                    }
14725                } catch (RemoteException e) {
14726                }
14727            }
14728        }
14729        return retList;
14730    }
14731
14732    @Override
14733    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14734        enforceNotIsolatedCaller("getMyMemoryState");
14735
14736        final int callingUid = Binder.getCallingUid();
14737        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14738
14739        synchronized (this) {
14740            ProcessRecord proc;
14741            synchronized (mPidsSelfLocked) {
14742                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14743            }
14744            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14745        }
14746    }
14747
14748    @Override
14749    public int getMemoryTrimLevel() {
14750        enforceNotIsolatedCaller("getMyMemoryState");
14751        synchronized (this) {
14752            return mLastMemoryLevel;
14753        }
14754    }
14755
14756    @Override
14757    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14758            FileDescriptor err, String[] args, ShellCallback callback,
14759            ResultReceiver resultReceiver) {
14760        (new ActivityManagerShellCommand(this, false)).exec(
14761                this, in, out, err, args, callback, resultReceiver);
14762    }
14763
14764    @Override
14765    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14766        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
14767
14768        boolean dumpAll = false;
14769        boolean dumpClient = false;
14770        boolean dumpCheckin = false;
14771        boolean dumpCheckinFormat = false;
14772        boolean dumpVisibleStacksOnly = false;
14773        boolean dumpFocusedStackOnly = false;
14774        String dumpPackage = null;
14775
14776        int opti = 0;
14777        while (opti < args.length) {
14778            String opt = args[opti];
14779            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14780                break;
14781            }
14782            opti++;
14783            if ("-a".equals(opt)) {
14784                dumpAll = true;
14785            } else if ("-c".equals(opt)) {
14786                dumpClient = true;
14787            } else if ("-v".equals(opt)) {
14788                dumpVisibleStacksOnly = true;
14789            } else if ("-f".equals(opt)) {
14790                dumpFocusedStackOnly = true;
14791            } else if ("-p".equals(opt)) {
14792                if (opti < args.length) {
14793                    dumpPackage = args[opti];
14794                    opti++;
14795                } else {
14796                    pw.println("Error: -p option requires package argument");
14797                    return;
14798                }
14799                dumpClient = true;
14800            } else if ("--checkin".equals(opt)) {
14801                dumpCheckin = dumpCheckinFormat = true;
14802            } else if ("-C".equals(opt)) {
14803                dumpCheckinFormat = true;
14804            } else if ("-h".equals(opt)) {
14805                ActivityManagerShellCommand.dumpHelp(pw, true);
14806                return;
14807            } else {
14808                pw.println("Unknown argument: " + opt + "; use -h for help");
14809            }
14810        }
14811
14812        long origId = Binder.clearCallingIdentity();
14813        boolean more = false;
14814        // Is the caller requesting to dump a particular piece of data?
14815        if (opti < args.length) {
14816            String cmd = args[opti];
14817            opti++;
14818            if ("activities".equals(cmd) || "a".equals(cmd)) {
14819                synchronized (this) {
14820                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14821                }
14822            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14823                synchronized (this) {
14824                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14825                }
14826            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14827                String[] newArgs;
14828                String name;
14829                if (opti >= args.length) {
14830                    name = null;
14831                    newArgs = EMPTY_STRING_ARRAY;
14832                } else {
14833                    dumpPackage = args[opti];
14834                    opti++;
14835                    newArgs = new String[args.length - opti];
14836                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14837                            args.length - opti);
14838                }
14839                synchronized (this) {
14840                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14841                }
14842            } else if ("broadcast-stats".equals(cmd)) {
14843                String[] newArgs;
14844                String name;
14845                if (opti >= args.length) {
14846                    name = null;
14847                    newArgs = EMPTY_STRING_ARRAY;
14848                } else {
14849                    dumpPackage = args[opti];
14850                    opti++;
14851                    newArgs = new String[args.length - opti];
14852                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14853                            args.length - opti);
14854                }
14855                synchronized (this) {
14856                    if (dumpCheckinFormat) {
14857                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14858                                dumpPackage);
14859                    } else {
14860                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14861                    }
14862                }
14863            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14864                String[] newArgs;
14865                String name;
14866                if (opti >= args.length) {
14867                    name = null;
14868                    newArgs = EMPTY_STRING_ARRAY;
14869                } else {
14870                    dumpPackage = args[opti];
14871                    opti++;
14872                    newArgs = new String[args.length - opti];
14873                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14874                            args.length - opti);
14875                }
14876                synchronized (this) {
14877                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14878                }
14879            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14880                String[] newArgs;
14881                String name;
14882                if (opti >= args.length) {
14883                    name = null;
14884                    newArgs = EMPTY_STRING_ARRAY;
14885                } else {
14886                    dumpPackage = args[opti];
14887                    opti++;
14888                    newArgs = new String[args.length - opti];
14889                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14890                            args.length - opti);
14891                }
14892                synchronized (this) {
14893                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14894                }
14895            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14896                synchronized (this) {
14897                    dumpOomLocked(fd, pw, args, opti, true);
14898                }
14899            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14900                synchronized (this) {
14901                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14902                }
14903            } else if ("provider".equals(cmd)) {
14904                String[] newArgs;
14905                String name;
14906                if (opti >= args.length) {
14907                    name = null;
14908                    newArgs = EMPTY_STRING_ARRAY;
14909                } else {
14910                    name = args[opti];
14911                    opti++;
14912                    newArgs = new String[args.length - opti];
14913                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14914                }
14915                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14916                    pw.println("No providers match: " + name);
14917                    pw.println("Use -h for help.");
14918                }
14919            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14920                synchronized (this) {
14921                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14922                }
14923            } else if ("service".equals(cmd)) {
14924                String[] newArgs;
14925                String name;
14926                if (opti >= args.length) {
14927                    name = null;
14928                    newArgs = EMPTY_STRING_ARRAY;
14929                } else {
14930                    name = args[opti];
14931                    opti++;
14932                    newArgs = new String[args.length - opti];
14933                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14934                            args.length - opti);
14935                }
14936                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14937                    pw.println("No services match: " + name);
14938                    pw.println("Use -h for help.");
14939                }
14940            } else if ("package".equals(cmd)) {
14941                String[] newArgs;
14942                if (opti >= args.length) {
14943                    pw.println("package: no package name specified");
14944                    pw.println("Use -h for help.");
14945                } else {
14946                    dumpPackage = args[opti];
14947                    opti++;
14948                    newArgs = new String[args.length - opti];
14949                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14950                            args.length - opti);
14951                    args = newArgs;
14952                    opti = 0;
14953                    more = true;
14954                }
14955            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14956                synchronized (this) {
14957                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14958                }
14959            } else if ("settings".equals(cmd)) {
14960                synchronized (this) {
14961                    mConstants.dump(pw);
14962                }
14963            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14964                if (dumpClient) {
14965                    ActiveServices.ServiceDumper dumper;
14966                    synchronized (this) {
14967                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14968                                dumpPackage);
14969                    }
14970                    dumper.dumpWithClient();
14971                } else {
14972                    synchronized (this) {
14973                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14974                                dumpPackage).dumpLocked();
14975                    }
14976                }
14977            } else if ("locks".equals(cmd)) {
14978                LockGuard.dump(fd, pw, args);
14979            } else {
14980                // Dumping a single activity?
14981                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
14982                        dumpFocusedStackOnly)) {
14983                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14984                    int res = shell.exec(this, null, fd, null, args, null,
14985                            new ResultReceiver(null));
14986                    if (res < 0) {
14987                        pw.println("Bad activity command, or no activities match: " + cmd);
14988                        pw.println("Use -h for help.");
14989                    }
14990                }
14991            }
14992            if (!more) {
14993                Binder.restoreCallingIdentity(origId);
14994                return;
14995            }
14996        }
14997
14998        // No piece of data specified, dump everything.
14999        if (dumpCheckinFormat) {
15000            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15001        } else if (dumpClient) {
15002            ActiveServices.ServiceDumper sdumper;
15003            synchronized (this) {
15004                mConstants.dump(pw);
15005                pw.println();
15006                if (dumpAll) {
15007                    pw.println("-------------------------------------------------------------------------------");
15008                }
15009                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15010                pw.println();
15011                if (dumpAll) {
15012                    pw.println("-------------------------------------------------------------------------------");
15013                }
15014                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15015                pw.println();
15016                if (dumpAll) {
15017                    pw.println("-------------------------------------------------------------------------------");
15018                }
15019                if (dumpAll || dumpPackage != null) {
15020                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15021                    pw.println();
15022                    if (dumpAll) {
15023                        pw.println("-------------------------------------------------------------------------------");
15024                    }
15025                }
15026                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15027                pw.println();
15028                if (dumpAll) {
15029                    pw.println("-------------------------------------------------------------------------------");
15030                }
15031                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15032                pw.println();
15033                if (dumpAll) {
15034                    pw.println("-------------------------------------------------------------------------------");
15035                }
15036                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15037                        dumpPackage);
15038            }
15039            sdumper.dumpWithClient();
15040            pw.println();
15041            synchronized (this) {
15042                if (dumpAll) {
15043                    pw.println("-------------------------------------------------------------------------------");
15044                }
15045                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15046                pw.println();
15047                if (dumpAll) {
15048                    pw.println("-------------------------------------------------------------------------------");
15049                }
15050                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15051                if (mAssociations.size() > 0) {
15052                    pw.println();
15053                    if (dumpAll) {
15054                        pw.println("-------------------------------------------------------------------------------");
15055                    }
15056                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15057                }
15058                pw.println();
15059                if (dumpAll) {
15060                    pw.println("-------------------------------------------------------------------------------");
15061                }
15062                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15063            }
15064
15065        } else {
15066            synchronized (this) {
15067                mConstants.dump(pw);
15068                pw.println();
15069                if (dumpAll) {
15070                    pw.println("-------------------------------------------------------------------------------");
15071                }
15072                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15073                pw.println();
15074                if (dumpAll) {
15075                    pw.println("-------------------------------------------------------------------------------");
15076                }
15077                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15078                pw.println();
15079                if (dumpAll) {
15080                    pw.println("-------------------------------------------------------------------------------");
15081                }
15082                if (dumpAll || dumpPackage != null) {
15083                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15084                    pw.println();
15085                    if (dumpAll) {
15086                        pw.println("-------------------------------------------------------------------------------");
15087                    }
15088                }
15089                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15090                pw.println();
15091                if (dumpAll) {
15092                    pw.println("-------------------------------------------------------------------------------");
15093                }
15094                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15095                pw.println();
15096                if (dumpAll) {
15097                    pw.println("-------------------------------------------------------------------------------");
15098                }
15099                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15100                        .dumpLocked();
15101                pw.println();
15102                if (dumpAll) {
15103                    pw.println("-------------------------------------------------------------------------------");
15104                }
15105                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15106                pw.println();
15107                if (dumpAll) {
15108                    pw.println("-------------------------------------------------------------------------------");
15109                }
15110                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15111                if (mAssociations.size() > 0) {
15112                    pw.println();
15113                    if (dumpAll) {
15114                        pw.println("-------------------------------------------------------------------------------");
15115                    }
15116                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15117                }
15118                pw.println();
15119                if (dumpAll) {
15120                    pw.println("-------------------------------------------------------------------------------");
15121                }
15122                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15123            }
15124        }
15125        Binder.restoreCallingIdentity(origId);
15126    }
15127
15128    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15129            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15130        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15131
15132        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15133                dumpPackage);
15134        boolean needSep = printedAnything;
15135
15136        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15137                mStackSupervisor.getResumedActivityLocked(),
15138                dumpPackage, needSep, "  ResumedActivity: ");
15139        if (printed) {
15140            printedAnything = true;
15141            needSep = false;
15142        }
15143
15144        if (dumpPackage == null) {
15145            if (needSep) {
15146                pw.println();
15147            }
15148            needSep = true;
15149            printedAnything = true;
15150            mStackSupervisor.dump(pw, "  ");
15151        }
15152
15153        if (!printedAnything) {
15154            pw.println("  (nothing)");
15155        }
15156    }
15157
15158    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15159            int opti, boolean dumpAll, String dumpPackage) {
15160        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15161
15162        boolean printedAnything = false;
15163
15164        if (mRecentTasks != null && mRecentTasks.size() > 0) {
15165            boolean printedHeader = false;
15166
15167            final int N = mRecentTasks.size();
15168            for (int i=0; i<N; i++) {
15169                TaskRecord tr = mRecentTasks.get(i);
15170                if (dumpPackage != null) {
15171                    if (tr.realActivity == null ||
15172                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
15173                        continue;
15174                    }
15175                }
15176                if (!printedHeader) {
15177                    pw.println("  Recent tasks:");
15178                    printedHeader = true;
15179                    printedAnything = true;
15180                }
15181                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15182                        pw.println(tr);
15183                if (dumpAll) {
15184                    mRecentTasks.get(i).dump(pw, "    ");
15185                }
15186            }
15187        }
15188
15189        if (!printedAnything) {
15190            pw.println("  (nothing)");
15191        }
15192    }
15193
15194    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15195            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15196        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15197
15198        int dumpUid = 0;
15199        if (dumpPackage != null) {
15200            IPackageManager pm = AppGlobals.getPackageManager();
15201            try {
15202                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15203            } catch (RemoteException e) {
15204            }
15205        }
15206
15207        boolean printedAnything = false;
15208
15209        final long now = SystemClock.uptimeMillis();
15210
15211        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15212            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15213                    = mAssociations.valueAt(i1);
15214            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15215                SparseArray<ArrayMap<String, Association>> sourceUids
15216                        = targetComponents.valueAt(i2);
15217                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15218                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15219                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15220                        Association ass = sourceProcesses.valueAt(i4);
15221                        if (dumpPackage != null) {
15222                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15223                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15224                                continue;
15225                            }
15226                        }
15227                        printedAnything = true;
15228                        pw.print("  ");
15229                        pw.print(ass.mTargetProcess);
15230                        pw.print("/");
15231                        UserHandle.formatUid(pw, ass.mTargetUid);
15232                        pw.print(" <- ");
15233                        pw.print(ass.mSourceProcess);
15234                        pw.print("/");
15235                        UserHandle.formatUid(pw, ass.mSourceUid);
15236                        pw.println();
15237                        pw.print("    via ");
15238                        pw.print(ass.mTargetComponent.flattenToShortString());
15239                        pw.println();
15240                        pw.print("    ");
15241                        long dur = ass.mTime;
15242                        if (ass.mNesting > 0) {
15243                            dur += now - ass.mStartTime;
15244                        }
15245                        TimeUtils.formatDuration(dur, pw);
15246                        pw.print(" (");
15247                        pw.print(ass.mCount);
15248                        pw.print(" times)");
15249                        pw.print("  ");
15250                        for (int i=0; i<ass.mStateTimes.length; i++) {
15251                            long amt = ass.mStateTimes[i];
15252                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15253                                amt += now - ass.mLastStateUptime;
15254                            }
15255                            if (amt != 0) {
15256                                pw.print(" ");
15257                                pw.print(ProcessList.makeProcStateString(
15258                                            i + ActivityManager.MIN_PROCESS_STATE));
15259                                pw.print("=");
15260                                TimeUtils.formatDuration(amt, pw);
15261                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15262                                    pw.print("*");
15263                                }
15264                            }
15265                        }
15266                        pw.println();
15267                        if (ass.mNesting > 0) {
15268                            pw.print("    Currently active: ");
15269                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15270                            pw.println();
15271                        }
15272                    }
15273                }
15274            }
15275
15276        }
15277
15278        if (!printedAnything) {
15279            pw.println("  (nothing)");
15280        }
15281    }
15282
15283    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15284            String header, boolean needSep) {
15285        boolean printed = false;
15286        int whichAppId = -1;
15287        if (dumpPackage != null) {
15288            try {
15289                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15290                        dumpPackage, 0);
15291                whichAppId = UserHandle.getAppId(info.uid);
15292            } catch (NameNotFoundException e) {
15293                e.printStackTrace();
15294            }
15295        }
15296        for (int i=0; i<uids.size(); i++) {
15297            UidRecord uidRec = uids.valueAt(i);
15298            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15299                continue;
15300            }
15301            if (!printed) {
15302                printed = true;
15303                if (needSep) {
15304                    pw.println();
15305                }
15306                pw.print("  ");
15307                pw.println(header);
15308                needSep = true;
15309            }
15310            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15311            pw.print(": "); pw.println(uidRec);
15312        }
15313        return printed;
15314    }
15315
15316    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15317            int opti, boolean dumpAll, String dumpPackage) {
15318        boolean needSep = false;
15319        boolean printedAnything = false;
15320        int numPers = 0;
15321
15322        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15323
15324        if (dumpAll) {
15325            final int NP = mProcessNames.getMap().size();
15326            for (int ip=0; ip<NP; ip++) {
15327                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15328                final int NA = procs.size();
15329                for (int ia=0; ia<NA; ia++) {
15330                    ProcessRecord r = procs.valueAt(ia);
15331                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15332                        continue;
15333                    }
15334                    if (!needSep) {
15335                        pw.println("  All known processes:");
15336                        needSep = true;
15337                        printedAnything = true;
15338                    }
15339                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15340                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15341                        pw.print(" "); pw.println(r);
15342                    r.dump(pw, "    ");
15343                    if (r.persistent) {
15344                        numPers++;
15345                    }
15346                }
15347            }
15348        }
15349
15350        if (mIsolatedProcesses.size() > 0) {
15351            boolean printed = false;
15352            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15353                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15354                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15355                    continue;
15356                }
15357                if (!printed) {
15358                    if (needSep) {
15359                        pw.println();
15360                    }
15361                    pw.println("  Isolated process list (sorted by uid):");
15362                    printedAnything = true;
15363                    printed = true;
15364                    needSep = true;
15365                }
15366                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15367                pw.println(r);
15368            }
15369        }
15370
15371        if (mActiveInstrumentation.size() > 0) {
15372            boolean printed = false;
15373            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15374                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15375                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15376                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15377                    continue;
15378                }
15379                if (!printed) {
15380                    if (needSep) {
15381                        pw.println();
15382                    }
15383                    pw.println("  Active instrumentation:");
15384                    printedAnything = true;
15385                    printed = true;
15386                    needSep = true;
15387                }
15388                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15389                pw.println(ai);
15390                ai.dump(pw, "      ");
15391            }
15392        }
15393
15394        if (mActiveUids.size() > 0) {
15395            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15396                printedAnything = needSep = true;
15397            }
15398        }
15399        if (dumpAll) {
15400            if (mValidateUids.size() > 0) {
15401                if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15402                    printedAnything = needSep = true;
15403                }
15404            }
15405        }
15406
15407        if (mLruProcesses.size() > 0) {
15408            if (needSep) {
15409                pw.println();
15410            }
15411            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15412                    pw.print(" total, non-act at ");
15413                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15414                    pw.print(", non-svc at ");
15415                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15416                    pw.println("):");
15417            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15418            needSep = true;
15419            printedAnything = true;
15420        }
15421
15422        if (dumpAll || dumpPackage != null) {
15423            synchronized (mPidsSelfLocked) {
15424                boolean printed = false;
15425                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15426                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15427                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15428                        continue;
15429                    }
15430                    if (!printed) {
15431                        if (needSep) pw.println();
15432                        needSep = true;
15433                        pw.println("  PID mappings:");
15434                        printed = true;
15435                        printedAnything = true;
15436                    }
15437                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15438                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15439                }
15440            }
15441        }
15442
15443        if (mForegroundProcesses.size() > 0) {
15444            synchronized (mPidsSelfLocked) {
15445                boolean printed = false;
15446                for (int i=0; i<mForegroundProcesses.size(); i++) {
15447                    ProcessRecord r = mPidsSelfLocked.get(
15448                            mForegroundProcesses.valueAt(i).pid);
15449                    if (dumpPackage != null && (r == null
15450                            || !r.pkgList.containsKey(dumpPackage))) {
15451                        continue;
15452                    }
15453                    if (!printed) {
15454                        if (needSep) pw.println();
15455                        needSep = true;
15456                        pw.println("  Foreground Processes:");
15457                        printed = true;
15458                        printedAnything = true;
15459                    }
15460                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
15461                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
15462                }
15463            }
15464        }
15465
15466        if (mPersistentStartingProcesses.size() > 0) {
15467            if (needSep) pw.println();
15468            needSep = true;
15469            printedAnything = true;
15470            pw.println("  Persisent processes that are starting:");
15471            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15472                    "Starting Norm", "Restarting PERS", dumpPackage);
15473        }
15474
15475        if (mRemovedProcesses.size() > 0) {
15476            if (needSep) pw.println();
15477            needSep = true;
15478            printedAnything = true;
15479            pw.println("  Processes that are being removed:");
15480            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15481                    "Removed Norm", "Removed PERS", dumpPackage);
15482        }
15483
15484        if (mProcessesOnHold.size() > 0) {
15485            if (needSep) pw.println();
15486            needSep = true;
15487            printedAnything = true;
15488            pw.println("  Processes that are on old until the system is ready:");
15489            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15490                    "OnHold Norm", "OnHold PERS", dumpPackage);
15491        }
15492
15493        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15494
15495        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15496        if (needSep) {
15497            printedAnything = true;
15498        }
15499
15500        if (dumpPackage == null) {
15501            pw.println();
15502            needSep = false;
15503            mUserController.dump(pw, dumpAll);
15504        }
15505        if (mHomeProcess != null && (dumpPackage == null
15506                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15507            if (needSep) {
15508                pw.println();
15509                needSep = false;
15510            }
15511            pw.println("  mHomeProcess: " + mHomeProcess);
15512        }
15513        if (mPreviousProcess != null && (dumpPackage == null
15514                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15515            if (needSep) {
15516                pw.println();
15517                needSep = false;
15518            }
15519            pw.println("  mPreviousProcess: " + mPreviousProcess);
15520        }
15521        if (dumpAll) {
15522            StringBuilder sb = new StringBuilder(128);
15523            sb.append("  mPreviousProcessVisibleTime: ");
15524            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15525            pw.println(sb);
15526        }
15527        if (mHeavyWeightProcess != null && (dumpPackage == null
15528                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15529            if (needSep) {
15530                pw.println();
15531                needSep = false;
15532            }
15533            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15534        }
15535        if (dumpPackage == null) {
15536            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15537            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15538        }
15539        if (dumpAll) {
15540            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15541            if (mCompatModePackages.getPackages().size() > 0) {
15542                boolean printed = false;
15543                for (Map.Entry<String, Integer> entry
15544                        : mCompatModePackages.getPackages().entrySet()) {
15545                    String pkg = entry.getKey();
15546                    int mode = entry.getValue();
15547                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15548                        continue;
15549                    }
15550                    if (!printed) {
15551                        pw.println("  mScreenCompatPackages:");
15552                        printed = true;
15553                    }
15554                    pw.print("    "); pw.print(pkg); pw.print(": ");
15555                            pw.print(mode); pw.println();
15556                }
15557            }
15558            final int NI = mUidObservers.getRegisteredCallbackCount();
15559            boolean printed = false;
15560            for (int i=0; i<NI; i++) {
15561                final UidObserverRegistration reg = (UidObserverRegistration)
15562                        mUidObservers.getRegisteredCallbackCookie(i);
15563                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15564                    if (!printed) {
15565                        pw.println("  mUidObservers:");
15566                        printed = true;
15567                    }
15568                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15569                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15570                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15571                        pw.print(" IDLE");
15572                    }
15573                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15574                        pw.print(" ACT" );
15575                    }
15576                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15577                        pw.print(" GONE");
15578                    }
15579                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15580                        pw.print(" STATE");
15581                        pw.print(" (cut="); pw.print(reg.cutpoint);
15582                        pw.print(")");
15583                    }
15584                    pw.println();
15585                    if (reg.lastProcStates != null) {
15586                        final int NJ = reg.lastProcStates.size();
15587                        for (int j=0; j<NJ; j++) {
15588                            pw.print("      Last ");
15589                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15590                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15591                        }
15592                    }
15593                }
15594            }
15595            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15596            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15597            if (mPendingTempWhitelist.size() > 0) {
15598                pw.println("  mPendingTempWhitelist:");
15599                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15600                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15601                    pw.print("    ");
15602                    UserHandle.formatUid(pw, ptw.targetUid);
15603                    pw.print(": ");
15604                    TimeUtils.formatDuration(ptw.duration, pw);
15605                    pw.print(" ");
15606                    pw.println(ptw.tag);
15607                }
15608            }
15609        }
15610        if (dumpPackage == null) {
15611            pw.println("  mWakefulness="
15612                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15613            pw.println("  mSleepTokens=" + mSleepTokens);
15614            pw.println("  mSleeping=" + mSleeping);
15615            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15616            if (mRunningVoice != null) {
15617                pw.println("  mRunningVoice=" + mRunningVoice);
15618                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15619            }
15620        }
15621        pw.println("  mVrController=" + mVrController);
15622        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15623                || mOrigWaitForDebugger) {
15624            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15625                    || dumpPackage.equals(mOrigDebugApp)) {
15626                if (needSep) {
15627                    pw.println();
15628                    needSep = false;
15629                }
15630                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15631                        + " mDebugTransient=" + mDebugTransient
15632                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15633            }
15634        }
15635        if (mCurAppTimeTracker != null) {
15636            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15637        }
15638        if (mMemWatchProcesses.getMap().size() > 0) {
15639            pw.println("  Mem watch processes:");
15640            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15641                    = mMemWatchProcesses.getMap();
15642            for (int i=0; i<procs.size(); i++) {
15643                final String proc = procs.keyAt(i);
15644                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15645                for (int j=0; j<uids.size(); j++) {
15646                    if (needSep) {
15647                        pw.println();
15648                        needSep = false;
15649                    }
15650                    StringBuilder sb = new StringBuilder();
15651                    sb.append("    ").append(proc).append('/');
15652                    UserHandle.formatUid(sb, uids.keyAt(j));
15653                    Pair<Long, String> val = uids.valueAt(j);
15654                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15655                    if (val.second != null) {
15656                        sb.append(", report to ").append(val.second);
15657                    }
15658                    pw.println(sb.toString());
15659                }
15660            }
15661            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15662            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15663            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15664                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15665        }
15666        if (mTrackAllocationApp != null) {
15667            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15668                if (needSep) {
15669                    pw.println();
15670                    needSep = false;
15671                }
15672                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15673            }
15674        }
15675        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15676                || mProfileFd != null) {
15677            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15678                if (needSep) {
15679                    pw.println();
15680                    needSep = false;
15681                }
15682                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15683                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15684                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15685                        + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15686                pw.println("  mProfileType=" + mProfileType);
15687            }
15688        }
15689        if (mNativeDebuggingApp != null) {
15690            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15691                if (needSep) {
15692                    pw.println();
15693                    needSep = false;
15694                }
15695                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15696            }
15697        }
15698        if (dumpPackage == null) {
15699            if (mAlwaysFinishActivities) {
15700                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15701            }
15702            if (mController != null) {
15703                pw.println("  mController=" + mController
15704                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15705            }
15706            if (dumpAll) {
15707                pw.println("  Total persistent processes: " + numPers);
15708                pw.println("  mProcessesReady=" + mProcessesReady
15709                        + " mSystemReady=" + mSystemReady
15710                        + " mBooted=" + mBooted
15711                        + " mFactoryTest=" + mFactoryTest);
15712                pw.println("  mBooting=" + mBooting
15713                        + " mCallFinishBooting=" + mCallFinishBooting
15714                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15715                pw.print("  mLastPowerCheckRealtime=");
15716                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15717                        pw.println("");
15718                pw.print("  mLastPowerCheckUptime=");
15719                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15720                        pw.println("");
15721                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15722                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15723                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15724                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15725                        + " (" + mLruProcesses.size() + " total)"
15726                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15727                        + " mNumServiceProcs=" + mNumServiceProcs
15728                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15729                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15730                        + " mLastMemoryLevel=" + mLastMemoryLevel
15731                        + " mLastNumProcesses=" + mLastNumProcesses);
15732                long now = SystemClock.uptimeMillis();
15733                pw.print("  mLastIdleTime=");
15734                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15735                        pw.print(" mLowRamSinceLastIdle=");
15736                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15737                        pw.println();
15738            }
15739        }
15740
15741        if (!printedAnything) {
15742            pw.println("  (nothing)");
15743        }
15744    }
15745
15746    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15747            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15748        if (mProcessesToGc.size() > 0) {
15749            boolean printed = false;
15750            long now = SystemClock.uptimeMillis();
15751            for (int i=0; i<mProcessesToGc.size(); i++) {
15752                ProcessRecord proc = mProcessesToGc.get(i);
15753                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15754                    continue;
15755                }
15756                if (!printed) {
15757                    if (needSep) pw.println();
15758                    needSep = true;
15759                    pw.println("  Processes that are waiting to GC:");
15760                    printed = true;
15761                }
15762                pw.print("    Process "); pw.println(proc);
15763                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15764                        pw.print(", last gced=");
15765                        pw.print(now-proc.lastRequestedGc);
15766                        pw.print(" ms ago, last lowMem=");
15767                        pw.print(now-proc.lastLowMemory);
15768                        pw.println(" ms ago");
15769
15770            }
15771        }
15772        return needSep;
15773    }
15774
15775    void printOomLevel(PrintWriter pw, String name, int adj) {
15776        pw.print("    ");
15777        if (adj >= 0) {
15778            pw.print(' ');
15779            if (adj < 10) pw.print(' ');
15780        } else {
15781            if (adj > -10) pw.print(' ');
15782        }
15783        pw.print(adj);
15784        pw.print(": ");
15785        pw.print(name);
15786        pw.print(" (");
15787        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15788        pw.println(")");
15789    }
15790
15791    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15792            int opti, boolean dumpAll) {
15793        boolean needSep = false;
15794
15795        if (mLruProcesses.size() > 0) {
15796            if (needSep) pw.println();
15797            needSep = true;
15798            pw.println("  OOM levels:");
15799            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15800            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15801            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15802            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15803            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15804            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15805            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15806            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15807            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15808            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15809            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15810            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15811            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15812            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15813
15814            if (needSep) pw.println();
15815            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15816                    pw.print(" total, non-act at ");
15817                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15818                    pw.print(", non-svc at ");
15819                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15820                    pw.println("):");
15821            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15822            needSep = true;
15823        }
15824
15825        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15826
15827        pw.println();
15828        pw.println("  mHomeProcess: " + mHomeProcess);
15829        pw.println("  mPreviousProcess: " + mPreviousProcess);
15830        if (mHeavyWeightProcess != null) {
15831            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15832        }
15833
15834        return true;
15835    }
15836
15837    /**
15838     * There are three ways to call this:
15839     *  - no provider specified: dump all the providers
15840     *  - a flattened component name that matched an existing provider was specified as the
15841     *    first arg: dump that one provider
15842     *  - the first arg isn't the flattened component name of an existing provider:
15843     *    dump all providers whose component contains the first arg as a substring
15844     */
15845    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15846            int opti, boolean dumpAll) {
15847        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15848    }
15849
15850    static class ItemMatcher {
15851        ArrayList<ComponentName> components;
15852        ArrayList<String> strings;
15853        ArrayList<Integer> objects;
15854        boolean all;
15855
15856        ItemMatcher() {
15857            all = true;
15858        }
15859
15860        void build(String name) {
15861            ComponentName componentName = ComponentName.unflattenFromString(name);
15862            if (componentName != null) {
15863                if (components == null) {
15864                    components = new ArrayList<ComponentName>();
15865                }
15866                components.add(componentName);
15867                all = false;
15868            } else {
15869                int objectId = 0;
15870                // Not a '/' separated full component name; maybe an object ID?
15871                try {
15872                    objectId = Integer.parseInt(name, 16);
15873                    if (objects == null) {
15874                        objects = new ArrayList<Integer>();
15875                    }
15876                    objects.add(objectId);
15877                    all = false;
15878                } catch (RuntimeException e) {
15879                    // Not an integer; just do string match.
15880                    if (strings == null) {
15881                        strings = new ArrayList<String>();
15882                    }
15883                    strings.add(name);
15884                    all = false;
15885                }
15886            }
15887        }
15888
15889        int build(String[] args, int opti) {
15890            for (; opti<args.length; opti++) {
15891                String name = args[opti];
15892                if ("--".equals(name)) {
15893                    return opti+1;
15894                }
15895                build(name);
15896            }
15897            return opti;
15898        }
15899
15900        boolean match(Object object, ComponentName comp) {
15901            if (all) {
15902                return true;
15903            }
15904            if (components != null) {
15905                for (int i=0; i<components.size(); i++) {
15906                    if (components.get(i).equals(comp)) {
15907                        return true;
15908                    }
15909                }
15910            }
15911            if (objects != null) {
15912                for (int i=0; i<objects.size(); i++) {
15913                    if (System.identityHashCode(object) == objects.get(i)) {
15914                        return true;
15915                    }
15916                }
15917            }
15918            if (strings != null) {
15919                String flat = comp.flattenToString();
15920                for (int i=0; i<strings.size(); i++) {
15921                    if (flat.contains(strings.get(i))) {
15922                        return true;
15923                    }
15924                }
15925            }
15926            return false;
15927        }
15928    }
15929
15930    /**
15931     * There are three things that cmd can be:
15932     *  - a flattened component name that matches an existing activity
15933     *  - the cmd arg isn't the flattened component name of an existing activity:
15934     *    dump all activity whose component contains the cmd as a substring
15935     *  - A hex number of the ActivityRecord object instance.
15936     *
15937     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
15938     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
15939     */
15940    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15941            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
15942        ArrayList<ActivityRecord> activities;
15943
15944        synchronized (this) {
15945            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
15946                    dumpFocusedStackOnly);
15947        }
15948
15949        if (activities.size() <= 0) {
15950            return false;
15951        }
15952
15953        String[] newArgs = new String[args.length - opti];
15954        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15955
15956        TaskRecord lastTask = null;
15957        boolean needSep = false;
15958        for (int i=activities.size()-1; i>=0; i--) {
15959            ActivityRecord r = activities.get(i);
15960            if (needSep) {
15961                pw.println();
15962            }
15963            needSep = true;
15964            synchronized (this) {
15965                final TaskRecord task = r.getTask();
15966                if (lastTask != task) {
15967                    lastTask = task;
15968                    pw.print("TASK "); pw.print(lastTask.affinity);
15969                            pw.print(" id="); pw.print(lastTask.taskId);
15970                            pw.print(" userId="); pw.println(lastTask.userId);
15971                    if (dumpAll) {
15972                        lastTask.dump(pw, "  ");
15973                    }
15974                }
15975            }
15976            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15977        }
15978        return true;
15979    }
15980
15981    /**
15982     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15983     * there is a thread associated with the activity.
15984     */
15985    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15986            final ActivityRecord r, String[] args, boolean dumpAll) {
15987        String innerPrefix = prefix + "  ";
15988        synchronized (this) {
15989            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15990                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15991                    pw.print(" pid=");
15992                    if (r.app != null) pw.println(r.app.pid);
15993                    else pw.println("(not running)");
15994            if (dumpAll) {
15995                r.dump(pw, innerPrefix);
15996            }
15997        }
15998        if (r.app != null && r.app.thread != null) {
15999            // flush anything that is already in the PrintWriter since the thread is going
16000            // to write to the file descriptor directly
16001            pw.flush();
16002            try {
16003                TransferPipe tp = new TransferPipe();
16004                try {
16005                    r.app.thread.dumpActivity(tp.getWriteFd(),
16006                            r.appToken, innerPrefix, args);
16007                    tp.go(fd);
16008                } finally {
16009                    tp.kill();
16010                }
16011            } catch (IOException e) {
16012                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16013            } catch (RemoteException e) {
16014                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16015            }
16016        }
16017    }
16018
16019    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16020            int opti, boolean dumpAll, String dumpPackage) {
16021        boolean needSep = false;
16022        boolean onlyHistory = false;
16023        boolean printedAnything = false;
16024
16025        if ("history".equals(dumpPackage)) {
16026            if (opti < args.length && "-s".equals(args[opti])) {
16027                dumpAll = false;
16028            }
16029            onlyHistory = true;
16030            dumpPackage = null;
16031        }
16032
16033        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16034        if (!onlyHistory && dumpAll) {
16035            if (mRegisteredReceivers.size() > 0) {
16036                boolean printed = false;
16037                Iterator it = mRegisteredReceivers.values().iterator();
16038                while (it.hasNext()) {
16039                    ReceiverList r = (ReceiverList)it.next();
16040                    if (dumpPackage != null && (r.app == null ||
16041                            !dumpPackage.equals(r.app.info.packageName))) {
16042                        continue;
16043                    }
16044                    if (!printed) {
16045                        pw.println("  Registered Receivers:");
16046                        needSep = true;
16047                        printed = true;
16048                        printedAnything = true;
16049                    }
16050                    pw.print("  * "); pw.println(r);
16051                    r.dump(pw, "    ");
16052                }
16053            }
16054
16055            if (mReceiverResolver.dump(pw, needSep ?
16056                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16057                    "    ", dumpPackage, false, false)) {
16058                needSep = true;
16059                printedAnything = true;
16060            }
16061        }
16062
16063        for (BroadcastQueue q : mBroadcastQueues) {
16064            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16065            printedAnything |= needSep;
16066        }
16067
16068        needSep = true;
16069
16070        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16071            for (int user=0; user<mStickyBroadcasts.size(); user++) {
16072                if (needSep) {
16073                    pw.println();
16074                }
16075                needSep = true;
16076                printedAnything = true;
16077                pw.print("  Sticky broadcasts for user ");
16078                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16079                StringBuilder sb = new StringBuilder(128);
16080                for (Map.Entry<String, ArrayList<Intent>> ent
16081                        : mStickyBroadcasts.valueAt(user).entrySet()) {
16082                    pw.print("  * Sticky action "); pw.print(ent.getKey());
16083                    if (dumpAll) {
16084                        pw.println(":");
16085                        ArrayList<Intent> intents = ent.getValue();
16086                        final int N = intents.size();
16087                        for (int i=0; i<N; i++) {
16088                            sb.setLength(0);
16089                            sb.append("    Intent: ");
16090                            intents.get(i).toShortString(sb, false, true, false, false);
16091                            pw.println(sb.toString());
16092                            Bundle bundle = intents.get(i).getExtras();
16093                            if (bundle != null) {
16094                                pw.print("      ");
16095                                pw.println(bundle.toString());
16096                            }
16097                        }
16098                    } else {
16099                        pw.println("");
16100                    }
16101                }
16102            }
16103        }
16104
16105        if (!onlyHistory && dumpAll) {
16106            pw.println();
16107            for (BroadcastQueue queue : mBroadcastQueues) {
16108                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16109                        + queue.mBroadcastsScheduled);
16110            }
16111            pw.println("  mHandler:");
16112            mHandler.dump(new PrintWriterPrinter(pw), "    ");
16113            needSep = true;
16114            printedAnything = true;
16115        }
16116
16117        if (!printedAnything) {
16118            pw.println("  (nothing)");
16119        }
16120    }
16121
16122    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16123            int opti, boolean dumpAll, String dumpPackage) {
16124        if (mCurBroadcastStats == null) {
16125            return;
16126        }
16127
16128        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16129        final long now = SystemClock.elapsedRealtime();
16130        if (mLastBroadcastStats != null) {
16131            pw.print("  Last stats (from ");
16132            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16133            pw.print(" to ");
16134            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16135            pw.print(", ");
16136            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16137                    - mLastBroadcastStats.mStartUptime, pw);
16138            pw.println(" uptime):");
16139            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16140                pw.println("    (nothing)");
16141            }
16142            pw.println();
16143        }
16144        pw.print("  Current stats (from ");
16145        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16146        pw.print(" to now, ");
16147        TimeUtils.formatDuration(SystemClock.uptimeMillis()
16148                - mCurBroadcastStats.mStartUptime, pw);
16149        pw.println(" uptime):");
16150        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16151            pw.println("    (nothing)");
16152        }
16153    }
16154
16155    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16156            int opti, boolean fullCheckin, String dumpPackage) {
16157        if (mCurBroadcastStats == null) {
16158            return;
16159        }
16160
16161        if (mLastBroadcastStats != null) {
16162            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16163            if (fullCheckin) {
16164                mLastBroadcastStats = null;
16165                return;
16166            }
16167        }
16168        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16169        if (fullCheckin) {
16170            mCurBroadcastStats = null;
16171        }
16172    }
16173
16174    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16175            int opti, boolean dumpAll, String dumpPackage) {
16176        boolean needSep;
16177        boolean printedAnything = false;
16178
16179        ItemMatcher matcher = new ItemMatcher();
16180        matcher.build(args, opti);
16181
16182        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16183
16184        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16185        printedAnything |= needSep;
16186
16187        if (mLaunchingProviders.size() > 0) {
16188            boolean printed = false;
16189            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16190                ContentProviderRecord r = mLaunchingProviders.get(i);
16191                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16192                    continue;
16193                }
16194                if (!printed) {
16195                    if (needSep) pw.println();
16196                    needSep = true;
16197                    pw.println("  Launching content providers:");
16198                    printed = true;
16199                    printedAnything = true;
16200                }
16201                pw.print("  Launching #"); pw.print(i); pw.print(": ");
16202                        pw.println(r);
16203            }
16204        }
16205
16206        if (!printedAnything) {
16207            pw.println("  (nothing)");
16208        }
16209    }
16210
16211    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16212            int opti, boolean dumpAll, String dumpPackage) {
16213        boolean needSep = false;
16214        boolean printedAnything = false;
16215
16216        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16217
16218        if (mGrantedUriPermissions.size() > 0) {
16219            boolean printed = false;
16220            int dumpUid = -2;
16221            if (dumpPackage != null) {
16222                try {
16223                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16224                            MATCH_ANY_USER, 0);
16225                } catch (NameNotFoundException e) {
16226                    dumpUid = -1;
16227                }
16228            }
16229            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16230                int uid = mGrantedUriPermissions.keyAt(i);
16231                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16232                    continue;
16233                }
16234                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16235                if (!printed) {
16236                    if (needSep) pw.println();
16237                    needSep = true;
16238                    pw.println("  Granted Uri Permissions:");
16239                    printed = true;
16240                    printedAnything = true;
16241                }
16242                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16243                for (UriPermission perm : perms.values()) {
16244                    pw.print("    "); pw.println(perm);
16245                    if (dumpAll) {
16246                        perm.dump(pw, "      ");
16247                    }
16248                }
16249            }
16250        }
16251
16252        if (!printedAnything) {
16253            pw.println("  (nothing)");
16254        }
16255    }
16256
16257    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16258            int opti, boolean dumpAll, String dumpPackage) {
16259        boolean printed = false;
16260
16261        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16262
16263        if (mIntentSenderRecords.size() > 0) {
16264            // Organize these by package name, so they are easier to read.
16265            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16266            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16267            final Iterator<WeakReference<PendingIntentRecord>> it
16268                    = mIntentSenderRecords.values().iterator();
16269            while (it.hasNext()) {
16270                WeakReference<PendingIntentRecord> ref = it.next();
16271                PendingIntentRecord rec = ref != null ? ref.get() : null;
16272                if (rec == null) {
16273                    weakRefs.add(ref);
16274                    continue;
16275                }
16276                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16277                    continue;
16278                }
16279                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16280                if (list == null) {
16281                    list = new ArrayList<>();
16282                    byPackage.put(rec.key.packageName, list);
16283                }
16284                list.add(rec);
16285            }
16286            for (int i = 0; i < byPackage.size(); i++) {
16287                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16288                printed = true;
16289                pw.print("  * "); pw.print(byPackage.keyAt(i));
16290                pw.print(": "); pw.print(intents.size()); pw.println(" items");
16291                for (int j = 0; j < intents.size(); j++) {
16292                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16293                    if (dumpAll) {
16294                        intents.get(j).dump(pw, "      ");
16295                    }
16296                }
16297            }
16298            if (weakRefs.size() > 0) {
16299                printed = true;
16300                pw.println("  * WEAK REFS:");
16301                for (int i = 0; i < weakRefs.size(); i++) {
16302                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16303                }
16304            }
16305        }
16306
16307        if (!printed) {
16308            pw.println("  (nothing)");
16309        }
16310    }
16311
16312    private static final int dumpProcessList(PrintWriter pw,
16313            ActivityManagerService service, List list,
16314            String prefix, String normalLabel, String persistentLabel,
16315            String dumpPackage) {
16316        int numPers = 0;
16317        final int N = list.size()-1;
16318        for (int i=N; i>=0; i--) {
16319            ProcessRecord r = (ProcessRecord)list.get(i);
16320            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16321                continue;
16322            }
16323            pw.println(String.format("%s%s #%2d: %s",
16324                    prefix, (r.persistent ? persistentLabel : normalLabel),
16325                    i, r.toString()));
16326            if (r.persistent) {
16327                numPers++;
16328            }
16329        }
16330        return numPers;
16331    }
16332
16333    private static final boolean dumpProcessOomList(PrintWriter pw,
16334            ActivityManagerService service, List<ProcessRecord> origList,
16335            String prefix, String normalLabel, String persistentLabel,
16336            boolean inclDetails, String dumpPackage) {
16337
16338        ArrayList<Pair<ProcessRecord, Integer>> list
16339                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16340        for (int i=0; i<origList.size(); i++) {
16341            ProcessRecord r = origList.get(i);
16342            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16343                continue;
16344            }
16345            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16346        }
16347
16348        if (list.size() <= 0) {
16349            return false;
16350        }
16351
16352        Comparator<Pair<ProcessRecord, Integer>> comparator
16353                = new Comparator<Pair<ProcessRecord, Integer>>() {
16354            @Override
16355            public int compare(Pair<ProcessRecord, Integer> object1,
16356                    Pair<ProcessRecord, Integer> object2) {
16357                if (object1.first.setAdj != object2.first.setAdj) {
16358                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16359                }
16360                if (object1.first.setProcState != object2.first.setProcState) {
16361                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16362                }
16363                if (object1.second.intValue() != object2.second.intValue()) {
16364                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16365                }
16366                return 0;
16367            }
16368        };
16369
16370        Collections.sort(list, comparator);
16371
16372        final long curRealtime = SystemClock.elapsedRealtime();
16373        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16374        final long curUptime = SystemClock.uptimeMillis();
16375        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16376
16377        for (int i=list.size()-1; i>=0; i--) {
16378            ProcessRecord r = list.get(i).first;
16379            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16380            char schedGroup;
16381            switch (r.setSchedGroup) {
16382                case ProcessList.SCHED_GROUP_BACKGROUND:
16383                    schedGroup = 'B';
16384                    break;
16385                case ProcessList.SCHED_GROUP_DEFAULT:
16386                    schedGroup = 'F';
16387                    break;
16388                case ProcessList.SCHED_GROUP_TOP_APP:
16389                    schedGroup = 'T';
16390                    break;
16391                default:
16392                    schedGroup = '?';
16393                    break;
16394            }
16395            char foreground;
16396            if (r.foregroundActivities) {
16397                foreground = 'A';
16398            } else if (r.foregroundServices) {
16399                foreground = 'S';
16400            } else {
16401                foreground = ' ';
16402            }
16403            String procState = ProcessList.makeProcStateString(r.curProcState);
16404            pw.print(prefix);
16405            pw.print(r.persistent ? persistentLabel : normalLabel);
16406            pw.print(" #");
16407            int num = (origList.size()-1)-list.get(i).second;
16408            if (num < 10) pw.print(' ');
16409            pw.print(num);
16410            pw.print(": ");
16411            pw.print(oomAdj);
16412            pw.print(' ');
16413            pw.print(schedGroup);
16414            pw.print('/');
16415            pw.print(foreground);
16416            pw.print('/');
16417            pw.print(procState);
16418            pw.print(" trm:");
16419            if (r.trimMemoryLevel < 10) pw.print(' ');
16420            pw.print(r.trimMemoryLevel);
16421            pw.print(' ');
16422            pw.print(r.toShortString());
16423            pw.print(" (");
16424            pw.print(r.adjType);
16425            pw.println(')');
16426            if (r.adjSource != null || r.adjTarget != null) {
16427                pw.print(prefix);
16428                pw.print("    ");
16429                if (r.adjTarget instanceof ComponentName) {
16430                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16431                } else if (r.adjTarget != null) {
16432                    pw.print(r.adjTarget.toString());
16433                } else {
16434                    pw.print("{null}");
16435                }
16436                pw.print("<=");
16437                if (r.adjSource instanceof ProcessRecord) {
16438                    pw.print("Proc{");
16439                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16440                    pw.println("}");
16441                } else if (r.adjSource != null) {
16442                    pw.println(r.adjSource.toString());
16443                } else {
16444                    pw.println("{null}");
16445                }
16446            }
16447            if (inclDetails) {
16448                pw.print(prefix);
16449                pw.print("    ");
16450                pw.print("oom: max="); pw.print(r.maxAdj);
16451                pw.print(" curRaw="); pw.print(r.curRawAdj);
16452                pw.print(" setRaw="); pw.print(r.setRawAdj);
16453                pw.print(" cur="); pw.print(r.curAdj);
16454                pw.print(" set="); pw.println(r.setAdj);
16455                pw.print(prefix);
16456                pw.print("    ");
16457                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16458                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16459                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16460                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16461                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16462                pw.println();
16463                pw.print(prefix);
16464                pw.print("    ");
16465                pw.print("cached="); pw.print(r.cached);
16466                pw.print(" empty="); pw.print(r.empty);
16467                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16468
16469                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16470                    if (r.lastWakeTime != 0) {
16471                        long wtime;
16472                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16473                        synchronized (stats) {
16474                            wtime = stats.getProcessWakeTime(r.info.uid,
16475                                    r.pid, curRealtime);
16476                        }
16477                        long timeUsed = wtime - r.lastWakeTime;
16478                        pw.print(prefix);
16479                        pw.print("    ");
16480                        pw.print("keep awake over ");
16481                        TimeUtils.formatDuration(realtimeSince, pw);
16482                        pw.print(" used ");
16483                        TimeUtils.formatDuration(timeUsed, pw);
16484                        pw.print(" (");
16485                        pw.print((timeUsed*100)/realtimeSince);
16486                        pw.println("%)");
16487                    }
16488                    if (r.lastCpuTime != 0) {
16489                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16490                        pw.print(prefix);
16491                        pw.print("    ");
16492                        pw.print("run cpu over ");
16493                        TimeUtils.formatDuration(uptimeSince, pw);
16494                        pw.print(" used ");
16495                        TimeUtils.formatDuration(timeUsed, pw);
16496                        pw.print(" (");
16497                        pw.print((timeUsed*100)/uptimeSince);
16498                        pw.println("%)");
16499                    }
16500                }
16501            }
16502        }
16503        return true;
16504    }
16505
16506    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16507            String[] args) {
16508        ArrayList<ProcessRecord> procs;
16509        synchronized (this) {
16510            if (args != null && args.length > start
16511                    && args[start].charAt(0) != '-') {
16512                procs = new ArrayList<ProcessRecord>();
16513                int pid = -1;
16514                try {
16515                    pid = Integer.parseInt(args[start]);
16516                } catch (NumberFormatException e) {
16517                }
16518                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16519                    ProcessRecord proc = mLruProcesses.get(i);
16520                    if (proc.pid == pid) {
16521                        procs.add(proc);
16522                    } else if (allPkgs && proc.pkgList != null
16523                            && proc.pkgList.containsKey(args[start])) {
16524                        procs.add(proc);
16525                    } else if (proc.processName.equals(args[start])) {
16526                        procs.add(proc);
16527                    }
16528                }
16529                if (procs.size() <= 0) {
16530                    return null;
16531                }
16532            } else {
16533                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16534            }
16535        }
16536        return procs;
16537    }
16538
16539    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16540            PrintWriter pw, String[] args) {
16541        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16542        if (procs == null) {
16543            pw.println("No process found for: " + args[0]);
16544            return;
16545        }
16546
16547        long uptime = SystemClock.uptimeMillis();
16548        long realtime = SystemClock.elapsedRealtime();
16549        pw.println("Applications Graphics Acceleration Info:");
16550        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16551
16552        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16553            ProcessRecord r = procs.get(i);
16554            if (r.thread != null) {
16555                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16556                pw.flush();
16557                try {
16558                    TransferPipe tp = new TransferPipe();
16559                    try {
16560                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16561                        tp.go(fd);
16562                    } finally {
16563                        tp.kill();
16564                    }
16565                } catch (IOException e) {
16566                    pw.println("Failure while dumping the app: " + r);
16567                    pw.flush();
16568                } catch (RemoteException e) {
16569                    pw.println("Got a RemoteException while dumping the app " + r);
16570                    pw.flush();
16571                }
16572            }
16573        }
16574    }
16575
16576    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16577        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16578        if (procs == null) {
16579            pw.println("No process found for: " + args[0]);
16580            return;
16581        }
16582
16583        pw.println("Applications Database Info:");
16584
16585        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16586            ProcessRecord r = procs.get(i);
16587            if (r.thread != null) {
16588                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16589                pw.flush();
16590                try {
16591                    TransferPipe tp = new TransferPipe();
16592                    try {
16593                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16594                        tp.go(fd);
16595                    } finally {
16596                        tp.kill();
16597                    }
16598                } catch (IOException e) {
16599                    pw.println("Failure while dumping the app: " + r);
16600                    pw.flush();
16601                } catch (RemoteException e) {
16602                    pw.println("Got a RemoteException while dumping the app " + r);
16603                    pw.flush();
16604                }
16605            }
16606        }
16607    }
16608
16609    final static class MemItem {
16610        final boolean isProc;
16611        final String label;
16612        final String shortLabel;
16613        final long pss;
16614        final long swapPss;
16615        final int id;
16616        final boolean hasActivities;
16617        ArrayList<MemItem> subitems;
16618
16619        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16620                boolean _hasActivities) {
16621            isProc = true;
16622            label = _label;
16623            shortLabel = _shortLabel;
16624            pss = _pss;
16625            swapPss = _swapPss;
16626            id = _id;
16627            hasActivities = _hasActivities;
16628        }
16629
16630        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16631            isProc = false;
16632            label = _label;
16633            shortLabel = _shortLabel;
16634            pss = _pss;
16635            swapPss = _swapPss;
16636            id = _id;
16637            hasActivities = false;
16638        }
16639    }
16640
16641    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16642            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16643        if (sort && !isCompact) {
16644            Collections.sort(items, new Comparator<MemItem>() {
16645                @Override
16646                public int compare(MemItem lhs, MemItem rhs) {
16647                    if (lhs.pss < rhs.pss) {
16648                        return 1;
16649                    } else if (lhs.pss > rhs.pss) {
16650                        return -1;
16651                    }
16652                    return 0;
16653                }
16654            });
16655        }
16656
16657        for (int i=0; i<items.size(); i++) {
16658            MemItem mi = items.get(i);
16659            if (!isCompact) {
16660                if (dumpSwapPss) {
16661                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16662                            mi.label, stringifyKBSize(mi.swapPss));
16663                } else {
16664                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16665                }
16666            } else if (mi.isProc) {
16667                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16668                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16669                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16670                pw.println(mi.hasActivities ? ",a" : ",e");
16671            } else {
16672                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16673                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16674            }
16675            if (mi.subitems != null) {
16676                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16677                        true, isCompact, dumpSwapPss);
16678            }
16679        }
16680    }
16681
16682    // These are in KB.
16683    static final long[] DUMP_MEM_BUCKETS = new long[] {
16684        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16685        120*1024, 160*1024, 200*1024,
16686        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16687        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16688    };
16689
16690    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16691            boolean stackLike) {
16692        int start = label.lastIndexOf('.');
16693        if (start >= 0) start++;
16694        else start = 0;
16695        int end = label.length();
16696        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16697            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16698                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16699                out.append(bucket);
16700                out.append(stackLike ? "MB." : "MB ");
16701                out.append(label, start, end);
16702                return;
16703            }
16704        }
16705        out.append(memKB/1024);
16706        out.append(stackLike ? "MB." : "MB ");
16707        out.append(label, start, end);
16708    }
16709
16710    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16711            ProcessList.NATIVE_ADJ,
16712            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16713            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16714            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16715            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16716            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16717            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16718    };
16719    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16720            "Native",
16721            "System", "Persistent", "Persistent Service", "Foreground",
16722            "Visible", "Perceptible",
16723            "Heavy Weight", "Backup",
16724            "A Services", "Home",
16725            "Previous", "B Services", "Cached"
16726    };
16727    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16728            "native",
16729            "sys", "pers", "persvc", "fore",
16730            "vis", "percept",
16731            "heavy", "backup",
16732            "servicea", "home",
16733            "prev", "serviceb", "cached"
16734    };
16735
16736    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16737            long realtime, boolean isCheckinRequest, boolean isCompact) {
16738        if (isCompact) {
16739            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16740        }
16741        if (isCheckinRequest || isCompact) {
16742            // short checkin version
16743            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16744        } else {
16745            pw.println("Applications Memory Usage (in Kilobytes):");
16746            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16747        }
16748    }
16749
16750    private static final int KSM_SHARED = 0;
16751    private static final int KSM_SHARING = 1;
16752    private static final int KSM_UNSHARED = 2;
16753    private static final int KSM_VOLATILE = 3;
16754
16755    private final long[] getKsmInfo() {
16756        long[] longOut = new long[4];
16757        final int[] SINGLE_LONG_FORMAT = new int[] {
16758            PROC_SPACE_TERM| PROC_OUT_LONG
16759        };
16760        long[] longTmp = new long[1];
16761        readProcFile("/sys/kernel/mm/ksm/pages_shared",
16762                SINGLE_LONG_FORMAT, null, longTmp, null);
16763        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16764        longTmp[0] = 0;
16765        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16766                SINGLE_LONG_FORMAT, null, longTmp, null);
16767        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16768        longTmp[0] = 0;
16769        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16770                SINGLE_LONG_FORMAT, null, longTmp, null);
16771        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16772        longTmp[0] = 0;
16773        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16774                SINGLE_LONG_FORMAT, null, longTmp, null);
16775        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16776        return longOut;
16777    }
16778
16779    private static String stringifySize(long size, int order) {
16780        Locale locale = Locale.US;
16781        switch (order) {
16782            case 1:
16783                return String.format(locale, "%,13d", size);
16784            case 1024:
16785                return String.format(locale, "%,9dK", size / 1024);
16786            case 1024 * 1024:
16787                return String.format(locale, "%,5dM", size / 1024 / 1024);
16788            case 1024 * 1024 * 1024:
16789                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16790            default:
16791                throw new IllegalArgumentException("Invalid size order");
16792        }
16793    }
16794
16795    private static String stringifyKBSize(long size) {
16796        return stringifySize(size * 1024, 1024);
16797    }
16798
16799    // Update this version number in case you change the 'compact' format
16800    private static final int MEMINFO_COMPACT_VERSION = 1;
16801
16802    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16803            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16804        boolean dumpDetails = false;
16805        boolean dumpFullDetails = false;
16806        boolean dumpDalvik = false;
16807        boolean dumpSummaryOnly = false;
16808        boolean dumpUnreachable = false;
16809        boolean oomOnly = false;
16810        boolean isCompact = false;
16811        boolean localOnly = false;
16812        boolean packages = false;
16813        boolean isCheckinRequest = false;
16814        boolean dumpSwapPss = false;
16815
16816        int opti = 0;
16817        while (opti < args.length) {
16818            String opt = args[opti];
16819            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16820                break;
16821            }
16822            opti++;
16823            if ("-a".equals(opt)) {
16824                dumpDetails = true;
16825                dumpFullDetails = true;
16826                dumpDalvik = true;
16827                dumpSwapPss = true;
16828            } else if ("-d".equals(opt)) {
16829                dumpDalvik = true;
16830            } else if ("-c".equals(opt)) {
16831                isCompact = true;
16832            } else if ("-s".equals(opt)) {
16833                dumpDetails = true;
16834                dumpSummaryOnly = true;
16835            } else if ("-S".equals(opt)) {
16836                dumpSwapPss = true;
16837            } else if ("--unreachable".equals(opt)) {
16838                dumpUnreachable = true;
16839            } else if ("--oom".equals(opt)) {
16840                oomOnly = true;
16841            } else if ("--local".equals(opt)) {
16842                localOnly = true;
16843            } else if ("--package".equals(opt)) {
16844                packages = true;
16845            } else if ("--checkin".equals(opt)) {
16846                isCheckinRequest = true;
16847
16848            } else if ("-h".equals(opt)) {
16849                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16850                pw.println("  -a: include all available information for each process.");
16851                pw.println("  -d: include dalvik details.");
16852                pw.println("  -c: dump in a compact machine-parseable representation.");
16853                pw.println("  -s: dump only summary of application memory usage.");
16854                pw.println("  -S: dump also SwapPss.");
16855                pw.println("  --oom: only show processes organized by oom adj.");
16856                pw.println("  --local: only collect details locally, don't call process.");
16857                pw.println("  --package: interpret process arg as package, dumping all");
16858                pw.println("             processes that have loaded that package.");
16859                pw.println("  --checkin: dump data for a checkin");
16860                pw.println("If [process] is specified it can be the name or ");
16861                pw.println("pid of a specific process to dump.");
16862                return;
16863            } else {
16864                pw.println("Unknown argument: " + opt + "; use -h for help");
16865            }
16866        }
16867
16868        long uptime = SystemClock.uptimeMillis();
16869        long realtime = SystemClock.elapsedRealtime();
16870        final long[] tmpLong = new long[1];
16871
16872        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16873        if (procs == null) {
16874            // No Java processes.  Maybe they want to print a native process.
16875            if (args != null && args.length > opti
16876                    && args[opti].charAt(0) != '-') {
16877                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16878                        = new ArrayList<ProcessCpuTracker.Stats>();
16879                updateCpuStatsNow();
16880                int findPid = -1;
16881                try {
16882                    findPid = Integer.parseInt(args[opti]);
16883                } catch (NumberFormatException e) {
16884                }
16885                synchronized (mProcessCpuTracker) {
16886                    final int N = mProcessCpuTracker.countStats();
16887                    for (int i=0; i<N; i++) {
16888                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16889                        if (st.pid == findPid || (st.baseName != null
16890                                && st.baseName.equals(args[opti]))) {
16891                            nativeProcs.add(st);
16892                        }
16893                    }
16894                }
16895                if (nativeProcs.size() > 0) {
16896                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16897                            isCompact);
16898                    Debug.MemoryInfo mi = null;
16899                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16900                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16901                        final int pid = r.pid;
16902                        if (!isCheckinRequest && dumpDetails) {
16903                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16904                        }
16905                        if (mi == null) {
16906                            mi = new Debug.MemoryInfo();
16907                        }
16908                        if (dumpDetails || (!brief && !oomOnly)) {
16909                            Debug.getMemoryInfo(pid, mi);
16910                        } else {
16911                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16912                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16913                        }
16914                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16915                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16916                        if (isCheckinRequest) {
16917                            pw.println();
16918                        }
16919                    }
16920                    return;
16921                }
16922            }
16923            pw.println("No process found for: " + args[opti]);
16924            return;
16925        }
16926
16927        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16928            dumpDetails = true;
16929        }
16930
16931        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16932
16933        String[] innerArgs = new String[args.length-opti];
16934        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16935
16936        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16937        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16938        long nativePss = 0;
16939        long nativeSwapPss = 0;
16940        long dalvikPss = 0;
16941        long dalvikSwapPss = 0;
16942        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16943                EmptyArray.LONG;
16944        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16945                EmptyArray.LONG;
16946        long otherPss = 0;
16947        long otherSwapPss = 0;
16948        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16949        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16950
16951        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16952        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16953        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16954                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16955
16956        long totalPss = 0;
16957        long totalSwapPss = 0;
16958        long cachedPss = 0;
16959        long cachedSwapPss = 0;
16960        boolean hasSwapPss = false;
16961
16962        Debug.MemoryInfo mi = null;
16963        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16964            final ProcessRecord r = procs.get(i);
16965            final IApplicationThread thread;
16966            final int pid;
16967            final int oomAdj;
16968            final boolean hasActivities;
16969            synchronized (this) {
16970                thread = r.thread;
16971                pid = r.pid;
16972                oomAdj = r.getSetAdjWithServices();
16973                hasActivities = r.activities.size() > 0;
16974            }
16975            if (thread != null) {
16976                if (!isCheckinRequest && dumpDetails) {
16977                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16978                }
16979                if (mi == null) {
16980                    mi = new Debug.MemoryInfo();
16981                }
16982                if (dumpDetails || (!brief && !oomOnly)) {
16983                    Debug.getMemoryInfo(pid, mi);
16984                    hasSwapPss = mi.hasSwappedOutPss;
16985                } else {
16986                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16987                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16988                }
16989                if (dumpDetails) {
16990                    if (localOnly) {
16991                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16992                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16993                        if (isCheckinRequest) {
16994                            pw.println();
16995                        }
16996                    } else {
16997                        pw.flush();
16998                        try {
16999                            TransferPipe tp = new TransferPipe();
17000                            try {
17001                                thread.dumpMemInfo(tp.getWriteFd(),
17002                                        mi, isCheckinRequest, dumpFullDetails,
17003                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17004                                tp.go(fd);
17005                            } finally {
17006                                tp.kill();
17007                            }
17008                        } catch (IOException e) {
17009                            if (!isCheckinRequest) {
17010                                pw.println("Got IoException!");
17011                                pw.flush();
17012                            }
17013                        } catch (RemoteException e) {
17014                            if (!isCheckinRequest) {
17015                                pw.println("Got RemoteException!");
17016                                pw.flush();
17017                            }
17018                        }
17019                    }
17020                }
17021
17022                final long myTotalPss = mi.getTotalPss();
17023                final long myTotalUss = mi.getTotalUss();
17024                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17025
17026                synchronized (this) {
17027                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17028                        // Record this for posterity if the process has been stable.
17029                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17030                    }
17031                }
17032
17033                if (!isCheckinRequest && mi != null) {
17034                    totalPss += myTotalPss;
17035                    totalSwapPss += myTotalSwapPss;
17036                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17037                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17038                            myTotalSwapPss, pid, hasActivities);
17039                    procMems.add(pssItem);
17040                    procMemsMap.put(pid, pssItem);
17041
17042                    nativePss += mi.nativePss;
17043                    nativeSwapPss += mi.nativeSwappedOutPss;
17044                    dalvikPss += mi.dalvikPss;
17045                    dalvikSwapPss += mi.dalvikSwappedOutPss;
17046                    for (int j=0; j<dalvikSubitemPss.length; j++) {
17047                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17048                        dalvikSubitemSwapPss[j] +=
17049                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17050                    }
17051                    otherPss += mi.otherPss;
17052                    otherSwapPss += mi.otherSwappedOutPss;
17053                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17054                        long mem = mi.getOtherPss(j);
17055                        miscPss[j] += mem;
17056                        otherPss -= mem;
17057                        mem = mi.getOtherSwappedOutPss(j);
17058                        miscSwapPss[j] += mem;
17059                        otherSwapPss -= mem;
17060                    }
17061
17062                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17063                        cachedPss += myTotalPss;
17064                        cachedSwapPss += myTotalSwapPss;
17065                    }
17066
17067                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17068                        if (oomIndex == (oomPss.length - 1)
17069                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17070                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17071                            oomPss[oomIndex] += myTotalPss;
17072                            oomSwapPss[oomIndex] += myTotalSwapPss;
17073                            if (oomProcs[oomIndex] == null) {
17074                                oomProcs[oomIndex] = new ArrayList<MemItem>();
17075                            }
17076                            oomProcs[oomIndex].add(pssItem);
17077                            break;
17078                        }
17079                    }
17080                }
17081            }
17082        }
17083
17084        long nativeProcTotalPss = 0;
17085
17086        if (!isCheckinRequest && procs.size() > 1 && !packages) {
17087            // If we are showing aggregations, also look for native processes to
17088            // include so that our aggregations are more accurate.
17089            updateCpuStatsNow();
17090            mi = null;
17091            synchronized (mProcessCpuTracker) {
17092                final int N = mProcessCpuTracker.countStats();
17093                for (int i=0; i<N; i++) {
17094                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17095                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17096                        if (mi == null) {
17097                            mi = new Debug.MemoryInfo();
17098                        }
17099                        if (!brief && !oomOnly) {
17100                            Debug.getMemoryInfo(st.pid, mi);
17101                        } else {
17102                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17103                            mi.nativePrivateDirty = (int)tmpLong[0];
17104                        }
17105
17106                        final long myTotalPss = mi.getTotalPss();
17107                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17108                        totalPss += myTotalPss;
17109                        nativeProcTotalPss += myTotalPss;
17110
17111                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17112                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17113                        procMems.add(pssItem);
17114
17115                        nativePss += mi.nativePss;
17116                        nativeSwapPss += mi.nativeSwappedOutPss;
17117                        dalvikPss += mi.dalvikPss;
17118                        dalvikSwapPss += mi.dalvikSwappedOutPss;
17119                        for (int j=0; j<dalvikSubitemPss.length; j++) {
17120                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17121                            dalvikSubitemSwapPss[j] +=
17122                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17123                        }
17124                        otherPss += mi.otherPss;
17125                        otherSwapPss += mi.otherSwappedOutPss;
17126                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17127                            long mem = mi.getOtherPss(j);
17128                            miscPss[j] += mem;
17129                            otherPss -= mem;
17130                            mem = mi.getOtherSwappedOutPss(j);
17131                            miscSwapPss[j] += mem;
17132                            otherSwapPss -= mem;
17133                        }
17134                        oomPss[0] += myTotalPss;
17135                        oomSwapPss[0] += myTotalSwapPss;
17136                        if (oomProcs[0] == null) {
17137                            oomProcs[0] = new ArrayList<MemItem>();
17138                        }
17139                        oomProcs[0].add(pssItem);
17140                    }
17141                }
17142            }
17143
17144            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17145
17146            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17147            final MemItem dalvikItem =
17148                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17149            if (dalvikSubitemPss.length > 0) {
17150                dalvikItem.subitems = new ArrayList<MemItem>();
17151                for (int j=0; j<dalvikSubitemPss.length; j++) {
17152                    final String name = Debug.MemoryInfo.getOtherLabel(
17153                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
17154                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17155                                    dalvikSubitemSwapPss[j], j));
17156                }
17157            }
17158            catMems.add(dalvikItem);
17159            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17160            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17161                String label = Debug.MemoryInfo.getOtherLabel(j);
17162                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17163            }
17164
17165            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17166            for (int j=0; j<oomPss.length; j++) {
17167                if (oomPss[j] != 0) {
17168                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17169                            : DUMP_MEM_OOM_LABEL[j];
17170                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17171                            DUMP_MEM_OOM_ADJ[j]);
17172                    item.subitems = oomProcs[j];
17173                    oomMems.add(item);
17174                }
17175            }
17176
17177            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17178            if (!brief && !oomOnly && !isCompact) {
17179                pw.println();
17180                pw.println("Total PSS by process:");
17181                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17182                pw.println();
17183            }
17184            if (!isCompact) {
17185                pw.println("Total PSS by OOM adjustment:");
17186            }
17187            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17188            if (!brief && !oomOnly) {
17189                PrintWriter out = categoryPw != null ? categoryPw : pw;
17190                if (!isCompact) {
17191                    out.println();
17192                    out.println("Total PSS by category:");
17193                }
17194                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17195            }
17196            if (!isCompact) {
17197                pw.println();
17198            }
17199            MemInfoReader memInfo = new MemInfoReader();
17200            memInfo.readMemInfo();
17201            if (nativeProcTotalPss > 0) {
17202                synchronized (this) {
17203                    final long cachedKb = memInfo.getCachedSizeKb();
17204                    final long freeKb = memInfo.getFreeSizeKb();
17205                    final long zramKb = memInfo.getZramTotalSizeKb();
17206                    final long kernelKb = memInfo.getKernelUsedSizeKb();
17207                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17208                            kernelKb*1024, nativeProcTotalPss*1024);
17209                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17210                            nativeProcTotalPss);
17211                }
17212            }
17213            if (!brief) {
17214                if (!isCompact) {
17215                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17216                    pw.print(" (status ");
17217                    switch (mLastMemoryLevel) {
17218                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17219                            pw.println("normal)");
17220                            break;
17221                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17222                            pw.println("moderate)");
17223                            break;
17224                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
17225                            pw.println("low)");
17226                            break;
17227                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17228                            pw.println("critical)");
17229                            break;
17230                        default:
17231                            pw.print(mLastMemoryLevel);
17232                            pw.println(")");
17233                            break;
17234                    }
17235                    pw.print(" Free RAM: ");
17236                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17237                            + memInfo.getFreeSizeKb()));
17238                    pw.print(" (");
17239                    pw.print(stringifyKBSize(cachedPss));
17240                    pw.print(" cached pss + ");
17241                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17242                    pw.print(" cached kernel + ");
17243                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17244                    pw.println(" free)");
17245                } else {
17246                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17247                    pw.print(cachedPss + memInfo.getCachedSizeKb()
17248                            + memInfo.getFreeSizeKb()); pw.print(",");
17249                    pw.println(totalPss - cachedPss);
17250                }
17251            }
17252            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17253                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17254                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17255            if (!isCompact) {
17256                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17257                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17258                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17259                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17260                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17261            } else {
17262                pw.print("lostram,"); pw.println(lostRAM);
17263            }
17264            if (!brief) {
17265                if (memInfo.getZramTotalSizeKb() != 0) {
17266                    if (!isCompact) {
17267                        pw.print("     ZRAM: ");
17268                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17269                                pw.print(" physical used for ");
17270                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17271                                        - memInfo.getSwapFreeSizeKb()));
17272                                pw.print(" in swap (");
17273                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17274                                pw.println(" total swap)");
17275                    } else {
17276                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17277                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17278                                pw.println(memInfo.getSwapFreeSizeKb());
17279                    }
17280                }
17281                final long[] ksm = getKsmInfo();
17282                if (!isCompact) {
17283                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17284                            || ksm[KSM_VOLATILE] != 0) {
17285                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17286                                pw.print(" saved from shared ");
17287                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17288                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17289                                pw.print(" unshared; ");
17290                                pw.print(stringifyKBSize(
17291                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
17292                    }
17293                    pw.print("   Tuning: ");
17294                    pw.print(ActivityManager.staticGetMemoryClass());
17295                    pw.print(" (large ");
17296                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17297                    pw.print("), oom ");
17298                    pw.print(stringifySize(
17299                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17300                    pw.print(", restore limit ");
17301                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17302                    if (ActivityManager.isLowRamDeviceStatic()) {
17303                        pw.print(" (low-ram)");
17304                    }
17305                    if (ActivityManager.isHighEndGfx()) {
17306                        pw.print(" (high-end-gfx)");
17307                    }
17308                    pw.println();
17309                } else {
17310                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17311                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17312                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17313                    pw.print("tuning,");
17314                    pw.print(ActivityManager.staticGetMemoryClass());
17315                    pw.print(',');
17316                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17317                    pw.print(',');
17318                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17319                    if (ActivityManager.isLowRamDeviceStatic()) {
17320                        pw.print(",low-ram");
17321                    }
17322                    if (ActivityManager.isHighEndGfx()) {
17323                        pw.print(",high-end-gfx");
17324                    }
17325                    pw.println();
17326                }
17327            }
17328        }
17329    }
17330
17331    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17332            long memtrack, String name) {
17333        sb.append("  ");
17334        sb.append(ProcessList.makeOomAdjString(oomAdj));
17335        sb.append(' ');
17336        sb.append(ProcessList.makeProcStateString(procState));
17337        sb.append(' ');
17338        ProcessList.appendRamKb(sb, pss);
17339        sb.append(": ");
17340        sb.append(name);
17341        if (memtrack > 0) {
17342            sb.append(" (");
17343            sb.append(stringifyKBSize(memtrack));
17344            sb.append(" memtrack)");
17345        }
17346    }
17347
17348    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17349        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17350        sb.append(" (pid ");
17351        sb.append(mi.pid);
17352        sb.append(") ");
17353        sb.append(mi.adjType);
17354        sb.append('\n');
17355        if (mi.adjReason != null) {
17356            sb.append("                      ");
17357            sb.append(mi.adjReason);
17358            sb.append('\n');
17359        }
17360    }
17361
17362    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17363        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17364        for (int i=0, N=memInfos.size(); i<N; i++) {
17365            ProcessMemInfo mi = memInfos.get(i);
17366            infoMap.put(mi.pid, mi);
17367        }
17368        updateCpuStatsNow();
17369        long[] memtrackTmp = new long[1];
17370        final List<ProcessCpuTracker.Stats> stats;
17371        // Get a list of Stats that have vsize > 0
17372        synchronized (mProcessCpuTracker) {
17373            stats = mProcessCpuTracker.getStats((st) -> {
17374                return st.vsize > 0;
17375            });
17376        }
17377        final int statsCount = stats.size();
17378        for (int i = 0; i < statsCount; i++) {
17379            ProcessCpuTracker.Stats st = stats.get(i);
17380            long pss = Debug.getPss(st.pid, null, memtrackTmp);
17381            if (pss > 0) {
17382                if (infoMap.indexOfKey(st.pid) < 0) {
17383                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17384                            ProcessList.NATIVE_ADJ, -1, "native", null);
17385                    mi.pss = pss;
17386                    mi.memtrack = memtrackTmp[0];
17387                    memInfos.add(mi);
17388                }
17389            }
17390        }
17391
17392        long totalPss = 0;
17393        long totalMemtrack = 0;
17394        for (int i=0, N=memInfos.size(); i<N; i++) {
17395            ProcessMemInfo mi = memInfos.get(i);
17396            if (mi.pss == 0) {
17397                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17398                mi.memtrack = memtrackTmp[0];
17399            }
17400            totalPss += mi.pss;
17401            totalMemtrack += mi.memtrack;
17402        }
17403        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17404            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17405                if (lhs.oomAdj != rhs.oomAdj) {
17406                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17407                }
17408                if (lhs.pss != rhs.pss) {
17409                    return lhs.pss < rhs.pss ? 1 : -1;
17410                }
17411                return 0;
17412            }
17413        });
17414
17415        StringBuilder tag = new StringBuilder(128);
17416        StringBuilder stack = new StringBuilder(128);
17417        tag.append("Low on memory -- ");
17418        appendMemBucket(tag, totalPss, "total", false);
17419        appendMemBucket(stack, totalPss, "total", true);
17420
17421        StringBuilder fullNativeBuilder = new StringBuilder(1024);
17422        StringBuilder shortNativeBuilder = new StringBuilder(1024);
17423        StringBuilder fullJavaBuilder = new StringBuilder(1024);
17424
17425        boolean firstLine = true;
17426        int lastOomAdj = Integer.MIN_VALUE;
17427        long extraNativeRam = 0;
17428        long extraNativeMemtrack = 0;
17429        long cachedPss = 0;
17430        for (int i=0, N=memInfos.size(); i<N; i++) {
17431            ProcessMemInfo mi = memInfos.get(i);
17432
17433            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17434                cachedPss += mi.pss;
17435            }
17436
17437            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17438                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17439                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17440                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17441                if (lastOomAdj != mi.oomAdj) {
17442                    lastOomAdj = mi.oomAdj;
17443                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17444                        tag.append(" / ");
17445                    }
17446                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17447                        if (firstLine) {
17448                            stack.append(":");
17449                            firstLine = false;
17450                        }
17451                        stack.append("\n\t at ");
17452                    } else {
17453                        stack.append("$");
17454                    }
17455                } else {
17456                    tag.append(" ");
17457                    stack.append("$");
17458                }
17459                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17460                    appendMemBucket(tag, mi.pss, mi.name, false);
17461                }
17462                appendMemBucket(stack, mi.pss, mi.name, true);
17463                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17464                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17465                    stack.append("(");
17466                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17467                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17468                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17469                            stack.append(":");
17470                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17471                        }
17472                    }
17473                    stack.append(")");
17474                }
17475            }
17476
17477            appendMemInfo(fullNativeBuilder, mi);
17478            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17479                // The short form only has native processes that are >= 512K.
17480                if (mi.pss >= 512) {
17481                    appendMemInfo(shortNativeBuilder, mi);
17482                } else {
17483                    extraNativeRam += mi.pss;
17484                    extraNativeMemtrack += mi.memtrack;
17485                }
17486            } else {
17487                // Short form has all other details, but if we have collected RAM
17488                // from smaller native processes let's dump a summary of that.
17489                if (extraNativeRam > 0) {
17490                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17491                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17492                    shortNativeBuilder.append('\n');
17493                    extraNativeRam = 0;
17494                }
17495                appendMemInfo(fullJavaBuilder, mi);
17496            }
17497        }
17498
17499        fullJavaBuilder.append("           ");
17500        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17501        fullJavaBuilder.append(": TOTAL");
17502        if (totalMemtrack > 0) {
17503            fullJavaBuilder.append(" (");
17504            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17505            fullJavaBuilder.append(" memtrack)");
17506        } else {
17507        }
17508        fullJavaBuilder.append("\n");
17509
17510        MemInfoReader memInfo = new MemInfoReader();
17511        memInfo.readMemInfo();
17512        final long[] infos = memInfo.getRawInfo();
17513
17514        StringBuilder memInfoBuilder = new StringBuilder(1024);
17515        Debug.getMemInfo(infos);
17516        memInfoBuilder.append("  MemInfo: ");
17517        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17518        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17519        memInfoBuilder.append(stringifyKBSize(
17520                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17521        memInfoBuilder.append(stringifyKBSize(
17522                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17523        memInfoBuilder.append(stringifyKBSize(
17524                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17525        memInfoBuilder.append("           ");
17526        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17527        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17528        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17529        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17530        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17531            memInfoBuilder.append("  ZRAM: ");
17532            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17533            memInfoBuilder.append(" RAM, ");
17534            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17535            memInfoBuilder.append(" swap total, ");
17536            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17537            memInfoBuilder.append(" swap free\n");
17538        }
17539        final long[] ksm = getKsmInfo();
17540        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17541                || ksm[KSM_VOLATILE] != 0) {
17542            memInfoBuilder.append("  KSM: ");
17543            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17544            memInfoBuilder.append(" saved from shared ");
17545            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17546            memInfoBuilder.append("\n       ");
17547            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17548            memInfoBuilder.append(" unshared; ");
17549            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17550            memInfoBuilder.append(" volatile\n");
17551        }
17552        memInfoBuilder.append("  Free RAM: ");
17553        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17554                + memInfo.getFreeSizeKb()));
17555        memInfoBuilder.append("\n");
17556        memInfoBuilder.append("  Used RAM: ");
17557        memInfoBuilder.append(stringifyKBSize(
17558                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17559        memInfoBuilder.append("\n");
17560        memInfoBuilder.append("  Lost RAM: ");
17561        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17562                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17563                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17564        memInfoBuilder.append("\n");
17565        Slog.i(TAG, "Low on memory:");
17566        Slog.i(TAG, shortNativeBuilder.toString());
17567        Slog.i(TAG, fullJavaBuilder.toString());
17568        Slog.i(TAG, memInfoBuilder.toString());
17569
17570        StringBuilder dropBuilder = new StringBuilder(1024);
17571        /*
17572        StringWriter oomSw = new StringWriter();
17573        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17574        StringWriter catSw = new StringWriter();
17575        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17576        String[] emptyArgs = new String[] { };
17577        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17578        oomPw.flush();
17579        String oomString = oomSw.toString();
17580        */
17581        dropBuilder.append("Low on memory:");
17582        dropBuilder.append(stack);
17583        dropBuilder.append('\n');
17584        dropBuilder.append(fullNativeBuilder);
17585        dropBuilder.append(fullJavaBuilder);
17586        dropBuilder.append('\n');
17587        dropBuilder.append(memInfoBuilder);
17588        dropBuilder.append('\n');
17589        /*
17590        dropBuilder.append(oomString);
17591        dropBuilder.append('\n');
17592        */
17593        StringWriter catSw = new StringWriter();
17594        synchronized (ActivityManagerService.this) {
17595            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17596            String[] emptyArgs = new String[] { };
17597            catPw.println();
17598            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17599            catPw.println();
17600            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17601                    false, null).dumpLocked();
17602            catPw.println();
17603            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17604            catPw.flush();
17605        }
17606        dropBuilder.append(catSw.toString());
17607        addErrorToDropBox("lowmem", null, "system_server", null,
17608                null, tag.toString(), dropBuilder.toString(), null, null);
17609        //Slog.i(TAG, "Sent to dropbox:");
17610        //Slog.i(TAG, dropBuilder.toString());
17611        synchronized (ActivityManagerService.this) {
17612            long now = SystemClock.uptimeMillis();
17613            if (mLastMemUsageReportTime < now) {
17614                mLastMemUsageReportTime = now;
17615            }
17616        }
17617    }
17618
17619    /**
17620     * Searches array of arguments for the specified string
17621     * @param args array of argument strings
17622     * @param value value to search for
17623     * @return true if the value is contained in the array
17624     */
17625    private static boolean scanArgs(String[] args, String value) {
17626        if (args != null) {
17627            for (String arg : args) {
17628                if (value.equals(arg)) {
17629                    return true;
17630                }
17631            }
17632        }
17633        return false;
17634    }
17635
17636    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17637            ContentProviderRecord cpr, boolean always) {
17638        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17639
17640        if (!inLaunching || always) {
17641            synchronized (cpr) {
17642                cpr.launchingApp = null;
17643                cpr.notifyAll();
17644            }
17645            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17646            String names[] = cpr.info.authority.split(";");
17647            for (int j = 0; j < names.length; j++) {
17648                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17649            }
17650        }
17651
17652        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17653            ContentProviderConnection conn = cpr.connections.get(i);
17654            if (conn.waiting) {
17655                // If this connection is waiting for the provider, then we don't
17656                // need to mess with its process unless we are always removing
17657                // or for some reason the provider is not currently launching.
17658                if (inLaunching && !always) {
17659                    continue;
17660                }
17661            }
17662            ProcessRecord capp = conn.client;
17663            conn.dead = true;
17664            if (conn.stableCount > 0) {
17665                if (!capp.persistent && capp.thread != null
17666                        && capp.pid != 0
17667                        && capp.pid != MY_PID) {
17668                    capp.kill("depends on provider "
17669                            + cpr.name.flattenToShortString()
17670                            + " in dying proc " + (proc != null ? proc.processName : "??")
17671                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17672                }
17673            } else if (capp.thread != null && conn.provider.provider != null) {
17674                try {
17675                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17676                } catch (RemoteException e) {
17677                }
17678                // In the protocol here, we don't expect the client to correctly
17679                // clean up this connection, we'll just remove it.
17680                cpr.connections.remove(i);
17681                if (conn.client.conProviders.remove(conn)) {
17682                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17683                }
17684            }
17685        }
17686
17687        if (inLaunching && always) {
17688            mLaunchingProviders.remove(cpr);
17689        }
17690        return inLaunching;
17691    }
17692
17693    /**
17694     * Main code for cleaning up a process when it has gone away.  This is
17695     * called both as a result of the process dying, or directly when stopping
17696     * a process when running in single process mode.
17697     *
17698     * @return Returns true if the given process has been restarted, so the
17699     * app that was passed in must remain on the process lists.
17700     */
17701    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17702            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17703        if (index >= 0) {
17704            removeLruProcessLocked(app);
17705            ProcessList.remove(app.pid);
17706        }
17707
17708        mProcessesToGc.remove(app);
17709        mPendingPssProcesses.remove(app);
17710
17711        // Dismiss any open dialogs.
17712        if (app.crashDialog != null && !app.forceCrashReport) {
17713            app.crashDialog.dismiss();
17714            app.crashDialog = null;
17715        }
17716        if (app.anrDialog != null) {
17717            app.anrDialog.dismiss();
17718            app.anrDialog = null;
17719        }
17720        if (app.waitDialog != null) {
17721            app.waitDialog.dismiss();
17722            app.waitDialog = null;
17723        }
17724
17725        app.crashing = false;
17726        app.notResponding = false;
17727
17728        app.resetPackageList(mProcessStats);
17729        app.unlinkDeathRecipient();
17730        app.makeInactive(mProcessStats);
17731        app.waitingToKill = null;
17732        app.forcingToForeground = null;
17733        updateProcessForegroundLocked(app, false, false);
17734        app.foregroundActivities = false;
17735        app.hasShownUi = false;
17736        app.treatLikeActivity = false;
17737        app.hasAboveClient = false;
17738        app.hasClientActivities = false;
17739
17740        mServices.killServicesLocked(app, allowRestart);
17741
17742        boolean restart = false;
17743
17744        // Remove published content providers.
17745        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17746            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17747            final boolean always = app.bad || !allowRestart;
17748            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17749            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17750                // We left the provider in the launching list, need to
17751                // restart it.
17752                restart = true;
17753            }
17754
17755            cpr.provider = null;
17756            cpr.proc = null;
17757        }
17758        app.pubProviders.clear();
17759
17760        // Take care of any launching providers waiting for this process.
17761        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17762            restart = true;
17763        }
17764
17765        // Unregister from connected content providers.
17766        if (!app.conProviders.isEmpty()) {
17767            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17768                ContentProviderConnection conn = app.conProviders.get(i);
17769                conn.provider.connections.remove(conn);
17770                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17771                        conn.provider.name);
17772            }
17773            app.conProviders.clear();
17774        }
17775
17776        // At this point there may be remaining entries in mLaunchingProviders
17777        // where we were the only one waiting, so they are no longer of use.
17778        // Look for these and clean up if found.
17779        // XXX Commented out for now.  Trying to figure out a way to reproduce
17780        // the actual situation to identify what is actually going on.
17781        if (false) {
17782            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17783                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17784                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17785                    synchronized (cpr) {
17786                        cpr.launchingApp = null;
17787                        cpr.notifyAll();
17788                    }
17789                }
17790            }
17791        }
17792
17793        skipCurrentReceiverLocked(app);
17794
17795        // Unregister any receivers.
17796        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17797            removeReceiverLocked(app.receivers.valueAt(i));
17798        }
17799        app.receivers.clear();
17800
17801        // If the app is undergoing backup, tell the backup manager about it
17802        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17803            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17804                    + mBackupTarget.appInfo + " died during backup");
17805            mHandler.post(new Runnable() {
17806                @Override
17807                public void run(){
17808                    try {
17809                        IBackupManager bm = IBackupManager.Stub.asInterface(
17810                                ServiceManager.getService(Context.BACKUP_SERVICE));
17811                        bm.agentDisconnected(app.info.packageName);
17812                    } catch (RemoteException e) {
17813                        // can't happen; backup manager is local
17814                    }
17815                }
17816            });
17817        }
17818
17819        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17820            ProcessChangeItem item = mPendingProcessChanges.get(i);
17821            if (item.pid == app.pid) {
17822                mPendingProcessChanges.remove(i);
17823                mAvailProcessChanges.add(item);
17824            }
17825        }
17826        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17827                null).sendToTarget();
17828
17829        // If the caller is restarting this app, then leave it in its
17830        // current lists and let the caller take care of it.
17831        if (restarting) {
17832            return false;
17833        }
17834
17835        if (!app.persistent || app.isolated) {
17836            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17837                    "Removing non-persistent process during cleanup: " + app);
17838            if (!replacingPid) {
17839                removeProcessNameLocked(app.processName, app.uid, app);
17840            }
17841            if (mHeavyWeightProcess == app) {
17842                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17843                        mHeavyWeightProcess.userId, 0));
17844                mHeavyWeightProcess = null;
17845            }
17846        } else if (!app.removed) {
17847            // This app is persistent, so we need to keep its record around.
17848            // If it is not already on the pending app list, add it there
17849            // and start a new process for it.
17850            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17851                mPersistentStartingProcesses.add(app);
17852                restart = true;
17853            }
17854        }
17855        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17856                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17857        mProcessesOnHold.remove(app);
17858
17859        if (app == mHomeProcess) {
17860            mHomeProcess = null;
17861        }
17862        if (app == mPreviousProcess) {
17863            mPreviousProcess = null;
17864        }
17865
17866        if (restart && !app.isolated) {
17867            // We have components that still need to be running in the
17868            // process, so re-launch it.
17869            if (index < 0) {
17870                ProcessList.remove(app.pid);
17871            }
17872            addProcessNameLocked(app);
17873            startProcessLocked(app, "restart", app.processName);
17874            return true;
17875        } else if (app.pid > 0 && app.pid != MY_PID) {
17876            // Goodbye!
17877            boolean removed;
17878            synchronized (mPidsSelfLocked) {
17879                mPidsSelfLocked.remove(app.pid);
17880                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17881            }
17882            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17883            if (app.isolated) {
17884                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17885            }
17886            app.setPid(0);
17887        }
17888        return false;
17889    }
17890
17891    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17892        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17893            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17894            if (cpr.launchingApp == app) {
17895                return true;
17896            }
17897        }
17898        return false;
17899    }
17900
17901    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17902        // Look through the content providers we are waiting to have launched,
17903        // and if any run in this process then either schedule a restart of
17904        // the process or kill the client waiting for it if this process has
17905        // gone bad.
17906        boolean restart = false;
17907        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17908            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17909            if (cpr.launchingApp == app) {
17910                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17911                    restart = true;
17912                } else {
17913                    removeDyingProviderLocked(app, cpr, true);
17914                }
17915            }
17916        }
17917        return restart;
17918    }
17919
17920    // =========================================================
17921    // SERVICES
17922    // =========================================================
17923
17924    @Override
17925    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17926            int flags) {
17927        enforceNotIsolatedCaller("getServices");
17928
17929        final int callingUid = Binder.getCallingUid();
17930        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
17931            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
17932        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
17933            callingUid);
17934        synchronized (this) {
17935            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
17936                allowed, canInteractAcrossUsers);
17937        }
17938    }
17939
17940    @Override
17941    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17942        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17943        synchronized (this) {
17944            return mServices.getRunningServiceControlPanelLocked(name);
17945        }
17946    }
17947
17948    @Override
17949    public ComponentName startService(IApplicationThread caller, Intent service,
17950            String resolvedType, boolean requireForeground, String callingPackage, int userId)
17951            throws TransactionTooLargeException {
17952        enforceNotIsolatedCaller("startService");
17953        // Refuse possible leaked file descriptors
17954        if (service != null && service.hasFileDescriptors() == true) {
17955            throw new IllegalArgumentException("File descriptors passed in Intent");
17956        }
17957
17958        if (callingPackage == null) {
17959            throw new IllegalArgumentException("callingPackage cannot be null");
17960        }
17961
17962        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17963                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
17964        synchronized(this) {
17965            final int callingPid = Binder.getCallingPid();
17966            final int callingUid = Binder.getCallingUid();
17967            final long origId = Binder.clearCallingIdentity();
17968            ComponentName res;
17969            try {
17970                res = mServices.startServiceLocked(caller, service,
17971                        resolvedType, callingPid, callingUid,
17972                        requireForeground, callingPackage, userId);
17973            } finally {
17974                Binder.restoreCallingIdentity(origId);
17975            }
17976            return res;
17977        }
17978    }
17979
17980    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17981            boolean fgRequired, String callingPackage, int userId)
17982            throws TransactionTooLargeException {
17983        synchronized(this) {
17984            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17985                    "startServiceInPackage: " + service + " type=" + resolvedType);
17986            final long origId = Binder.clearCallingIdentity();
17987            ComponentName res;
17988            try {
17989                res = mServices.startServiceLocked(null, service,
17990                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
17991            } finally {
17992                Binder.restoreCallingIdentity(origId);
17993            }
17994            return res;
17995        }
17996    }
17997
17998    @Override
17999    public int stopService(IApplicationThread caller, Intent service,
18000            String resolvedType, int userId) {
18001        enforceNotIsolatedCaller("stopService");
18002        // Refuse possible leaked file descriptors
18003        if (service != null && service.hasFileDescriptors() == true) {
18004            throw new IllegalArgumentException("File descriptors passed in Intent");
18005        }
18006
18007        synchronized(this) {
18008            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18009        }
18010    }
18011
18012    @Override
18013    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18014        enforceNotIsolatedCaller("peekService");
18015        // Refuse possible leaked file descriptors
18016        if (service != null && service.hasFileDescriptors() == true) {
18017            throw new IllegalArgumentException("File descriptors passed in Intent");
18018        }
18019
18020        if (callingPackage == null) {
18021            throw new IllegalArgumentException("callingPackage cannot be null");
18022        }
18023
18024        synchronized(this) {
18025            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18026        }
18027    }
18028
18029    @Override
18030    public boolean stopServiceToken(ComponentName className, IBinder token,
18031            int startId) {
18032        synchronized(this) {
18033            return mServices.stopServiceTokenLocked(className, token, startId);
18034        }
18035    }
18036
18037    @Override
18038    public void setServiceForeground(ComponentName className, IBinder token,
18039            int id, Notification notification, int flags) {
18040        synchronized(this) {
18041            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18042        }
18043    }
18044
18045    @Override
18046    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18047            boolean requireFull, String name, String callerPackage) {
18048        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18049                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18050    }
18051
18052    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18053            String className, int flags) {
18054        boolean result = false;
18055        // For apps that don't have pre-defined UIDs, check for permission
18056        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18057            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18058                if (ActivityManager.checkUidPermission(
18059                        INTERACT_ACROSS_USERS,
18060                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18061                    ComponentName comp = new ComponentName(aInfo.packageName, className);
18062                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
18063                            + " requests FLAG_SINGLE_USER, but app does not hold "
18064                            + INTERACT_ACROSS_USERS;
18065                    Slog.w(TAG, msg);
18066                    throw new SecurityException(msg);
18067                }
18068                // Permission passed
18069                result = true;
18070            }
18071        } else if ("system".equals(componentProcessName)) {
18072            result = true;
18073        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18074            // Phone app and persistent apps are allowed to export singleuser providers.
18075            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18076                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18077        }
18078        if (DEBUG_MU) Slog.v(TAG_MU,
18079                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18080                + Integer.toHexString(flags) + ") = " + result);
18081        return result;
18082    }
18083
18084    /**
18085     * Checks to see if the caller is in the same app as the singleton
18086     * component, or the component is in a special app. It allows special apps
18087     * to export singleton components but prevents exporting singleton
18088     * components for regular apps.
18089     */
18090    boolean isValidSingletonCall(int callingUid, int componentUid) {
18091        int componentAppId = UserHandle.getAppId(componentUid);
18092        return UserHandle.isSameApp(callingUid, componentUid)
18093                || componentAppId == SYSTEM_UID
18094                || componentAppId == PHONE_UID
18095                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18096                        == PackageManager.PERMISSION_GRANTED;
18097    }
18098
18099    public int bindService(IApplicationThread caller, IBinder token, Intent service,
18100            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18101            int userId) throws TransactionTooLargeException {
18102        enforceNotIsolatedCaller("bindService");
18103
18104        // Refuse possible leaked file descriptors
18105        if (service != null && service.hasFileDescriptors() == true) {
18106            throw new IllegalArgumentException("File descriptors passed in Intent");
18107        }
18108
18109        if (callingPackage == null) {
18110            throw new IllegalArgumentException("callingPackage cannot be null");
18111        }
18112
18113        synchronized(this) {
18114            return mServices.bindServiceLocked(caller, token, service,
18115                    resolvedType, connection, flags, callingPackage, userId);
18116        }
18117    }
18118
18119    public boolean unbindService(IServiceConnection connection) {
18120        synchronized (this) {
18121            return mServices.unbindServiceLocked(connection);
18122        }
18123    }
18124
18125    public void publishService(IBinder token, Intent intent, IBinder service) {
18126        // Refuse possible leaked file descriptors
18127        if (intent != null && intent.hasFileDescriptors() == true) {
18128            throw new IllegalArgumentException("File descriptors passed in Intent");
18129        }
18130
18131        synchronized(this) {
18132            if (!(token instanceof ServiceRecord)) {
18133                throw new IllegalArgumentException("Invalid service token");
18134            }
18135            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18136        }
18137    }
18138
18139    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18140        // Refuse possible leaked file descriptors
18141        if (intent != null && intent.hasFileDescriptors() == true) {
18142            throw new IllegalArgumentException("File descriptors passed in Intent");
18143        }
18144
18145        synchronized(this) {
18146            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18147        }
18148    }
18149
18150    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18151        synchronized(this) {
18152            if (!(token instanceof ServiceRecord)) {
18153                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18154                throw new IllegalArgumentException("Invalid service token");
18155            }
18156            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18157        }
18158    }
18159
18160    // =========================================================
18161    // BACKUP AND RESTORE
18162    // =========================================================
18163
18164    // Cause the target app to be launched if necessary and its backup agent
18165    // instantiated.  The backup agent will invoke backupAgentCreated() on the
18166    // activity manager to announce its creation.
18167    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18168        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18169        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18170
18171        IPackageManager pm = AppGlobals.getPackageManager();
18172        ApplicationInfo app = null;
18173        try {
18174            app = pm.getApplicationInfo(packageName, 0, userId);
18175        } catch (RemoteException e) {
18176            // can't happen; package manager is process-local
18177        }
18178        if (app == null) {
18179            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18180            return false;
18181        }
18182
18183        int oldBackupUid;
18184        int newBackupUid;
18185
18186        synchronized(this) {
18187            // !!! TODO: currently no check here that we're already bound
18188            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18189            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18190            synchronized (stats) {
18191                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18192            }
18193
18194            // Backup agent is now in use, its package can't be stopped.
18195            try {
18196                AppGlobals.getPackageManager().setPackageStoppedState(
18197                        app.packageName, false, UserHandle.getUserId(app.uid));
18198            } catch (RemoteException e) {
18199            } catch (IllegalArgumentException e) {
18200                Slog.w(TAG, "Failed trying to unstop package "
18201                        + app.packageName + ": " + e);
18202            }
18203
18204            BackupRecord r = new BackupRecord(ss, app, backupMode);
18205            ComponentName hostingName =
18206                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18207                            ? new ComponentName(app.packageName, app.backupAgentName)
18208                            : new ComponentName("android", "FullBackupAgent");
18209            // startProcessLocked() returns existing proc's record if it's already running
18210            ProcessRecord proc = startProcessLocked(app.processName, app,
18211                    false, 0, "backup", hostingName, false, false, false);
18212            if (proc == null) {
18213                Slog.e(TAG, "Unable to start backup agent process " + r);
18214                return false;
18215            }
18216
18217            // If the app is a regular app (uid >= 10000) and not the system server or phone
18218            // process, etc, then mark it as being in full backup so that certain calls to the
18219            // process can be blocked. This is not reset to false anywhere because we kill the
18220            // process after the full backup is done and the ProcessRecord will vaporize anyway.
18221            if (UserHandle.isApp(app.uid) &&
18222                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18223                proc.inFullBackup = true;
18224            }
18225            r.app = proc;
18226            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18227            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18228            mBackupTarget = r;
18229            mBackupAppName = app.packageName;
18230
18231            // Try not to kill the process during backup
18232            updateOomAdjLocked(proc);
18233
18234            // If the process is already attached, schedule the creation of the backup agent now.
18235            // If it is not yet live, this will be done when it attaches to the framework.
18236            if (proc.thread != null) {
18237                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18238                try {
18239                    proc.thread.scheduleCreateBackupAgent(app,
18240                            compatibilityInfoForPackageLocked(app), backupMode);
18241                } catch (RemoteException e) {
18242                    // Will time out on the backup manager side
18243                }
18244            } else {
18245                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18246            }
18247            // Invariants: at this point, the target app process exists and the application
18248            // is either already running or in the process of coming up.  mBackupTarget and
18249            // mBackupAppName describe the app, so that when it binds back to the AM we
18250            // know that it's scheduled for a backup-agent operation.
18251        }
18252
18253        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18254        if (oldBackupUid != -1) {
18255            js.removeBackingUpUid(oldBackupUid);
18256        }
18257        if (newBackupUid != -1) {
18258            js.addBackingUpUid(newBackupUid);
18259        }
18260
18261        return true;
18262    }
18263
18264    @Override
18265    public void clearPendingBackup() {
18266        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18267        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18268
18269        synchronized (this) {
18270            mBackupTarget = null;
18271            mBackupAppName = null;
18272        }
18273
18274        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18275        js.clearAllBackingUpUids();
18276    }
18277
18278    // A backup agent has just come up
18279    public void backupAgentCreated(String agentPackageName, IBinder agent) {
18280        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18281                + " = " + agent);
18282
18283        synchronized(this) {
18284            if (!agentPackageName.equals(mBackupAppName)) {
18285                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18286                return;
18287            }
18288        }
18289
18290        long oldIdent = Binder.clearCallingIdentity();
18291        try {
18292            IBackupManager bm = IBackupManager.Stub.asInterface(
18293                    ServiceManager.getService(Context.BACKUP_SERVICE));
18294            bm.agentConnected(agentPackageName, agent);
18295        } catch (RemoteException e) {
18296            // can't happen; the backup manager service is local
18297        } catch (Exception e) {
18298            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18299            e.printStackTrace();
18300        } finally {
18301            Binder.restoreCallingIdentity(oldIdent);
18302        }
18303    }
18304
18305    // done with this agent
18306    public void unbindBackupAgent(ApplicationInfo appInfo) {
18307        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18308        if (appInfo == null) {
18309            Slog.w(TAG, "unbind backup agent for null app");
18310            return;
18311        }
18312
18313        int oldBackupUid;
18314
18315        synchronized(this) {
18316            try {
18317                if (mBackupAppName == null) {
18318                    Slog.w(TAG, "Unbinding backup agent with no active backup");
18319                    return;
18320                }
18321
18322                if (!mBackupAppName.equals(appInfo.packageName)) {
18323                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18324                    return;
18325                }
18326
18327                // Not backing this app up any more; reset its OOM adjustment
18328                final ProcessRecord proc = mBackupTarget.app;
18329                updateOomAdjLocked(proc);
18330                proc.inFullBackup = false;
18331
18332                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18333
18334                // If the app crashed during backup, 'thread' will be null here
18335                if (proc.thread != null) {
18336                    try {
18337                        proc.thread.scheduleDestroyBackupAgent(appInfo,
18338                                compatibilityInfoForPackageLocked(appInfo));
18339                    } catch (Exception e) {
18340                        Slog.e(TAG, "Exception when unbinding backup agent:");
18341                        e.printStackTrace();
18342                    }
18343                }
18344            } finally {
18345                mBackupTarget = null;
18346                mBackupAppName = null;
18347            }
18348        }
18349
18350        if (oldBackupUid != -1) {
18351            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18352            js.removeBackingUpUid(oldBackupUid);
18353        }
18354    }
18355
18356    // =========================================================
18357    // BROADCASTS
18358    // =========================================================
18359
18360    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18361        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18362            return false;
18363        }
18364        // Easy case -- we have the app's ProcessRecord.
18365        if (record != null) {
18366            return record.info.isInstantApp();
18367        }
18368        // Otherwise check with PackageManager.
18369        if (callerPackage == null) {
18370            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18371            throw new IllegalArgumentException("Calling application did not provide package name");
18372        }
18373        mAppOpsService.checkPackage(uid, callerPackage);
18374        try {
18375            IPackageManager pm = AppGlobals.getPackageManager();
18376            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18377        } catch (RemoteException e) {
18378            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18379            return true;
18380        }
18381    }
18382
18383    boolean isPendingBroadcastProcessLocked(int pid) {
18384        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18385                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18386    }
18387
18388    void skipPendingBroadcastLocked(int pid) {
18389            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18390            for (BroadcastQueue queue : mBroadcastQueues) {
18391                queue.skipPendingBroadcastLocked(pid);
18392            }
18393    }
18394
18395    // The app just attached; send any pending broadcasts that it should receive
18396    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18397        boolean didSomething = false;
18398        for (BroadcastQueue queue : mBroadcastQueues) {
18399            didSomething |= queue.sendPendingBroadcastsLocked(app);
18400        }
18401        return didSomething;
18402    }
18403
18404    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18405            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18406            int flags) {
18407        enforceNotIsolatedCaller("registerReceiver");
18408        ArrayList<Intent> stickyIntents = null;
18409        ProcessRecord callerApp = null;
18410        final boolean visibleToInstantApps
18411                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18412        int callingUid;
18413        int callingPid;
18414        boolean instantApp;
18415        synchronized(this) {
18416            if (caller != null) {
18417                callerApp = getRecordForAppLocked(caller);
18418                if (callerApp == null) {
18419                    throw new SecurityException(
18420                            "Unable to find app for caller " + caller
18421                            + " (pid=" + Binder.getCallingPid()
18422                            + ") when registering receiver " + receiver);
18423                }
18424                if (callerApp.info.uid != SYSTEM_UID &&
18425                        !callerApp.pkgList.containsKey(callerPackage) &&
18426                        !"android".equals(callerPackage)) {
18427                    throw new SecurityException("Given caller package " + callerPackage
18428                            + " is not running in process " + callerApp);
18429                }
18430                callingUid = callerApp.info.uid;
18431                callingPid = callerApp.pid;
18432            } else {
18433                callerPackage = null;
18434                callingUid = Binder.getCallingUid();
18435                callingPid = Binder.getCallingPid();
18436            }
18437
18438            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18439            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18440                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18441
18442            Iterator<String> actions = filter.actionsIterator();
18443            if (actions == null) {
18444                ArrayList<String> noAction = new ArrayList<String>(1);
18445                noAction.add(null);
18446                actions = noAction.iterator();
18447            }
18448
18449            // Collect stickies of users
18450            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18451            while (actions.hasNext()) {
18452                String action = actions.next();
18453                for (int id : userIds) {
18454                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18455                    if (stickies != null) {
18456                        ArrayList<Intent> intents = stickies.get(action);
18457                        if (intents != null) {
18458                            if (stickyIntents == null) {
18459                                stickyIntents = new ArrayList<Intent>();
18460                            }
18461                            stickyIntents.addAll(intents);
18462                        }
18463                    }
18464                }
18465            }
18466        }
18467
18468        ArrayList<Intent> allSticky = null;
18469        if (stickyIntents != null) {
18470            final ContentResolver resolver = mContext.getContentResolver();
18471            // Look for any matching sticky broadcasts...
18472            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18473                Intent intent = stickyIntents.get(i);
18474                // Don't provided intents that aren't available to instant apps.
18475                if (instantApp &&
18476                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18477                    continue;
18478                }
18479                // If intent has scheme "content", it will need to acccess
18480                // provider that needs to lock mProviderMap in ActivityThread
18481                // and also it may need to wait application response, so we
18482                // cannot lock ActivityManagerService here.
18483                if (filter.match(resolver, intent, true, TAG) >= 0) {
18484                    if (allSticky == null) {
18485                        allSticky = new ArrayList<Intent>();
18486                    }
18487                    allSticky.add(intent);
18488                }
18489            }
18490        }
18491
18492        // The first sticky in the list is returned directly back to the client.
18493        Intent sticky = allSticky != null ? allSticky.get(0) : null;
18494        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18495        if (receiver == null) {
18496            return sticky;
18497        }
18498
18499        synchronized (this) {
18500            if (callerApp != null && (callerApp.thread == null
18501                    || callerApp.thread.asBinder() != caller.asBinder())) {
18502                // Original caller already died
18503                return null;
18504            }
18505            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18506            if (rl == null) {
18507                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18508                        userId, receiver);
18509                if (rl.app != null) {
18510                    rl.app.receivers.add(rl);
18511                } else {
18512                    try {
18513                        receiver.asBinder().linkToDeath(rl, 0);
18514                    } catch (RemoteException e) {
18515                        return sticky;
18516                    }
18517                    rl.linkedToDeath = true;
18518                }
18519                mRegisteredReceivers.put(receiver.asBinder(), rl);
18520            } else if (rl.uid != callingUid) {
18521                throw new IllegalArgumentException(
18522                        "Receiver requested to register for uid " + callingUid
18523                        + " was previously registered for uid " + rl.uid
18524                        + " callerPackage is " + callerPackage);
18525            } else if (rl.pid != callingPid) {
18526                throw new IllegalArgumentException(
18527                        "Receiver requested to register for pid " + callingPid
18528                        + " was previously registered for pid " + rl.pid
18529                        + " callerPackage is " + callerPackage);
18530            } else if (rl.userId != userId) {
18531                throw new IllegalArgumentException(
18532                        "Receiver requested to register for user " + userId
18533                        + " was previously registered for user " + rl.userId
18534                        + " callerPackage is " + callerPackage);
18535            }
18536            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18537                    permission, callingUid, userId, instantApp, visibleToInstantApps);
18538            rl.add(bf);
18539            if (!bf.debugCheck()) {
18540                Slog.w(TAG, "==> For Dynamic broadcast");
18541            }
18542            mReceiverResolver.addFilter(bf);
18543
18544            // Enqueue broadcasts for all existing stickies that match
18545            // this filter.
18546            if (allSticky != null) {
18547                ArrayList receivers = new ArrayList();
18548                receivers.add(bf);
18549
18550                final int stickyCount = allSticky.size();
18551                for (int i = 0; i < stickyCount; i++) {
18552                    Intent intent = allSticky.get(i);
18553                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18554                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18555                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18556                            null, 0, null, null, false, true, true, -1);
18557                    queue.enqueueParallelBroadcastLocked(r);
18558                    queue.scheduleBroadcastsLocked();
18559                }
18560            }
18561
18562            return sticky;
18563        }
18564    }
18565
18566    public void unregisterReceiver(IIntentReceiver receiver) {
18567        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18568
18569        final long origId = Binder.clearCallingIdentity();
18570        try {
18571            boolean doTrim = false;
18572
18573            synchronized(this) {
18574                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18575                if (rl != null) {
18576                    final BroadcastRecord r = rl.curBroadcast;
18577                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18578                        final boolean doNext = r.queue.finishReceiverLocked(
18579                                r, r.resultCode, r.resultData, r.resultExtras,
18580                                r.resultAbort, false);
18581                        if (doNext) {
18582                            doTrim = true;
18583                            r.queue.processNextBroadcast(false);
18584                        }
18585                    }
18586
18587                    if (rl.app != null) {
18588                        rl.app.receivers.remove(rl);
18589                    }
18590                    removeReceiverLocked(rl);
18591                    if (rl.linkedToDeath) {
18592                        rl.linkedToDeath = false;
18593                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18594                    }
18595                }
18596            }
18597
18598            // If we actually concluded any broadcasts, we might now be able
18599            // to trim the recipients' apps from our working set
18600            if (doTrim) {
18601                trimApplications();
18602                return;
18603            }
18604
18605        } finally {
18606            Binder.restoreCallingIdentity(origId);
18607        }
18608    }
18609
18610    void removeReceiverLocked(ReceiverList rl) {
18611        mRegisteredReceivers.remove(rl.receiver.asBinder());
18612        for (int i = rl.size() - 1; i >= 0; i--) {
18613            mReceiverResolver.removeFilter(rl.get(i));
18614        }
18615    }
18616
18617    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18618        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18619            ProcessRecord r = mLruProcesses.get(i);
18620            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18621                try {
18622                    r.thread.dispatchPackageBroadcast(cmd, packages);
18623                } catch (RemoteException ex) {
18624                }
18625            }
18626        }
18627    }
18628
18629    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18630            int callingUid, int[] users) {
18631        // TODO: come back and remove this assumption to triage all broadcasts
18632        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18633
18634        List<ResolveInfo> receivers = null;
18635        try {
18636            HashSet<ComponentName> singleUserReceivers = null;
18637            boolean scannedFirstReceivers = false;
18638            for (int user : users) {
18639                // Skip users that have Shell restrictions, with exception of always permitted
18640                // Shell broadcasts
18641                if (callingUid == SHELL_UID
18642                        && mUserController.hasUserRestriction(
18643                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18644                        && !isPermittedShellBroadcast(intent)) {
18645                    continue;
18646                }
18647                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18648                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18649                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18650                    // If this is not the system user, we need to check for
18651                    // any receivers that should be filtered out.
18652                    for (int i=0; i<newReceivers.size(); i++) {
18653                        ResolveInfo ri = newReceivers.get(i);
18654                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18655                            newReceivers.remove(i);
18656                            i--;
18657                        }
18658                    }
18659                }
18660                if (newReceivers != null && newReceivers.size() == 0) {
18661                    newReceivers = null;
18662                }
18663                if (receivers == null) {
18664                    receivers = newReceivers;
18665                } else if (newReceivers != null) {
18666                    // We need to concatenate the additional receivers
18667                    // found with what we have do far.  This would be easy,
18668                    // but we also need to de-dup any receivers that are
18669                    // singleUser.
18670                    if (!scannedFirstReceivers) {
18671                        // Collect any single user receivers we had already retrieved.
18672                        scannedFirstReceivers = true;
18673                        for (int i=0; i<receivers.size(); i++) {
18674                            ResolveInfo ri = receivers.get(i);
18675                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18676                                ComponentName cn = new ComponentName(
18677                                        ri.activityInfo.packageName, ri.activityInfo.name);
18678                                if (singleUserReceivers == null) {
18679                                    singleUserReceivers = new HashSet<ComponentName>();
18680                                }
18681                                singleUserReceivers.add(cn);
18682                            }
18683                        }
18684                    }
18685                    // Add the new results to the existing results, tracking
18686                    // and de-dupping single user receivers.
18687                    for (int i=0; i<newReceivers.size(); i++) {
18688                        ResolveInfo ri = newReceivers.get(i);
18689                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18690                            ComponentName cn = new ComponentName(
18691                                    ri.activityInfo.packageName, ri.activityInfo.name);
18692                            if (singleUserReceivers == null) {
18693                                singleUserReceivers = new HashSet<ComponentName>();
18694                            }
18695                            if (!singleUserReceivers.contains(cn)) {
18696                                singleUserReceivers.add(cn);
18697                                receivers.add(ri);
18698                            }
18699                        } else {
18700                            receivers.add(ri);
18701                        }
18702                    }
18703                }
18704            }
18705        } catch (RemoteException ex) {
18706            // pm is in same process, this will never happen.
18707        }
18708        return receivers;
18709    }
18710
18711    private boolean isPermittedShellBroadcast(Intent intent) {
18712        // remote bugreport should always be allowed to be taken
18713        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18714    }
18715
18716    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18717            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18718        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18719            // Don't yell about broadcasts sent via shell
18720            return;
18721        }
18722
18723        final String action = intent.getAction();
18724        if (isProtectedBroadcast
18725                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18726                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18727                || Intent.ACTION_MEDIA_BUTTON.equals(action)
18728                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18729                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18730                || Intent.ACTION_MASTER_CLEAR.equals(action)
18731                || Intent.ACTION_FACTORY_RESET.equals(action)
18732                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18733                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18734                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18735                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18736                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18737                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18738                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18739            // Broadcast is either protected, or it's a public action that
18740            // we've relaxed, so it's fine for system internals to send.
18741            return;
18742        }
18743
18744        // This broadcast may be a problem...  but there are often system components that
18745        // want to send an internal broadcast to themselves, which is annoying to have to
18746        // explicitly list each action as a protected broadcast, so we will check for that
18747        // one safe case and allow it: an explicit broadcast, only being received by something
18748        // that has protected itself.
18749        if (receivers != null && receivers.size() > 0
18750                && (intent.getPackage() != null || intent.getComponent() != null)) {
18751            boolean allProtected = true;
18752            for (int i = receivers.size()-1; i >= 0; i--) {
18753                Object target = receivers.get(i);
18754                if (target instanceof ResolveInfo) {
18755                    ResolveInfo ri = (ResolveInfo)target;
18756                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18757                        allProtected = false;
18758                        break;
18759                    }
18760                } else {
18761                    BroadcastFilter bf = (BroadcastFilter)target;
18762                    if (bf.requiredPermission == null) {
18763                        allProtected = false;
18764                        break;
18765                    }
18766                }
18767            }
18768            if (allProtected) {
18769                // All safe!
18770                return;
18771            }
18772        }
18773
18774        // The vast majority of broadcasts sent from system internals
18775        // should be protected to avoid security holes, so yell loudly
18776        // to ensure we examine these cases.
18777        if (callerApp != null) {
18778            Log.wtf(TAG, "Sending non-protected broadcast " + action
18779                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
18780                    new Throwable());
18781        } else {
18782            Log.wtf(TAG, "Sending non-protected broadcast " + action
18783                            + " from system uid " + UserHandle.formatUid(callingUid)
18784                            + " pkg " + callerPackage,
18785                    new Throwable());
18786        }
18787    }
18788
18789    final int broadcastIntentLocked(ProcessRecord callerApp,
18790            String callerPackage, Intent intent, String resolvedType,
18791            IIntentReceiver resultTo, int resultCode, String resultData,
18792            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
18793            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
18794        intent = new Intent(intent);
18795
18796        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
18797        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
18798        if (callerInstantApp) {
18799            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
18800        }
18801
18802        // By default broadcasts do not go to stopped apps.
18803        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
18804
18805        // If we have not finished booting, don't allow this to launch new processes.
18806        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
18807            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18808        }
18809
18810        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
18811                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
18812                + " ordered=" + ordered + " userid=" + userId);
18813        if ((resultTo != null) && !ordered) {
18814            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
18815        }
18816
18817        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18818                ALLOW_NON_FULL, "broadcast", callerPackage);
18819
18820        // Make sure that the user who is receiving this broadcast is running.
18821        // If not, we will just skip it. Make an exception for shutdown broadcasts
18822        // and upgrade steps.
18823
18824        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
18825            if ((callingUid != SYSTEM_UID
18826                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
18827                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
18828                Slog.w(TAG, "Skipping broadcast of " + intent
18829                        + ": user " + userId + " is stopped");
18830                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
18831            }
18832        }
18833
18834        BroadcastOptions brOptions = null;
18835        if (bOptions != null) {
18836            brOptions = new BroadcastOptions(bOptions);
18837            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
18838                // See if the caller is allowed to do this.  Note we are checking against
18839                // the actual real caller (not whoever provided the operation as say a
18840                // PendingIntent), because that who is actually supplied the arguments.
18841                if (checkComponentPermission(
18842                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
18843                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
18844                        != PackageManager.PERMISSION_GRANTED) {
18845                    String msg = "Permission Denial: " + intent.getAction()
18846                            + " broadcast from " + callerPackage + " (pid=" + callingPid
18847                            + ", uid=" + callingUid + ")"
18848                            + " requires "
18849                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
18850                    Slog.w(TAG, msg);
18851                    throw new SecurityException(msg);
18852                }
18853            }
18854        }
18855
18856        // Verify that protected broadcasts are only being sent by system code,
18857        // and that system code is only sending protected broadcasts.
18858        final String action = intent.getAction();
18859        final boolean isProtectedBroadcast;
18860        try {
18861            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18862        } catch (RemoteException e) {
18863            Slog.w(TAG, "Remote exception", e);
18864            return ActivityManager.BROADCAST_SUCCESS;
18865        }
18866
18867        final boolean isCallerSystem;
18868        switch (UserHandle.getAppId(callingUid)) {
18869            case ROOT_UID:
18870            case SYSTEM_UID:
18871            case PHONE_UID:
18872            case BLUETOOTH_UID:
18873            case NFC_UID:
18874                isCallerSystem = true;
18875                break;
18876            default:
18877                isCallerSystem = (callerApp != null) && callerApp.persistent;
18878                break;
18879        }
18880
18881        // First line security check before anything else: stop non-system apps from
18882        // sending protected broadcasts.
18883        if (!isCallerSystem) {
18884            if (isProtectedBroadcast) {
18885                String msg = "Permission Denial: not allowed to send broadcast "
18886                        + action + " from pid="
18887                        + callingPid + ", uid=" + callingUid;
18888                Slog.w(TAG, msg);
18889                throw new SecurityException(msg);
18890
18891            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18892                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18893                // Special case for compatibility: we don't want apps to send this,
18894                // but historically it has not been protected and apps may be using it
18895                // to poke their own app widget.  So, instead of making it protected,
18896                // just limit it to the caller.
18897                if (callerPackage == null) {
18898                    String msg = "Permission Denial: not allowed to send broadcast "
18899                            + action + " from unknown caller.";
18900                    Slog.w(TAG, msg);
18901                    throw new SecurityException(msg);
18902                } else if (intent.getComponent() != null) {
18903                    // They are good enough to send to an explicit component...  verify
18904                    // it is being sent to the calling app.
18905                    if (!intent.getComponent().getPackageName().equals(
18906                            callerPackage)) {
18907                        String msg = "Permission Denial: not allowed to send broadcast "
18908                                + action + " to "
18909                                + intent.getComponent().getPackageName() + " from "
18910                                + callerPackage;
18911                        Slog.w(TAG, msg);
18912                        throw new SecurityException(msg);
18913                    }
18914                } else {
18915                    // Limit broadcast to their own package.
18916                    intent.setPackage(callerPackage);
18917                }
18918            }
18919        }
18920
18921        if (action != null) {
18922            if (getBackgroundLaunchBroadcasts().contains(action)) {
18923                if (DEBUG_BACKGROUND_CHECK) {
18924                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
18925                }
18926                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
18927            }
18928
18929            switch (action) {
18930                case Intent.ACTION_UID_REMOVED:
18931                case Intent.ACTION_PACKAGE_REMOVED:
18932                case Intent.ACTION_PACKAGE_CHANGED:
18933                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18934                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18935                case Intent.ACTION_PACKAGES_SUSPENDED:
18936                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18937                    // Handle special intents: if this broadcast is from the package
18938                    // manager about a package being removed, we need to remove all of
18939                    // its activities from the history stack.
18940                    if (checkComponentPermission(
18941                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18942                            callingPid, callingUid, -1, true)
18943                            != PackageManager.PERMISSION_GRANTED) {
18944                        String msg = "Permission Denial: " + intent.getAction()
18945                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18946                                + ", uid=" + callingUid + ")"
18947                                + " requires "
18948                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18949                        Slog.w(TAG, msg);
18950                        throw new SecurityException(msg);
18951                    }
18952                    switch (action) {
18953                        case Intent.ACTION_UID_REMOVED:
18954                            final int uid = getUidFromIntent(intent);
18955                            if (uid >= 0) {
18956                                mBatteryStatsService.removeUid(uid);
18957                                mAppOpsService.uidRemoved(uid);
18958                            }
18959                            break;
18960                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18961                            // If resources are unavailable just force stop all those packages
18962                            // and flush the attribute cache as well.
18963                            String list[] =
18964                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18965                            if (list != null && list.length > 0) {
18966                                for (int i = 0; i < list.length; i++) {
18967                                    forceStopPackageLocked(list[i], -1, false, true, true,
18968                                            false, false, userId, "storage unmount");
18969                                }
18970                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18971                                sendPackageBroadcastLocked(
18972                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
18973                                        list, userId);
18974                            }
18975                            break;
18976                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18977                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18978                            break;
18979                        case Intent.ACTION_PACKAGE_REMOVED:
18980                        case Intent.ACTION_PACKAGE_CHANGED:
18981                            Uri data = intent.getData();
18982                            String ssp;
18983                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18984                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18985                                final boolean replacing =
18986                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18987                                final boolean killProcess =
18988                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18989                                final boolean fullUninstall = removed && !replacing;
18990                                if (removed) {
18991                                    if (killProcess) {
18992                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18993                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18994                                                false, true, true, false, fullUninstall, userId,
18995                                                removed ? "pkg removed" : "pkg changed");
18996                                    }
18997                                    final int cmd = killProcess
18998                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18999                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19000                                    sendPackageBroadcastLocked(cmd,
19001                                            new String[] {ssp}, userId);
19002                                    if (fullUninstall) {
19003                                        mAppOpsService.packageRemoved(
19004                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19005
19006                                        // Remove all permissions granted from/to this package
19007                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
19008
19009                                        removeTasksByPackageNameLocked(ssp, userId);
19010
19011                                        mServices.removeUninstalledPackageLocked(ssp, userId);
19012
19013                                        // Hide the "unsupported display" dialog if necessary.
19014                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19015                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19016                                            mUnsupportedDisplaySizeDialog.dismiss();
19017                                            mUnsupportedDisplaySizeDialog = null;
19018                                        }
19019                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
19020                                        mBatteryStatsService.notePackageUninstalled(ssp);
19021                                    }
19022                                } else {
19023                                    if (killProcess) {
19024                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
19025                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19026                                                userId, ProcessList.INVALID_ADJ,
19027                                                false, true, true, false, "change " + ssp);
19028                                    }
19029                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19030                                            intent.getStringArrayExtra(
19031                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19032                                }
19033                            }
19034                            break;
19035                        case Intent.ACTION_PACKAGES_SUSPENDED:
19036                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
19037                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19038                                    intent.getAction());
19039                            final String[] packageNames = intent.getStringArrayExtra(
19040                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
19041                            final int userHandle = intent.getIntExtra(
19042                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19043
19044                            synchronized(ActivityManagerService.this) {
19045                                mRecentTasks.onPackagesSuspendedChanged(
19046                                        packageNames, suspended, userHandle);
19047                            }
19048                            break;
19049                    }
19050                    break;
19051                case Intent.ACTION_PACKAGE_REPLACED:
19052                {
19053                    final Uri data = intent.getData();
19054                    final String ssp;
19055                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19056                        final ApplicationInfo aInfo =
19057                                getPackageManagerInternalLocked().getApplicationInfo(
19058                                        ssp,
19059                                        userId);
19060                        if (aInfo == null) {
19061                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19062                                    + " ssp=" + ssp + " data=" + data);
19063                            return ActivityManager.BROADCAST_SUCCESS;
19064                        }
19065                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19066                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19067                                new String[] {ssp}, userId);
19068                    }
19069                    break;
19070                }
19071                case Intent.ACTION_PACKAGE_ADDED:
19072                {
19073                    // Special case for adding a package: by default turn on compatibility mode.
19074                    Uri data = intent.getData();
19075                    String ssp;
19076                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19077                        final boolean replacing =
19078                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19079                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19080
19081                        try {
19082                            ApplicationInfo ai = AppGlobals.getPackageManager().
19083                                    getApplicationInfo(ssp, 0, 0);
19084                            mBatteryStatsService.notePackageInstalled(ssp,
19085                                    ai != null ? ai.versionCode : 0);
19086                        } catch (RemoteException e) {
19087                        }
19088                    }
19089                    break;
19090                }
19091                case Intent.ACTION_PACKAGE_DATA_CLEARED:
19092                {
19093                    Uri data = intent.getData();
19094                    String ssp;
19095                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19096                        // Hide the "unsupported display" dialog if necessary.
19097                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19098                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19099                            mUnsupportedDisplaySizeDialog.dismiss();
19100                            mUnsupportedDisplaySizeDialog = null;
19101                        }
19102                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
19103                    }
19104                    break;
19105                }
19106                case Intent.ACTION_TIMEZONE_CHANGED:
19107                    // If this is the time zone changed action, queue up a message that will reset
19108                    // the timezone of all currently running processes. This message will get
19109                    // queued up before the broadcast happens.
19110                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19111                    break;
19112                case Intent.ACTION_TIME_CHANGED:
19113                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19114                    // the tri-state value it may contain and "unknown".
19115                    // For convenience we re-use the Intent extra values.
19116                    final int NO_EXTRA_VALUE_FOUND = -1;
19117                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19118                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19119                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
19120                    // Only send a message if the time preference is available.
19121                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19122                        Message updateTimePreferenceMsg =
19123                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19124                                        timeFormatPreferenceMsgValue, 0);
19125                        mHandler.sendMessage(updateTimePreferenceMsg);
19126                    }
19127                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19128                    synchronized (stats) {
19129                        stats.noteCurrentTimeChangedLocked();
19130                    }
19131                    break;
19132                case Intent.ACTION_CLEAR_DNS_CACHE:
19133                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19134                    break;
19135                case Proxy.PROXY_CHANGE_ACTION:
19136                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19137                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19138                    break;
19139                case android.hardware.Camera.ACTION_NEW_PICTURE:
19140                case android.hardware.Camera.ACTION_NEW_VIDEO:
19141                    // In N we just turned these off; in O we are turing them back on partly,
19142                    // only for registered receivers.  This will still address the main problem
19143                    // (a spam of apps waking up when a picture is taken putting significant
19144                    // memory pressure on the system at a bad point), while still allowing apps
19145                    // that are already actively running to know about this happening.
19146                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19147                    break;
19148                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19149                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19150                    break;
19151                case "com.android.launcher.action.INSTALL_SHORTCUT":
19152                    // As of O, we no longer support this broadcasts, even for pre-O apps.
19153                    // Apps should now be using ShortcutManager.pinRequestShortcut().
19154                    Log.w(TAG, "Broadcast " + action
19155                            + " no longer supported. It will not be delivered.");
19156                    return ActivityManager.BROADCAST_SUCCESS;
19157            }
19158
19159            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19160                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19161                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19162                final int uid = getUidFromIntent(intent);
19163                if (uid != -1) {
19164                    final UidRecord uidRec = mActiveUids.get(uid);
19165                    if (uidRec != null) {
19166                        uidRec.updateHasInternetPermission();
19167                    }
19168                }
19169            }
19170        }
19171
19172        // Add to the sticky list if requested.
19173        if (sticky) {
19174            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19175                    callingPid, callingUid)
19176                    != PackageManager.PERMISSION_GRANTED) {
19177                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19178                        + callingPid + ", uid=" + callingUid
19179                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19180                Slog.w(TAG, msg);
19181                throw new SecurityException(msg);
19182            }
19183            if (requiredPermissions != null && requiredPermissions.length > 0) {
19184                Slog.w(TAG, "Can't broadcast sticky intent " + intent
19185                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
19186                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19187            }
19188            if (intent.getComponent() != null) {
19189                throw new SecurityException(
19190                        "Sticky broadcasts can't target a specific component");
19191            }
19192            // We use userId directly here, since the "all" target is maintained
19193            // as a separate set of sticky broadcasts.
19194            if (userId != UserHandle.USER_ALL) {
19195                // But first, if this is not a broadcast to all users, then
19196                // make sure it doesn't conflict with an existing broadcast to
19197                // all users.
19198                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19199                        UserHandle.USER_ALL);
19200                if (stickies != null) {
19201                    ArrayList<Intent> list = stickies.get(intent.getAction());
19202                    if (list != null) {
19203                        int N = list.size();
19204                        int i;
19205                        for (i=0; i<N; i++) {
19206                            if (intent.filterEquals(list.get(i))) {
19207                                throw new IllegalArgumentException(
19208                                        "Sticky broadcast " + intent + " for user "
19209                                        + userId + " conflicts with existing global broadcast");
19210                            }
19211                        }
19212                    }
19213                }
19214            }
19215            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19216            if (stickies == null) {
19217                stickies = new ArrayMap<>();
19218                mStickyBroadcasts.put(userId, stickies);
19219            }
19220            ArrayList<Intent> list = stickies.get(intent.getAction());
19221            if (list == null) {
19222                list = new ArrayList<>();
19223                stickies.put(intent.getAction(), list);
19224            }
19225            final int stickiesCount = list.size();
19226            int i;
19227            for (i = 0; i < stickiesCount; i++) {
19228                if (intent.filterEquals(list.get(i))) {
19229                    // This sticky already exists, replace it.
19230                    list.set(i, new Intent(intent));
19231                    break;
19232                }
19233            }
19234            if (i >= stickiesCount) {
19235                list.add(new Intent(intent));
19236            }
19237        }
19238
19239        int[] users;
19240        if (userId == UserHandle.USER_ALL) {
19241            // Caller wants broadcast to go to all started users.
19242            users = mUserController.getStartedUserArrayLocked();
19243        } else {
19244            // Caller wants broadcast to go to one specific user.
19245            users = new int[] {userId};
19246        }
19247
19248        // Figure out who all will receive this broadcast.
19249        List receivers = null;
19250        List<BroadcastFilter> registeredReceivers = null;
19251        // Need to resolve the intent to interested receivers...
19252        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19253                 == 0) {
19254            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19255        }
19256        if (intent.getComponent() == null) {
19257            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19258                // Query one target user at a time, excluding shell-restricted users
19259                for (int i = 0; i < users.length; i++) {
19260                    if (mUserController.hasUserRestriction(
19261                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19262                        continue;
19263                    }
19264                    List<BroadcastFilter> registeredReceiversForUser =
19265                            mReceiverResolver.queryIntent(intent,
19266                                    resolvedType, false /*defaultOnly*/, users[i]);
19267                    if (registeredReceivers == null) {
19268                        registeredReceivers = registeredReceiversForUser;
19269                    } else if (registeredReceiversForUser != null) {
19270                        registeredReceivers.addAll(registeredReceiversForUser);
19271                    }
19272                }
19273            } else {
19274                registeredReceivers = mReceiverResolver.queryIntent(intent,
19275                        resolvedType, false /*defaultOnly*/, userId);
19276            }
19277        }
19278
19279        final boolean replacePending =
19280                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19281
19282        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19283                + " replacePending=" + replacePending);
19284
19285        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19286        if (!ordered && NR > 0) {
19287            // If we are not serializing this broadcast, then send the
19288            // registered receivers separately so they don't wait for the
19289            // components to be launched.
19290            if (isCallerSystem) {
19291                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19292                        isProtectedBroadcast, registeredReceivers);
19293            }
19294            final BroadcastQueue queue = broadcastQueueForIntent(intent);
19295            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19296                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19297                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19298                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19299            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19300            final boolean replaced = replacePending
19301                    && (queue.replaceParallelBroadcastLocked(r) != null);
19302            // Note: We assume resultTo is null for non-ordered broadcasts.
19303            if (!replaced) {
19304                queue.enqueueParallelBroadcastLocked(r);
19305                queue.scheduleBroadcastsLocked();
19306            }
19307            registeredReceivers = null;
19308            NR = 0;
19309        }
19310
19311        // Merge into one list.
19312        int ir = 0;
19313        if (receivers != null) {
19314            // A special case for PACKAGE_ADDED: do not allow the package
19315            // being added to see this broadcast.  This prevents them from
19316            // using this as a back door to get run as soon as they are
19317            // installed.  Maybe in the future we want to have a special install
19318            // broadcast or such for apps, but we'd like to deliberately make
19319            // this decision.
19320            String skipPackages[] = null;
19321            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19322                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19323                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19324                Uri data = intent.getData();
19325                if (data != null) {
19326                    String pkgName = data.getSchemeSpecificPart();
19327                    if (pkgName != null) {
19328                        skipPackages = new String[] { pkgName };
19329                    }
19330                }
19331            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19332                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19333            }
19334            if (skipPackages != null && (skipPackages.length > 0)) {
19335                for (String skipPackage : skipPackages) {
19336                    if (skipPackage != null) {
19337                        int NT = receivers.size();
19338                        for (int it=0; it<NT; it++) {
19339                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
19340                            if (curt.activityInfo.packageName.equals(skipPackage)) {
19341                                receivers.remove(it);
19342                                it--;
19343                                NT--;
19344                            }
19345                        }
19346                    }
19347                }
19348            }
19349
19350            int NT = receivers != null ? receivers.size() : 0;
19351            int it = 0;
19352            ResolveInfo curt = null;
19353            BroadcastFilter curr = null;
19354            while (it < NT && ir < NR) {
19355                if (curt == null) {
19356                    curt = (ResolveInfo)receivers.get(it);
19357                }
19358                if (curr == null) {
19359                    curr = registeredReceivers.get(ir);
19360                }
19361                if (curr.getPriority() >= curt.priority) {
19362                    // Insert this broadcast record into the final list.
19363                    receivers.add(it, curr);
19364                    ir++;
19365                    curr = null;
19366                    it++;
19367                    NT++;
19368                } else {
19369                    // Skip to the next ResolveInfo in the final list.
19370                    it++;
19371                    curt = null;
19372                }
19373            }
19374        }
19375        while (ir < NR) {
19376            if (receivers == null) {
19377                receivers = new ArrayList();
19378            }
19379            receivers.add(registeredReceivers.get(ir));
19380            ir++;
19381        }
19382
19383        if (isCallerSystem) {
19384            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19385                    isProtectedBroadcast, receivers);
19386        }
19387
19388        if ((receivers != null && receivers.size() > 0)
19389                || resultTo != null) {
19390            BroadcastQueue queue = broadcastQueueForIntent(intent);
19391            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19392                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19393                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19394                    resultData, resultExtras, ordered, sticky, false, userId);
19395
19396            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19397                    + ": prev had " + queue.mOrderedBroadcasts.size());
19398            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19399                    "Enqueueing broadcast " + r.intent.getAction());
19400
19401            final BroadcastRecord oldRecord =
19402                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19403            if (oldRecord != null) {
19404                // Replaced, fire the result-to receiver.
19405                if (oldRecord.resultTo != null) {
19406                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19407                    try {
19408                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19409                                oldRecord.intent,
19410                                Activity.RESULT_CANCELED, null, null,
19411                                false, false, oldRecord.userId);
19412                    } catch (RemoteException e) {
19413                        Slog.w(TAG, "Failure ["
19414                                + queue.mQueueName + "] sending broadcast result of "
19415                                + intent, e);
19416
19417                    }
19418                }
19419            } else {
19420                queue.enqueueOrderedBroadcastLocked(r);
19421                queue.scheduleBroadcastsLocked();
19422            }
19423        } else {
19424            // There was nobody interested in the broadcast, but we still want to record
19425            // that it happened.
19426            if (intent.getComponent() == null && intent.getPackage() == null
19427                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19428                // This was an implicit broadcast... let's record it for posterity.
19429                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19430            }
19431        }
19432
19433        return ActivityManager.BROADCAST_SUCCESS;
19434    }
19435
19436    /**
19437     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19438     */
19439    private int getUidFromIntent(Intent intent) {
19440        if (intent == null) {
19441            return -1;
19442        }
19443        final Bundle intentExtras = intent.getExtras();
19444        return intent.hasExtra(Intent.EXTRA_UID)
19445                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19446    }
19447
19448    final void rotateBroadcastStatsIfNeededLocked() {
19449        final long now = SystemClock.elapsedRealtime();
19450        if (mCurBroadcastStats == null ||
19451                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19452            mLastBroadcastStats = mCurBroadcastStats;
19453            if (mLastBroadcastStats != null) {
19454                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19455                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19456            }
19457            mCurBroadcastStats = new BroadcastStats();
19458        }
19459    }
19460
19461    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19462            int skipCount, long dispatchTime) {
19463        rotateBroadcastStatsIfNeededLocked();
19464        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19465    }
19466
19467    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19468        rotateBroadcastStatsIfNeededLocked();
19469        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19470    }
19471
19472    final Intent verifyBroadcastLocked(Intent intent) {
19473        // Refuse possible leaked file descriptors
19474        if (intent != null && intent.hasFileDescriptors() == true) {
19475            throw new IllegalArgumentException("File descriptors passed in Intent");
19476        }
19477
19478        int flags = intent.getFlags();
19479
19480        if (!mProcessesReady) {
19481            // if the caller really truly claims to know what they're doing, go
19482            // ahead and allow the broadcast without launching any receivers
19483            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19484                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19485            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19486                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19487                        + " before boot completion");
19488                throw new IllegalStateException("Cannot broadcast before boot completed");
19489            }
19490        }
19491
19492        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19493            throw new IllegalArgumentException(
19494                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19495        }
19496
19497        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19498            switch (Binder.getCallingUid()) {
19499                case ROOT_UID:
19500                case SHELL_UID:
19501                    break;
19502                default:
19503                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19504                            + Binder.getCallingUid());
19505                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19506                    break;
19507            }
19508        }
19509
19510        return intent;
19511    }
19512
19513    public final int broadcastIntent(IApplicationThread caller,
19514            Intent intent, String resolvedType, IIntentReceiver resultTo,
19515            int resultCode, String resultData, Bundle resultExtras,
19516            String[] requiredPermissions, int appOp, Bundle bOptions,
19517            boolean serialized, boolean sticky, int userId) {
19518        enforceNotIsolatedCaller("broadcastIntent");
19519        synchronized(this) {
19520            intent = verifyBroadcastLocked(intent);
19521
19522            final ProcessRecord callerApp = getRecordForAppLocked(caller);
19523            final int callingPid = Binder.getCallingPid();
19524            final int callingUid = Binder.getCallingUid();
19525            final long origId = Binder.clearCallingIdentity();
19526            int res = broadcastIntentLocked(callerApp,
19527                    callerApp != null ? callerApp.info.packageName : null,
19528                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19529                    requiredPermissions, appOp, bOptions, serialized, sticky,
19530                    callingPid, callingUid, userId);
19531            Binder.restoreCallingIdentity(origId);
19532            return res;
19533        }
19534    }
19535
19536
19537    int broadcastIntentInPackage(String packageName, int uid,
19538            Intent intent, String resolvedType, IIntentReceiver resultTo,
19539            int resultCode, String resultData, Bundle resultExtras,
19540            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19541            int userId) {
19542        synchronized(this) {
19543            intent = verifyBroadcastLocked(intent);
19544
19545            final long origId = Binder.clearCallingIdentity();
19546            String[] requiredPermissions = requiredPermission == null ? null
19547                    : new String[] {requiredPermission};
19548            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19549                    resultTo, resultCode, resultData, resultExtras,
19550                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19551                    sticky, -1, uid, userId);
19552            Binder.restoreCallingIdentity(origId);
19553            return res;
19554        }
19555    }
19556
19557    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19558        // Refuse possible leaked file descriptors
19559        if (intent != null && intent.hasFileDescriptors() == true) {
19560            throw new IllegalArgumentException("File descriptors passed in Intent");
19561        }
19562
19563        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19564                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19565
19566        synchronized(this) {
19567            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19568                    != PackageManager.PERMISSION_GRANTED) {
19569                String msg = "Permission Denial: unbroadcastIntent() from pid="
19570                        + Binder.getCallingPid()
19571                        + ", uid=" + Binder.getCallingUid()
19572                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19573                Slog.w(TAG, msg);
19574                throw new SecurityException(msg);
19575            }
19576            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19577            if (stickies != null) {
19578                ArrayList<Intent> list = stickies.get(intent.getAction());
19579                if (list != null) {
19580                    int N = list.size();
19581                    int i;
19582                    for (i=0; i<N; i++) {
19583                        if (intent.filterEquals(list.get(i))) {
19584                            list.remove(i);
19585                            break;
19586                        }
19587                    }
19588                    if (list.size() <= 0) {
19589                        stickies.remove(intent.getAction());
19590                    }
19591                }
19592                if (stickies.size() <= 0) {
19593                    mStickyBroadcasts.remove(userId);
19594                }
19595            }
19596        }
19597    }
19598
19599    void backgroundServicesFinishedLocked(int userId) {
19600        for (BroadcastQueue queue : mBroadcastQueues) {
19601            queue.backgroundServicesFinishedLocked(userId);
19602        }
19603    }
19604
19605    public void finishReceiver(IBinder who, int resultCode, String resultData,
19606            Bundle resultExtras, boolean resultAbort, int flags) {
19607        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19608
19609        // Refuse possible leaked file descriptors
19610        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19611            throw new IllegalArgumentException("File descriptors passed in Bundle");
19612        }
19613
19614        final long origId = Binder.clearCallingIdentity();
19615        try {
19616            boolean doNext = false;
19617            BroadcastRecord r;
19618
19619            synchronized(this) {
19620                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19621                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19622                r = queue.getMatchingOrderedReceiver(who);
19623                if (r != null) {
19624                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19625                        resultData, resultExtras, resultAbort, true);
19626                }
19627            }
19628
19629            if (doNext) {
19630                r.queue.processNextBroadcast(false);
19631            }
19632            trimApplications();
19633        } finally {
19634            Binder.restoreCallingIdentity(origId);
19635        }
19636    }
19637
19638    // =========================================================
19639    // INSTRUMENTATION
19640    // =========================================================
19641
19642    public boolean startInstrumentation(ComponentName className,
19643            String profileFile, int flags, Bundle arguments,
19644            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19645            int userId, String abiOverride) {
19646        enforceNotIsolatedCaller("startInstrumentation");
19647        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19648                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19649        // Refuse possible leaked file descriptors
19650        if (arguments != null && arguments.hasFileDescriptors()) {
19651            throw new IllegalArgumentException("File descriptors passed in Bundle");
19652        }
19653
19654        synchronized(this) {
19655            InstrumentationInfo ii = null;
19656            ApplicationInfo ai = null;
19657            try {
19658                ii = mContext.getPackageManager().getInstrumentationInfo(
19659                    className, STOCK_PM_FLAGS);
19660                ai = AppGlobals.getPackageManager().getApplicationInfo(
19661                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19662            } catch (PackageManager.NameNotFoundException e) {
19663            } catch (RemoteException e) {
19664            }
19665            if (ii == null) {
19666                reportStartInstrumentationFailureLocked(watcher, className,
19667                        "Unable to find instrumentation info for: " + className);
19668                return false;
19669            }
19670            if (ai == null) {
19671                reportStartInstrumentationFailureLocked(watcher, className,
19672                        "Unable to find instrumentation target package: " + ii.targetPackage);
19673                return false;
19674            }
19675            if (!ai.hasCode()) {
19676                reportStartInstrumentationFailureLocked(watcher, className,
19677                        "Instrumentation target has no code: " + ii.targetPackage);
19678                return false;
19679            }
19680
19681            int match = mContext.getPackageManager().checkSignatures(
19682                    ii.targetPackage, ii.packageName);
19683            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19684                String msg = "Permission Denial: starting instrumentation "
19685                        + className + " from pid="
19686                        + Binder.getCallingPid()
19687                        + ", uid=" + Binder.getCallingPid()
19688                        + " not allowed because package " + ii.packageName
19689                        + " does not have a signature matching the target "
19690                        + ii.targetPackage;
19691                reportStartInstrumentationFailureLocked(watcher, className, msg);
19692                throw new SecurityException(msg);
19693            }
19694
19695            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19696            activeInstr.mClass = className;
19697            String defProcess = ai.processName;;
19698            if (ii.targetProcesses == null) {
19699                activeInstr.mTargetProcesses = new String[]{ai.processName};
19700            } else if (ii.targetProcesses.equals("*")) {
19701                activeInstr.mTargetProcesses = new String[0];
19702            } else {
19703                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19704                defProcess = activeInstr.mTargetProcesses[0];
19705            }
19706            activeInstr.mTargetInfo = ai;
19707            activeInstr.mProfileFile = profileFile;
19708            activeInstr.mArguments = arguments;
19709            activeInstr.mWatcher = watcher;
19710            activeInstr.mUiAutomationConnection = uiAutomationConnection;
19711            activeInstr.mResultClass = className;
19712
19713            final long origId = Binder.clearCallingIdentity();
19714            // Instrumentation can kill and relaunch even persistent processes
19715            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19716                    "start instr");
19717            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19718            app.instr = activeInstr;
19719            activeInstr.mFinished = false;
19720            activeInstr.mRunningProcesses.add(app);
19721            if (!mActiveInstrumentation.contains(activeInstr)) {
19722                mActiveInstrumentation.add(activeInstr);
19723            }
19724            Binder.restoreCallingIdentity(origId);
19725        }
19726
19727        return true;
19728    }
19729
19730    /**
19731     * Report errors that occur while attempting to start Instrumentation.  Always writes the
19732     * error to the logs, but if somebody is watching, send the report there too.  This enables
19733     * the "am" command to report errors with more information.
19734     *
19735     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19736     * @param cn The component name of the instrumentation.
19737     * @param report The error report.
19738     */
19739    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19740            ComponentName cn, String report) {
19741        Slog.w(TAG, report);
19742        if (watcher != null) {
19743            Bundle results = new Bundle();
19744            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19745            results.putString("Error", report);
19746            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19747        }
19748    }
19749
19750    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19751        if (app.instr == null) {
19752            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19753            return;
19754        }
19755
19756        if (!app.instr.mFinished && results != null) {
19757            if (app.instr.mCurResults == null) {
19758                app.instr.mCurResults = new Bundle(results);
19759            } else {
19760                app.instr.mCurResults.putAll(results);
19761            }
19762        }
19763    }
19764
19765    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
19766        int userId = UserHandle.getCallingUserId();
19767        // Refuse possible leaked file descriptors
19768        if (results != null && results.hasFileDescriptors()) {
19769            throw new IllegalArgumentException("File descriptors passed in Intent");
19770        }
19771
19772        synchronized(this) {
19773            ProcessRecord app = getRecordForAppLocked(target);
19774            if (app == null) {
19775                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
19776                return;
19777            }
19778            final long origId = Binder.clearCallingIdentity();
19779            addInstrumentationResultsLocked(app, results);
19780            Binder.restoreCallingIdentity(origId);
19781        }
19782    }
19783
19784    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
19785        if (app.instr == null) {
19786            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19787            return;
19788        }
19789
19790        if (!app.instr.mFinished) {
19791            if (app.instr.mWatcher != null) {
19792                Bundle finalResults = app.instr.mCurResults;
19793                if (finalResults != null) {
19794                    if (app.instr.mCurResults != null && results != null) {
19795                        finalResults.putAll(results);
19796                    }
19797                } else {
19798                    finalResults = results;
19799                }
19800                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
19801                        app.instr.mClass, resultCode, finalResults);
19802            }
19803
19804            // Can't call out of the system process with a lock held, so post a message.
19805            if (app.instr.mUiAutomationConnection != null) {
19806                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
19807                        app.instr.mUiAutomationConnection).sendToTarget();
19808            }
19809            app.instr.mFinished = true;
19810        }
19811
19812        app.instr.removeProcess(app);
19813        app.instr = null;
19814
19815        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
19816                "finished inst");
19817    }
19818
19819    public void finishInstrumentation(IApplicationThread target,
19820            int resultCode, Bundle results) {
19821        int userId = UserHandle.getCallingUserId();
19822        // Refuse possible leaked file descriptors
19823        if (results != null && results.hasFileDescriptors()) {
19824            throw new IllegalArgumentException("File descriptors passed in Intent");
19825        }
19826
19827        synchronized(this) {
19828            ProcessRecord app = getRecordForAppLocked(target);
19829            if (app == null) {
19830                Slog.w(TAG, "finishInstrumentation: no app for " + target);
19831                return;
19832            }
19833            final long origId = Binder.clearCallingIdentity();
19834            finishInstrumentationLocked(app, resultCode, results);
19835            Binder.restoreCallingIdentity(origId);
19836        }
19837    }
19838
19839    // =========================================================
19840    // CONFIGURATION
19841    // =========================================================
19842
19843    public ConfigurationInfo getDeviceConfigurationInfo() {
19844        ConfigurationInfo config = new ConfigurationInfo();
19845        synchronized (this) {
19846            final Configuration globalConfig = getGlobalConfiguration();
19847            config.reqTouchScreen = globalConfig.touchscreen;
19848            config.reqKeyboardType = globalConfig.keyboard;
19849            config.reqNavigation = globalConfig.navigation;
19850            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
19851                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
19852                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
19853            }
19854            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
19855                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
19856                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
19857            }
19858            config.reqGlEsVersion = GL_ES_VERSION;
19859        }
19860        return config;
19861    }
19862
19863    ActivityStack getFocusedStack() {
19864        return mStackSupervisor.getFocusedStack();
19865    }
19866
19867    @Override
19868    public int getFocusedStackId() throws RemoteException {
19869        ActivityStack focusedStack = getFocusedStack();
19870        if (focusedStack != null) {
19871            return focusedStack.getStackId();
19872        }
19873        return -1;
19874    }
19875
19876    public Configuration getConfiguration() {
19877        Configuration ci;
19878        synchronized(this) {
19879            ci = new Configuration(getGlobalConfiguration());
19880            ci.userSetLocale = false;
19881        }
19882        return ci;
19883    }
19884
19885    @Override
19886    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
19887        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
19888        synchronized (this) {
19889            mSuppressResizeConfigChanges = suppress;
19890        }
19891    }
19892
19893    /**
19894     * NOTE: For the pinned stack, this method is only called after the bounds animation has
19895     *       animated the stack to the fullscreen.
19896     */
19897    @Override
19898    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
19899        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
19900        if (StackId.isHomeOrRecentsStack(fromStackId)) {
19901            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
19902        }
19903        synchronized (this) {
19904            final long origId = Binder.clearCallingIdentity();
19905            try {
19906                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
19907            } finally {
19908                Binder.restoreCallingIdentity(origId);
19909            }
19910        }
19911    }
19912
19913    @Override
19914    public void updatePersistentConfiguration(Configuration values) {
19915        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
19916        enforceWriteSettingsPermission("updatePersistentConfiguration()");
19917        if (values == null) {
19918            throw new NullPointerException("Configuration must not be null");
19919        }
19920
19921        int userId = UserHandle.getCallingUserId();
19922
19923        synchronized(this) {
19924            updatePersistentConfigurationLocked(values, userId);
19925        }
19926    }
19927
19928    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
19929        final long origId = Binder.clearCallingIdentity();
19930        try {
19931            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
19932        } finally {
19933            Binder.restoreCallingIdentity(origId);
19934        }
19935    }
19936
19937    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
19938        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
19939                FONT_SCALE, 1.0f, userId);
19940
19941        synchronized (this) {
19942            if (getGlobalConfiguration().fontScale == scaleFactor) {
19943                return;
19944            }
19945
19946            final Configuration configuration
19947                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19948            configuration.fontScale = scaleFactor;
19949            updatePersistentConfigurationLocked(configuration, userId);
19950        }
19951    }
19952
19953    private void enforceWriteSettingsPermission(String func) {
19954        int uid = Binder.getCallingUid();
19955        if (uid == ROOT_UID) {
19956            return;
19957        }
19958
19959        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
19960                Settings.getPackageNameForUid(mContext, uid), false)) {
19961            return;
19962        }
19963
19964        String msg = "Permission Denial: " + func + " from pid="
19965                + Binder.getCallingPid()
19966                + ", uid=" + uid
19967                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
19968        Slog.w(TAG, msg);
19969        throw new SecurityException(msg);
19970    }
19971
19972    @Override
19973    public boolean updateConfiguration(Configuration values) {
19974        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
19975
19976        synchronized(this) {
19977            if (values == null && mWindowManager != null) {
19978                // sentinel: fetch the current configuration from the window manager
19979                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19980            }
19981
19982            if (mWindowManager != null) {
19983                // Update OOM levels based on display size.
19984                mProcessList.applyDisplaySize(mWindowManager);
19985            }
19986
19987            final long origId = Binder.clearCallingIdentity();
19988            try {
19989                if (values != null) {
19990                    Settings.System.clearConfiguration(values);
19991                }
19992                updateConfigurationLocked(values, null, false, false /* persistent */,
19993                        UserHandle.USER_NULL, false /* deferResume */,
19994                        mTmpUpdateConfigurationResult);
19995                return mTmpUpdateConfigurationResult.changes != 0;
19996            } finally {
19997                Binder.restoreCallingIdentity(origId);
19998            }
19999        }
20000    }
20001
20002    void updateUserConfigurationLocked() {
20003        final Configuration configuration = new Configuration(getGlobalConfiguration());
20004        final int currentUserId = mUserController.getCurrentUserIdLocked();
20005        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20006                currentUserId, Settings.System.canWrite(mContext));
20007        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20008                false /* persistent */, currentUserId, false /* deferResume */);
20009    }
20010
20011    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20012            boolean initLocale) {
20013        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20014    }
20015
20016    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20017            boolean initLocale, boolean deferResume) {
20018        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20019        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20020                UserHandle.USER_NULL, deferResume);
20021    }
20022
20023    // To cache the list of supported system locales
20024    private String[] mSupportedSystemLocales = null;
20025
20026    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20027            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20028        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20029                deferResume, null /* result */);
20030    }
20031
20032    /**
20033     * Do either or both things: (1) change the current configuration, and (2)
20034     * make sure the given activity is running with the (now) current
20035     * configuration.  Returns true if the activity has been left running, or
20036     * false if <var>starting</var> is being destroyed to match the new
20037     * configuration.
20038     *
20039     * @param userId is only used when persistent parameter is set to true to persist configuration
20040     *               for that particular user
20041     */
20042    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20043            boolean initLocale, boolean persistent, int userId, boolean deferResume,
20044            UpdateConfigurationResult result) {
20045        int changes = 0;
20046        boolean kept = true;
20047
20048        if (mWindowManager != null) {
20049            mWindowManager.deferSurfaceLayout();
20050        }
20051        try {
20052            if (values != null) {
20053                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20054                        deferResume);
20055            }
20056
20057            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20058        } finally {
20059            if (mWindowManager != null) {
20060                mWindowManager.continueSurfaceLayout();
20061            }
20062        }
20063
20064        if (result != null) {
20065            result.changes = changes;
20066            result.activityRelaunched = !kept;
20067        }
20068        return kept;
20069    }
20070
20071    /** Update default (global) configuration and notify listeners about changes. */
20072    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20073            boolean persistent, int userId, boolean deferResume) {
20074        mTempConfig.setTo(getGlobalConfiguration());
20075        final int changes = mTempConfig.updateFrom(values);
20076        if (changes == 0) {
20077            return 0;
20078        }
20079
20080        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20081                "Updating global configuration to: " + values);
20082
20083        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20084
20085        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20086            final LocaleList locales = values.getLocales();
20087            int bestLocaleIndex = 0;
20088            if (locales.size() > 1) {
20089                if (mSupportedSystemLocales == null) {
20090                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20091                }
20092                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20093            }
20094            SystemProperties.set("persist.sys.locale",
20095                    locales.get(bestLocaleIndex).toLanguageTag());
20096            LocaleList.setDefault(locales, bestLocaleIndex);
20097            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20098                    locales.get(bestLocaleIndex)));
20099        }
20100
20101        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20102        mTempConfig.seq = mConfigurationSeq;
20103
20104        // Update stored global config and notify everyone about the change.
20105        mStackSupervisor.onConfigurationChanged(mTempConfig);
20106
20107        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20108        // TODO(multi-display): Update UsageEvents#Event to include displayId.
20109        mUsageStatsService.reportConfigurationChange(mTempConfig,
20110                mUserController.getCurrentUserIdLocked());
20111
20112        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20113        mShowDialogs = shouldShowDialogs(mTempConfig);
20114
20115        AttributeCache ac = AttributeCache.instance();
20116        if (ac != null) {
20117            ac.updateConfiguration(mTempConfig);
20118        }
20119
20120        // Make sure all resources in our process are updated right now, so that anyone who is going
20121        // to retrieve resource values after we return will be sure to get the new ones. This is
20122        // especially important during boot, where the first config change needs to guarantee all
20123        // resources have that config before following boot code is executed.
20124        mSystemThread.applyConfigurationToResources(mTempConfig);
20125
20126        // We need another copy of global config because we're scheduling some calls instead of
20127        // running them in place. We need to be sure that object we send will be handled unchanged.
20128        final Configuration configCopy = new Configuration(mTempConfig);
20129        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20130            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20131            msg.obj = configCopy;
20132            msg.arg1 = userId;
20133            mHandler.sendMessage(msg);
20134        }
20135
20136        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20137            ProcessRecord app = mLruProcesses.get(i);
20138            try {
20139                if (app.thread != null) {
20140                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20141                            + app.processName + " new config " + configCopy);
20142                    app.thread.scheduleConfigurationChanged(configCopy);
20143                }
20144            } catch (Exception e) {
20145            }
20146        }
20147
20148        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20149        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20150                | Intent.FLAG_RECEIVER_FOREGROUND
20151                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20152        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20153                AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20154                UserHandle.USER_ALL);
20155        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20156            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20157            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20158                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20159                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20160            if (initLocale || !mProcessesReady) {
20161                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20162            }
20163            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20164                    AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20165                    UserHandle.USER_ALL);
20166        }
20167
20168        // Override configuration of the default display duplicates global config, so we need to
20169        // update it also. This will also notify WindowManager about changes.
20170        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20171                DEFAULT_DISPLAY);
20172
20173        return changes;
20174    }
20175
20176    @Override
20177    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20178        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20179
20180        synchronized (this) {
20181            // Check if display is initialized in AM.
20182            if (!mStackSupervisor.isDisplayAdded(displayId)) {
20183                // Call might come when display is not yet added or has already been removed.
20184                if (DEBUG_CONFIGURATION) {
20185                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20186                            + displayId);
20187                }
20188                return false;
20189            }
20190
20191            if (values == null && mWindowManager != null) {
20192                // sentinel: fetch the current configuration from the window manager
20193                values = mWindowManager.computeNewConfiguration(displayId);
20194            }
20195
20196            if (mWindowManager != null) {
20197                // Update OOM levels based on display size.
20198                mProcessList.applyDisplaySize(mWindowManager);
20199            }
20200
20201            final long origId = Binder.clearCallingIdentity();
20202            try {
20203                if (values != null) {
20204                    Settings.System.clearConfiguration(values);
20205                }
20206                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20207                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20208                return mTmpUpdateConfigurationResult.changes != 0;
20209            } finally {
20210                Binder.restoreCallingIdentity(origId);
20211            }
20212        }
20213    }
20214
20215    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20216            boolean deferResume, int displayId) {
20217        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20218                displayId, null /* result */);
20219    }
20220
20221    /**
20222     * Updates override configuration specific for the selected display. If no config is provided,
20223     * new one will be computed in WM based on current display info.
20224     */
20225    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20226            ActivityRecord starting, boolean deferResume, int displayId,
20227            UpdateConfigurationResult result) {
20228        int changes = 0;
20229        boolean kept = true;
20230
20231        if (mWindowManager != null) {
20232            mWindowManager.deferSurfaceLayout();
20233        }
20234        try {
20235            if (values != null) {
20236                if (displayId == DEFAULT_DISPLAY) {
20237                    // Override configuration of the default display duplicates global config, so
20238                    // we're calling global config update instead for default display. It will also
20239                    // apply the correct override config.
20240                    changes = updateGlobalConfiguration(values, false /* initLocale */,
20241                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20242                } else {
20243                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20244                }
20245            }
20246
20247            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20248        } finally {
20249            if (mWindowManager != null) {
20250                mWindowManager.continueSurfaceLayout();
20251            }
20252        }
20253
20254        if (result != null) {
20255            result.changes = changes;
20256            result.activityRelaunched = !kept;
20257        }
20258        return kept;
20259    }
20260
20261    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20262            int displayId) {
20263        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20264        final int changes = mTempConfig.updateFrom(values);
20265        if (changes == 0) {
20266            return 0;
20267        }
20268
20269        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
20270                + " for displayId=" + displayId);
20271        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20272
20273        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20274        if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20275            // Reset the unsupported display size dialog.
20276            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20277
20278            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20279        }
20280
20281        // Update the configuration with WM first and check if any of the stacks need to be resized
20282        // due to the configuration change. If so, resize the stacks now and do any relaunches if
20283        // necessary. This way we don't need to relaunch again afterwards in
20284        // ensureActivityConfigurationLocked().
20285        if (mWindowManager != null) {
20286            final int[] resizedStacks =
20287                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20288            if (resizedStacks != null) {
20289                for (int stackId : resizedStacks) {
20290                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20291                }
20292            }
20293        }
20294
20295        return changes;
20296    }
20297
20298    /** Applies latest configuration and/or visibility updates if needed. */
20299    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20300        boolean kept = true;
20301        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20302        // mainStack is null during startup.
20303        if (mainStack != null) {
20304            if (changes != 0 && starting == null) {
20305                // If the configuration changed, and the caller is not already
20306                // in the process of starting an activity, then find the top
20307                // activity to check if its configuration needs to change.
20308                starting = mainStack.topRunningActivityLocked();
20309            }
20310
20311            if (starting != null) {
20312                kept = starting.ensureActivityConfigurationLocked(changes,
20313                        false /* preserveWindow */);
20314                // And we need to make sure at this point that all other activities
20315                // are made visible with the correct configuration.
20316                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20317                        !PRESERVE_WINDOWS);
20318            }
20319        }
20320
20321        return kept;
20322    }
20323
20324    /** Helper method that requests bounds from WM and applies them to stack. */
20325    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20326        final Rect newStackBounds = new Rect();
20327        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20328        mStackSupervisor.resizeStackLocked(
20329                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20330                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20331                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20332    }
20333
20334    /**
20335     * Decide based on the configuration whether we should show the ANR,
20336     * crash, etc dialogs.  The idea is that if there is no affordance to
20337     * press the on-screen buttons, or the user experience would be more
20338     * greatly impacted than the crash itself, we shouldn't show the dialog.
20339     *
20340     * A thought: SystemUI might also want to get told about this, the Power
20341     * dialog / global actions also might want different behaviors.
20342     */
20343    private static boolean shouldShowDialogs(Configuration config) {
20344        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20345                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20346                                   && config.navigation == Configuration.NAVIGATION_NONAV);
20347        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20348        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20349                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20350                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20351                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20352        return inputMethodExists && uiModeSupportsDialogs;
20353    }
20354
20355    @Override
20356    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20357        synchronized (this) {
20358            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20359            if (srec != null) {
20360                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20361            }
20362        }
20363        return false;
20364    }
20365
20366    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20367            Intent resultData) {
20368
20369        synchronized (this) {
20370            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20371            if (r != null) {
20372                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20373            }
20374            return false;
20375        }
20376    }
20377
20378    public int getLaunchedFromUid(IBinder activityToken) {
20379        ActivityRecord srec;
20380        synchronized (this) {
20381            srec = ActivityRecord.forTokenLocked(activityToken);
20382        }
20383        if (srec == null) {
20384            return -1;
20385        }
20386        return srec.launchedFromUid;
20387    }
20388
20389    public String getLaunchedFromPackage(IBinder activityToken) {
20390        ActivityRecord srec;
20391        synchronized (this) {
20392            srec = ActivityRecord.forTokenLocked(activityToken);
20393        }
20394        if (srec == null) {
20395            return null;
20396        }
20397        return srec.launchedFromPackage;
20398    }
20399
20400    // =========================================================
20401    // LIFETIME MANAGEMENT
20402    // =========================================================
20403
20404    // Returns whether the app is receiving broadcast.
20405    // If receiving, fetch all broadcast queues which the app is
20406    // the current [or imminent] receiver on.
20407    private boolean isReceivingBroadcastLocked(ProcessRecord app,
20408            ArraySet<BroadcastQueue> receivingQueues) {
20409        if (!app.curReceivers.isEmpty()) {
20410            for (BroadcastRecord r : app.curReceivers) {
20411                receivingQueues.add(r.queue);
20412            }
20413            return true;
20414        }
20415
20416        // It's not the current receiver, but it might be starting up to become one
20417        for (BroadcastQueue queue : mBroadcastQueues) {
20418            final BroadcastRecord r = queue.mPendingBroadcast;
20419            if (r != null && r.curApp == app) {
20420                // found it; report which queue it's in
20421                receivingQueues.add(queue);
20422            }
20423        }
20424
20425        return !receivingQueues.isEmpty();
20426    }
20427
20428    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20429            int targetUid, ComponentName targetComponent, String targetProcess) {
20430        if (!mTrackingAssociations) {
20431            return null;
20432        }
20433        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20434                = mAssociations.get(targetUid);
20435        if (components == null) {
20436            components = new ArrayMap<>();
20437            mAssociations.put(targetUid, components);
20438        }
20439        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20440        if (sourceUids == null) {
20441            sourceUids = new SparseArray<>();
20442            components.put(targetComponent, sourceUids);
20443        }
20444        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20445        if (sourceProcesses == null) {
20446            sourceProcesses = new ArrayMap<>();
20447            sourceUids.put(sourceUid, sourceProcesses);
20448        }
20449        Association ass = sourceProcesses.get(sourceProcess);
20450        if (ass == null) {
20451            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20452                    targetProcess);
20453            sourceProcesses.put(sourceProcess, ass);
20454        }
20455        ass.mCount++;
20456        ass.mNesting++;
20457        if (ass.mNesting == 1) {
20458            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20459            ass.mLastState = sourceState;
20460        }
20461        return ass;
20462    }
20463
20464    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20465            ComponentName targetComponent) {
20466        if (!mTrackingAssociations) {
20467            return;
20468        }
20469        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20470                = mAssociations.get(targetUid);
20471        if (components == null) {
20472            return;
20473        }
20474        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20475        if (sourceUids == null) {
20476            return;
20477        }
20478        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20479        if (sourceProcesses == null) {
20480            return;
20481        }
20482        Association ass = sourceProcesses.get(sourceProcess);
20483        if (ass == null || ass.mNesting <= 0) {
20484            return;
20485        }
20486        ass.mNesting--;
20487        if (ass.mNesting == 0) {
20488            long uptime = SystemClock.uptimeMillis();
20489            ass.mTime += uptime - ass.mStartTime;
20490            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20491                    += uptime - ass.mLastStateUptime;
20492            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20493        }
20494    }
20495
20496    private void noteUidProcessState(final int uid, final int state) {
20497        mBatteryStatsService.noteUidProcessState(uid, state);
20498        if (mTrackingAssociations) {
20499            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20500                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20501                        = mAssociations.valueAt(i1);
20502                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20503                    SparseArray<ArrayMap<String, Association>> sourceUids
20504                            = targetComponents.valueAt(i2);
20505                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20506                    if (sourceProcesses != null) {
20507                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20508                            Association ass = sourceProcesses.valueAt(i4);
20509                            if (ass.mNesting >= 1) {
20510                                // currently associated
20511                                long uptime = SystemClock.uptimeMillis();
20512                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20513                                        += uptime - ass.mLastStateUptime;
20514                                ass.mLastState = state;
20515                                ass.mLastStateUptime = uptime;
20516                            }
20517                        }
20518                    }
20519                }
20520            }
20521        }
20522    }
20523
20524    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20525            boolean doingAll, long now) {
20526        if (mAdjSeq == app.adjSeq) {
20527            // This adjustment has already been computed.
20528            return app.curRawAdj;
20529        }
20530
20531        if (app.thread == null) {
20532            app.adjSeq = mAdjSeq;
20533            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20534            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20535            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20536        }
20537
20538        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20539        app.adjSource = null;
20540        app.adjTarget = null;
20541        app.empty = false;
20542        app.cached = false;
20543
20544        final int activitiesSize = app.activities.size();
20545
20546        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20547            // The max adjustment doesn't allow this app to be anything
20548            // below foreground, so it is not worth doing work for it.
20549            app.adjType = "fixed";
20550            app.adjSeq = mAdjSeq;
20551            app.curRawAdj = app.maxAdj;
20552            app.foregroundActivities = false;
20553            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20554            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20555            // System processes can do UI, and when they do we want to have
20556            // them trim their memory after the user leaves the UI.  To
20557            // facilitate this, here we need to determine whether or not it
20558            // is currently showing UI.
20559            app.systemNoUi = true;
20560            if (app == TOP_APP) {
20561                app.systemNoUi = false;
20562                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20563                app.adjType = "pers-top-activity";
20564            } else if (app.hasTopUi) {
20565                app.systemNoUi = false;
20566                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20567                app.adjType = "pers-top-ui";
20568            } else if (activitiesSize > 0) {
20569                for (int j = 0; j < activitiesSize; j++) {
20570                    final ActivityRecord r = app.activities.get(j);
20571                    if (r.visible) {
20572                        app.systemNoUi = false;
20573                    }
20574                }
20575            }
20576            if (!app.systemNoUi) {
20577                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20578            }
20579            return (app.curAdj=app.maxAdj);
20580        }
20581
20582        app.systemNoUi = false;
20583
20584        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20585
20586        // Determine the importance of the process, starting with most
20587        // important to least, and assign an appropriate OOM adjustment.
20588        int adj;
20589        int schedGroup;
20590        int procState;
20591        boolean foregroundActivities = false;
20592        mTmpBroadcastQueue.clear();
20593        if (app == TOP_APP) {
20594            // The last app on the list is the foreground app.
20595            adj = ProcessList.FOREGROUND_APP_ADJ;
20596            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20597            app.adjType = "top-activity";
20598            foregroundActivities = true;
20599            procState = PROCESS_STATE_CUR_TOP;
20600        } else if (app.instr != null) {
20601            // Don't want to kill running instrumentation.
20602            adj = ProcessList.FOREGROUND_APP_ADJ;
20603            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20604            app.adjType = "instrumentation";
20605            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20606        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20607            // An app that is currently receiving a broadcast also
20608            // counts as being in the foreground for OOM killer purposes.
20609            // It's placed in a sched group based on the nature of the
20610            // broadcast as reflected by which queue it's active in.
20611            adj = ProcessList.FOREGROUND_APP_ADJ;
20612            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20613                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20614            app.adjType = "broadcast";
20615            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20616        } else if (app.executingServices.size() > 0) {
20617            // An app that is currently executing a service callback also
20618            // counts as being in the foreground.
20619            adj = ProcessList.FOREGROUND_APP_ADJ;
20620            schedGroup = app.execServicesFg ?
20621                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20622            app.adjType = "exec-service";
20623            procState = ActivityManager.PROCESS_STATE_SERVICE;
20624            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20625        } else {
20626            // As far as we know the process is empty.  We may change our mind later.
20627            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20628            // At this point we don't actually know the adjustment.  Use the cached adj
20629            // value that the caller wants us to.
20630            adj = cachedAdj;
20631            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20632            app.cached = true;
20633            app.empty = true;
20634            app.adjType = "cch-empty";
20635        }
20636
20637        // Examine all activities if not already foreground.
20638        if (!foregroundActivities && activitiesSize > 0) {
20639            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20640            for (int j = 0; j < activitiesSize; j++) {
20641                final ActivityRecord r = app.activities.get(j);
20642                if (r.app != app) {
20643                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20644                            + " instead of expected " + app);
20645                    if (r.app == null || (r.app.uid == app.uid)) {
20646                        // Only fix things up when they look sane
20647                        r.app = app;
20648                    } else {
20649                        continue;
20650                    }
20651                }
20652                if (r.visible) {
20653                    // App has a visible activity; only upgrade adjustment.
20654                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20655                        adj = ProcessList.VISIBLE_APP_ADJ;
20656                        app.adjType = "visible";
20657                    }
20658                    if (procState > PROCESS_STATE_CUR_TOP) {
20659                        procState = PROCESS_STATE_CUR_TOP;
20660                    }
20661                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20662                    app.cached = false;
20663                    app.empty = false;
20664                    foregroundActivities = true;
20665                    final TaskRecord task = r.getTask();
20666                    if (task != null && minLayer > 0) {
20667                        final int layer = task.mLayerRank;
20668                        if (layer >= 0 && minLayer > layer) {
20669                            minLayer = layer;
20670                        }
20671                    }
20672                    break;
20673                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20674                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20675                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20676                        app.adjType = "pausing";
20677                    }
20678                    if (procState > PROCESS_STATE_CUR_TOP) {
20679                        procState = PROCESS_STATE_CUR_TOP;
20680                    }
20681                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20682                    app.cached = false;
20683                    app.empty = false;
20684                    foregroundActivities = true;
20685                } else if (r.state == ActivityState.STOPPING) {
20686                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20687                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20688                        app.adjType = "stopping";
20689                    }
20690                    // For the process state, we will at this point consider the
20691                    // process to be cached.  It will be cached either as an activity
20692                    // or empty depending on whether the activity is finishing.  We do
20693                    // this so that we can treat the process as cached for purposes of
20694                    // memory trimming (determing current memory level, trim command to
20695                    // send to process) since there can be an arbitrary number of stopping
20696                    // processes and they should soon all go into the cached state.
20697                    if (!r.finishing) {
20698                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20699                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20700                        }
20701                    }
20702                    app.cached = false;
20703                    app.empty = false;
20704                    foregroundActivities = true;
20705                } else {
20706                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20707                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20708                        app.adjType = "cch-act";
20709                    }
20710                }
20711            }
20712            if (adj == ProcessList.VISIBLE_APP_ADJ) {
20713                adj += minLayer;
20714            }
20715        }
20716
20717        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20718                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20719            if (app.foregroundServices) {
20720                // The user is aware of this app, so make it visible.
20721                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20722                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20723                app.cached = false;
20724                app.adjType = "fg-service";
20725                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20726            } else if (app.forcingToForeground != null) {
20727                // The user is aware of this app, so make it visible.
20728                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20729                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20730                app.cached = false;
20731                app.adjType = "force-fg";
20732                app.adjSource = app.forcingToForeground;
20733                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20734            } else if (app.hasOverlayUi) {
20735                // The process is display an overlay UI.
20736                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20737                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20738                app.cached = false;
20739                app.adjType = "has-overlay-ui";
20740                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20741            }
20742        }
20743
20744        if (app == mHeavyWeightProcess) {
20745            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
20746                // We don't want to kill the current heavy-weight process.
20747                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
20748                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20749                app.cached = false;
20750                app.adjType = "heavy";
20751            }
20752            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20753                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
20754            }
20755        }
20756
20757        if (app == mHomeProcess) {
20758            if (adj > ProcessList.HOME_APP_ADJ) {
20759                // This process is hosting what we currently consider to be the
20760                // home app, so we don't want to let it go into the background.
20761                adj = ProcessList.HOME_APP_ADJ;
20762                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20763                app.cached = false;
20764                app.adjType = "home";
20765            }
20766            if (procState > ActivityManager.PROCESS_STATE_HOME) {
20767                procState = ActivityManager.PROCESS_STATE_HOME;
20768            }
20769        }
20770
20771        if (app == mPreviousProcess && app.activities.size() > 0) {
20772            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20773                // This was the previous process that showed UI to the user.
20774                // We want to try to keep it around more aggressively, to give
20775                // a good experience around switching between two apps.
20776                adj = ProcessList.PREVIOUS_APP_ADJ;
20777                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20778                app.cached = false;
20779                app.adjType = "previous";
20780            }
20781            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20782                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20783            }
20784        }
20785
20786        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
20787                + " reason=" + app.adjType);
20788
20789        // By default, we use the computed adjustment.  It may be changed if
20790        // there are applications dependent on our services or providers, but
20791        // this gives us a baseline and makes sure we don't get into an
20792        // infinite recursion.
20793        app.adjSeq = mAdjSeq;
20794        app.curRawAdj = adj;
20795        app.hasStartedServices = false;
20796
20797        if (mBackupTarget != null && app == mBackupTarget.app) {
20798            // If possible we want to avoid killing apps while they're being backed up
20799            if (adj > ProcessList.BACKUP_APP_ADJ) {
20800                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
20801                adj = ProcessList.BACKUP_APP_ADJ;
20802                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
20803                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
20804                }
20805                app.adjType = "backup";
20806                app.cached = false;
20807            }
20808            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
20809                procState = ActivityManager.PROCESS_STATE_BACKUP;
20810            }
20811        }
20812
20813        boolean mayBeTop = false;
20814
20815        for (int is = app.services.size()-1;
20816                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20817                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20818                        || procState > ActivityManager.PROCESS_STATE_TOP);
20819                is--) {
20820            ServiceRecord s = app.services.valueAt(is);
20821            if (s.startRequested) {
20822                app.hasStartedServices = true;
20823                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
20824                    procState = ActivityManager.PROCESS_STATE_SERVICE;
20825                }
20826                if (app.hasShownUi && app != mHomeProcess) {
20827                    // If this process has shown some UI, let it immediately
20828                    // go to the LRU list because it may be pretty heavy with
20829                    // UI stuff.  We'll tag it with a label just to help
20830                    // debug and understand what is going on.
20831                    if (adj > ProcessList.SERVICE_ADJ) {
20832                        app.adjType = "cch-started-ui-services";
20833                    }
20834                } else {
20835                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
20836                        // This service has seen some activity within
20837                        // recent memory, so we will keep its process ahead
20838                        // of the background processes.
20839                        if (adj > ProcessList.SERVICE_ADJ) {
20840                            adj = ProcessList.SERVICE_ADJ;
20841                            app.adjType = "started-services";
20842                            app.cached = false;
20843                        }
20844                    }
20845                    // If we have let the service slide into the background
20846                    // state, still have some text describing what it is doing
20847                    // even though the service no longer has an impact.
20848                    if (adj > ProcessList.SERVICE_ADJ) {
20849                        app.adjType = "cch-started-services";
20850                    }
20851                }
20852            }
20853
20854            for (int conni = s.connections.size()-1;
20855                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20856                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20857                            || procState > ActivityManager.PROCESS_STATE_TOP);
20858                    conni--) {
20859                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
20860                for (int i = 0;
20861                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
20862                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20863                                || procState > ActivityManager.PROCESS_STATE_TOP);
20864                        i++) {
20865                    // XXX should compute this based on the max of
20866                    // all connected clients.
20867                    ConnectionRecord cr = clist.get(i);
20868                    if (cr.binding.client == app) {
20869                        // Binding to ourself is not interesting.
20870                        continue;
20871                    }
20872
20873                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
20874                        ProcessRecord client = cr.binding.client;
20875                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
20876                                TOP_APP, doingAll, now);
20877                        int clientProcState = client.curProcState;
20878                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20879                            // If the other app is cached for any reason, for purposes here
20880                            // we are going to consider it empty.  The specific cached state
20881                            // doesn't propagate except under certain conditions.
20882                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20883                        }
20884                        String adjType = null;
20885                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
20886                            // Not doing bind OOM management, so treat
20887                            // this guy more like a started service.
20888                            if (app.hasShownUi && app != mHomeProcess) {
20889                                // If this process has shown some UI, let it immediately
20890                                // go to the LRU list because it may be pretty heavy with
20891                                // UI stuff.  We'll tag it with a label just to help
20892                                // debug and understand what is going on.
20893                                if (adj > clientAdj) {
20894                                    adjType = "cch-bound-ui-services";
20895                                }
20896                                app.cached = false;
20897                                clientAdj = adj;
20898                                clientProcState = procState;
20899                            } else {
20900                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
20901                                    // This service has not seen activity within
20902                                    // recent memory, so allow it to drop to the
20903                                    // LRU list if there is no other reason to keep
20904                                    // it around.  We'll also tag it with a label just
20905                                    // to help debug and undertand what is going on.
20906                                    if (adj > clientAdj) {
20907                                        adjType = "cch-bound-services";
20908                                    }
20909                                    clientAdj = adj;
20910                                }
20911                            }
20912                        }
20913                        if (adj > clientAdj) {
20914                            // If this process has recently shown UI, and
20915                            // the process that is binding to it is less
20916                            // important than being visible, then we don't
20917                            // care about the binding as much as we care
20918                            // about letting this process get into the LRU
20919                            // list to be killed and restarted if needed for
20920                            // memory.
20921                            if (app.hasShownUi && app != mHomeProcess
20922                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20923                                adjType = "cch-bound-ui-services";
20924                            } else {
20925                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
20926                                        |Context.BIND_IMPORTANT)) != 0) {
20927                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
20928                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
20929                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
20930                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
20931                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20932                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20933                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
20934                                    adj = clientAdj;
20935                                } else {
20936                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20937                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
20938                                    }
20939                                }
20940                                if (!client.cached) {
20941                                    app.cached = false;
20942                                }
20943                                adjType = "service";
20944                            }
20945                        }
20946                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
20947                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
20948                            // This will treat important bound services identically to
20949                            // the top app, which may behave differently than generic
20950                            // foreground work.
20951                            if (client.curSchedGroup > schedGroup) {
20952                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20953                                    schedGroup = client.curSchedGroup;
20954                                } else {
20955                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20956                                }
20957                            }
20958                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20959                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20960                                    // Special handling of clients who are in the top state.
20961                                    // We *may* want to consider this process to be in the
20962                                    // top state as well, but only if there is not another
20963                                    // reason for it to be running.  Being on the top is a
20964                                    // special state, meaning you are specifically running
20965                                    // for the current top app.  If the process is already
20966                                    // running in the background for some other reason, it
20967                                    // is more important to continue considering it to be
20968                                    // in the background state.
20969                                    mayBeTop = true;
20970                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20971                                } else {
20972                                    // Special handling for above-top states (persistent
20973                                    // processes).  These should not bring the current process
20974                                    // into the top state, since they are not on top.  Instead
20975                                    // give them the best state after that.
20976                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
20977                                        clientProcState =
20978                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20979                                    } else if (mWakefulness
20980                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
20981                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
20982                                                    != 0) {
20983                                        clientProcState =
20984                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20985                                    } else {
20986                                        clientProcState =
20987                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20988                                    }
20989                                }
20990                            }
20991                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
20992                            if (clientProcState <
20993                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
20994                                clientProcState =
20995                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
20996                            }
20997                        } else {
20998                            if (clientProcState <
20999                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21000                                clientProcState =
21001                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21002                            }
21003                        }
21004                        if (procState > clientProcState) {
21005                            procState = clientProcState;
21006                        }
21007                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21008                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21009                            app.pendingUiClean = true;
21010                        }
21011                        if (adjType != null) {
21012                            app.adjType = adjType;
21013                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21014                                    .REASON_SERVICE_IN_USE;
21015                            app.adjSource = cr.binding.client;
21016                            app.adjSourceProcState = clientProcState;
21017                            app.adjTarget = s.name;
21018                        }
21019                    }
21020                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21021                        app.treatLikeActivity = true;
21022                    }
21023                    final ActivityRecord a = cr.activity;
21024                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21025                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21026                            (a.visible || a.state == ActivityState.RESUMED ||
21027                             a.state == ActivityState.PAUSING)) {
21028                            adj = ProcessList.FOREGROUND_APP_ADJ;
21029                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21030                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21031                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21032                                } else {
21033                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21034                                }
21035                            }
21036                            app.cached = false;
21037                            app.adjType = "service";
21038                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21039                                    .REASON_SERVICE_IN_USE;
21040                            app.adjSource = a;
21041                            app.adjSourceProcState = procState;
21042                            app.adjTarget = s.name;
21043                        }
21044                    }
21045                }
21046            }
21047        }
21048
21049        for (int provi = app.pubProviders.size()-1;
21050                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21051                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21052                        || procState > ActivityManager.PROCESS_STATE_TOP);
21053                provi--) {
21054            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21055            for (int i = cpr.connections.size()-1;
21056                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21057                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21058                            || procState > ActivityManager.PROCESS_STATE_TOP);
21059                    i--) {
21060                ContentProviderConnection conn = cpr.connections.get(i);
21061                ProcessRecord client = conn.client;
21062                if (client == app) {
21063                    // Being our own client is not interesting.
21064                    continue;
21065                }
21066                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21067                int clientProcState = client.curProcState;
21068                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21069                    // If the other app is cached for any reason, for purposes here
21070                    // we are going to consider it empty.
21071                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21072                }
21073                if (adj > clientAdj) {
21074                    if (app.hasShownUi && app != mHomeProcess
21075                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21076                        app.adjType = "cch-ui-provider";
21077                    } else {
21078                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21079                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21080                        app.adjType = "provider";
21081                    }
21082                    app.cached &= client.cached;
21083                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21084                            .REASON_PROVIDER_IN_USE;
21085                    app.adjSource = client;
21086                    app.adjSourceProcState = clientProcState;
21087                    app.adjTarget = cpr.name;
21088                }
21089                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21090                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21091                        // Special handling of clients who are in the top state.
21092                        // We *may* want to consider this process to be in the
21093                        // top state as well, but only if there is not another
21094                        // reason for it to be running.  Being on the top is a
21095                        // special state, meaning you are specifically running
21096                        // for the current top app.  If the process is already
21097                        // running in the background for some other reason, it
21098                        // is more important to continue considering it to be
21099                        // in the background state.
21100                        mayBeTop = true;
21101                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21102                    } else {
21103                        // Special handling for above-top states (persistent
21104                        // processes).  These should not bring the current process
21105                        // into the top state, since they are not on top.  Instead
21106                        // give them the best state after that.
21107                        clientProcState =
21108                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21109                    }
21110                }
21111                if (procState > clientProcState) {
21112                    procState = clientProcState;
21113                }
21114                if (client.curSchedGroup > schedGroup) {
21115                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21116                }
21117            }
21118            // If the provider has external (non-framework) process
21119            // dependencies, ensure that its adjustment is at least
21120            // FOREGROUND_APP_ADJ.
21121            if (cpr.hasExternalProcessHandles()) {
21122                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21123                    adj = ProcessList.FOREGROUND_APP_ADJ;
21124                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21125                    app.cached = false;
21126                    app.adjType = "provider";
21127                    app.adjTarget = cpr.name;
21128                }
21129                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21130                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21131                }
21132            }
21133        }
21134
21135        if (app.lastProviderTime > 0 &&
21136                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21137            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21138                adj = ProcessList.PREVIOUS_APP_ADJ;
21139                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21140                app.cached = false;
21141                app.adjType = "provider";
21142            }
21143            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21144                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21145            }
21146        }
21147
21148        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21149            // A client of one of our services or providers is in the top state.  We
21150            // *may* want to be in the top state, but not if we are already running in
21151            // the background for some other reason.  For the decision here, we are going
21152            // to pick out a few specific states that we want to remain in when a client
21153            // is top (states that tend to be longer-term) and otherwise allow it to go
21154            // to the top state.
21155            switch (procState) {
21156                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21157                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21158                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21159                case ActivityManager.PROCESS_STATE_SERVICE:
21160                    // These all are longer-term states, so pull them up to the top
21161                    // of the background states, but not all the way to the top state.
21162                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21163                    break;
21164                default:
21165                    // Otherwise, top is a better choice, so take it.
21166                    procState = ActivityManager.PROCESS_STATE_TOP;
21167                    break;
21168            }
21169        }
21170
21171        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21172            if (app.hasClientActivities) {
21173                // This is a cached process, but with client activities.  Mark it so.
21174                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21175                app.adjType = "cch-client-act";
21176            } else if (app.treatLikeActivity) {
21177                // This is a cached process, but somebody wants us to treat it like it has
21178                // an activity, okay!
21179                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21180                app.adjType = "cch-as-act";
21181            }
21182        }
21183
21184        if (adj == ProcessList.SERVICE_ADJ) {
21185            if (doingAll) {
21186                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21187                mNewNumServiceProcs++;
21188                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21189                if (!app.serviceb) {
21190                    // This service isn't far enough down on the LRU list to
21191                    // normally be a B service, but if we are low on RAM and it
21192                    // is large we want to force it down since we would prefer to
21193                    // keep launcher over it.
21194                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21195                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21196                        app.serviceHighRam = true;
21197                        app.serviceb = true;
21198                        //Slog.i(TAG, "ADJ " + app + " high ram!");
21199                    } else {
21200                        mNewNumAServiceProcs++;
21201                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
21202                    }
21203                } else {
21204                    app.serviceHighRam = false;
21205                }
21206            }
21207            if (app.serviceb) {
21208                adj = ProcessList.SERVICE_B_ADJ;
21209            }
21210        }
21211
21212        app.curRawAdj = adj;
21213
21214        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21215        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21216        if (adj > app.maxAdj) {
21217            adj = app.maxAdj;
21218            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21219                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21220            }
21221        }
21222
21223        // Do final modification to adj.  Everything we do between here and applying
21224        // the final setAdj must be done in this function, because we will also use
21225        // it when computing the final cached adj later.  Note that we don't need to
21226        // worry about this for max adj above, since max adj will always be used to
21227        // keep it out of the cached vaues.
21228        app.curAdj = app.modifyRawOomAdj(adj);
21229        app.curSchedGroup = schedGroup;
21230        app.curProcState = procState;
21231        app.foregroundActivities = foregroundActivities;
21232
21233        return app.curRawAdj;
21234    }
21235
21236    /**
21237     * Record new PSS sample for a process.
21238     */
21239    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21240            long now) {
21241        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21242                swapPss * 1024);
21243        proc.lastPssTime = now;
21244        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21245        if (DEBUG_PSS) Slog.d(TAG_PSS,
21246                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21247                + " state=" + ProcessList.makeProcStateString(procState));
21248        if (proc.initialIdlePss == 0) {
21249            proc.initialIdlePss = pss;
21250        }
21251        proc.lastPss = pss;
21252        proc.lastSwapPss = swapPss;
21253        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21254            proc.lastCachedPss = pss;
21255            proc.lastCachedSwapPss = swapPss;
21256        }
21257
21258        final SparseArray<Pair<Long, String>> watchUids
21259                = mMemWatchProcesses.getMap().get(proc.processName);
21260        Long check = null;
21261        if (watchUids != null) {
21262            Pair<Long, String> val = watchUids.get(proc.uid);
21263            if (val == null) {
21264                val = watchUids.get(0);
21265            }
21266            if (val != null) {
21267                check = val.first;
21268            }
21269        }
21270        if (check != null) {
21271            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21272                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21273                if (!isDebuggable) {
21274                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21275                        isDebuggable = true;
21276                    }
21277                }
21278                if (isDebuggable) {
21279                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21280                    final ProcessRecord myProc = proc;
21281                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
21282                    mMemWatchDumpProcName = proc.processName;
21283                    mMemWatchDumpFile = heapdumpFile.toString();
21284                    mMemWatchDumpPid = proc.pid;
21285                    mMemWatchDumpUid = proc.uid;
21286                    BackgroundThread.getHandler().post(new Runnable() {
21287                        @Override
21288                        public void run() {
21289                            revokeUriPermission(ActivityThread.currentActivityThread()
21290                                            .getApplicationThread(),
21291                                    null, DumpHeapActivity.JAVA_URI,
21292                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
21293                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21294                                    UserHandle.myUserId());
21295                            ParcelFileDescriptor fd = null;
21296                            try {
21297                                heapdumpFile.delete();
21298                                fd = ParcelFileDescriptor.open(heapdumpFile,
21299                                        ParcelFileDescriptor.MODE_CREATE |
21300                                                ParcelFileDescriptor.MODE_TRUNCATE |
21301                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
21302                                                ParcelFileDescriptor.MODE_APPEND);
21303                                IApplicationThread thread = myProc.thread;
21304                                if (thread != null) {
21305                                    try {
21306                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
21307                                                "Requesting dump heap from "
21308                                                + myProc + " to " + heapdumpFile);
21309                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
21310                                    } catch (RemoteException e) {
21311                                    }
21312                                }
21313                            } catch (FileNotFoundException e) {
21314                                e.printStackTrace();
21315                            } finally {
21316                                if (fd != null) {
21317                                    try {
21318                                        fd.close();
21319                                    } catch (IOException e) {
21320                                    }
21321                                }
21322                            }
21323                        }
21324                    });
21325                } else {
21326                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21327                            + ", but debugging not enabled");
21328                }
21329            }
21330        }
21331    }
21332
21333    /**
21334     * Schedule PSS collection of a process.
21335     */
21336    void requestPssLocked(ProcessRecord proc, int procState) {
21337        if (mPendingPssProcesses.contains(proc)) {
21338            return;
21339        }
21340        if (mPendingPssProcesses.size() == 0) {
21341            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21342        }
21343        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21344        proc.pssProcState = procState;
21345        mPendingPssProcesses.add(proc);
21346    }
21347
21348    /**
21349     * Schedule PSS collection of all processes.
21350     */
21351    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21352        if (!always) {
21353            if (now < (mLastFullPssTime +
21354                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21355                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
21356                return;
21357            }
21358        }
21359        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21360        mLastFullPssTime = now;
21361        mFullPssPending = true;
21362        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21363        mPendingPssProcesses.clear();
21364        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21365            ProcessRecord app = mLruProcesses.get(i);
21366            if (app.thread == null
21367                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21368                continue;
21369            }
21370            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21371                app.pssProcState = app.setProcState;
21372                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21373                        mTestPssMode, isSleepingLocked(), now);
21374                mPendingPssProcesses.add(app);
21375            }
21376        }
21377        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21378    }
21379
21380    public void setTestPssMode(boolean enabled) {
21381        synchronized (this) {
21382            mTestPssMode = enabled;
21383            if (enabled) {
21384                // Whenever we enable the mode, we want to take a snapshot all of current
21385                // process mem use.
21386                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21387            }
21388        }
21389    }
21390
21391    /**
21392     * Ask a given process to GC right now.
21393     */
21394    final void performAppGcLocked(ProcessRecord app) {
21395        try {
21396            app.lastRequestedGc = SystemClock.uptimeMillis();
21397            if (app.thread != null) {
21398                if (app.reportLowMemory) {
21399                    app.reportLowMemory = false;
21400                    app.thread.scheduleLowMemory();
21401                } else {
21402                    app.thread.processInBackground();
21403                }
21404            }
21405        } catch (Exception e) {
21406            // whatever.
21407        }
21408    }
21409
21410    /**
21411     * Returns true if things are idle enough to perform GCs.
21412     */
21413    private final boolean canGcNowLocked() {
21414        boolean processingBroadcasts = false;
21415        for (BroadcastQueue q : mBroadcastQueues) {
21416            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21417                processingBroadcasts = true;
21418            }
21419        }
21420        return !processingBroadcasts
21421                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21422    }
21423
21424    /**
21425     * Perform GCs on all processes that are waiting for it, but only
21426     * if things are idle.
21427     */
21428    final void performAppGcsLocked() {
21429        final int N = mProcessesToGc.size();
21430        if (N <= 0) {
21431            return;
21432        }
21433        if (canGcNowLocked()) {
21434            while (mProcessesToGc.size() > 0) {
21435                ProcessRecord proc = mProcessesToGc.remove(0);
21436                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21437                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21438                            <= SystemClock.uptimeMillis()) {
21439                        // To avoid spamming the system, we will GC processes one
21440                        // at a time, waiting a few seconds between each.
21441                        performAppGcLocked(proc);
21442                        scheduleAppGcsLocked();
21443                        return;
21444                    } else {
21445                        // It hasn't been long enough since we last GCed this
21446                        // process...  put it in the list to wait for its time.
21447                        addProcessToGcListLocked(proc);
21448                        break;
21449                    }
21450                }
21451            }
21452
21453            scheduleAppGcsLocked();
21454        }
21455    }
21456
21457    /**
21458     * If all looks good, perform GCs on all processes waiting for them.
21459     */
21460    final void performAppGcsIfAppropriateLocked() {
21461        if (canGcNowLocked()) {
21462            performAppGcsLocked();
21463            return;
21464        }
21465        // Still not idle, wait some more.
21466        scheduleAppGcsLocked();
21467    }
21468
21469    /**
21470     * Schedule the execution of all pending app GCs.
21471     */
21472    final void scheduleAppGcsLocked() {
21473        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21474
21475        if (mProcessesToGc.size() > 0) {
21476            // Schedule a GC for the time to the next process.
21477            ProcessRecord proc = mProcessesToGc.get(0);
21478            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21479
21480            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21481            long now = SystemClock.uptimeMillis();
21482            if (when < (now+mConstants.GC_TIMEOUT)) {
21483                when = now + mConstants.GC_TIMEOUT;
21484            }
21485            mHandler.sendMessageAtTime(msg, when);
21486        }
21487    }
21488
21489    /**
21490     * Add a process to the array of processes waiting to be GCed.  Keeps the
21491     * list in sorted order by the last GC time.  The process can't already be
21492     * on the list.
21493     */
21494    final void addProcessToGcListLocked(ProcessRecord proc) {
21495        boolean added = false;
21496        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21497            if (mProcessesToGc.get(i).lastRequestedGc <
21498                    proc.lastRequestedGc) {
21499                added = true;
21500                mProcessesToGc.add(i+1, proc);
21501                break;
21502            }
21503        }
21504        if (!added) {
21505            mProcessesToGc.add(0, proc);
21506        }
21507    }
21508
21509    /**
21510     * Set up to ask a process to GC itself.  This will either do it
21511     * immediately, or put it on the list of processes to gc the next
21512     * time things are idle.
21513     */
21514    final void scheduleAppGcLocked(ProcessRecord app) {
21515        long now = SystemClock.uptimeMillis();
21516        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21517            return;
21518        }
21519        if (!mProcessesToGc.contains(app)) {
21520            addProcessToGcListLocked(app);
21521            scheduleAppGcsLocked();
21522        }
21523    }
21524
21525    final void checkExcessivePowerUsageLocked(boolean doKills) {
21526        updateCpuStatsNow();
21527
21528        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21529        boolean doWakeKills = doKills;
21530        boolean doCpuKills = doKills;
21531        if (mLastPowerCheckRealtime == 0) {
21532            doWakeKills = false;
21533        }
21534        if (mLastPowerCheckUptime == 0) {
21535            doCpuKills = false;
21536        }
21537        if (stats.isScreenOn()) {
21538            doWakeKills = false;
21539        }
21540        final long curRealtime = SystemClock.elapsedRealtime();
21541        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21542        final long curUptime = SystemClock.uptimeMillis();
21543        final long uptimeSince = curUptime - mLastPowerCheckUptime;
21544        mLastPowerCheckRealtime = curRealtime;
21545        mLastPowerCheckUptime = curUptime;
21546        if (realtimeSince < mConstants.WAKE_LOCK_MIN_CHECK_DURATION) {
21547            doWakeKills = false;
21548        }
21549        if (uptimeSince < mConstants.CPU_MIN_CHECK_DURATION) {
21550            doCpuKills = false;
21551        }
21552        int i = mLruProcesses.size();
21553        while (i > 0) {
21554            i--;
21555            ProcessRecord app = mLruProcesses.get(i);
21556            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21557                long wtime;
21558                synchronized (stats) {
21559                    wtime = stats.getProcessWakeTime(app.info.uid,
21560                            app.pid, curRealtime);
21561                }
21562                long wtimeUsed = wtime - app.lastWakeTime;
21563                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21564                if (DEBUG_POWER) {
21565                    StringBuilder sb = new StringBuilder(128);
21566                    sb.append("Wake for ");
21567                    app.toShortString(sb);
21568                    sb.append(": over ");
21569                    TimeUtils.formatDuration(realtimeSince, sb);
21570                    sb.append(" used ");
21571                    TimeUtils.formatDuration(wtimeUsed, sb);
21572                    sb.append(" (");
21573                    sb.append((wtimeUsed*100)/realtimeSince);
21574                    sb.append("%)");
21575                    Slog.i(TAG_POWER, sb.toString());
21576                    sb.setLength(0);
21577                    sb.append("CPU for ");
21578                    app.toShortString(sb);
21579                    sb.append(": over ");
21580                    TimeUtils.formatDuration(uptimeSince, sb);
21581                    sb.append(" used ");
21582                    TimeUtils.formatDuration(cputimeUsed, sb);
21583                    sb.append(" (");
21584                    sb.append((cputimeUsed*100)/uptimeSince);
21585                    sb.append("%)");
21586                    Slog.i(TAG_POWER, sb.toString());
21587                }
21588                // If a process has held a wake lock for more
21589                // than 50% of the time during this period,
21590                // that sounds bad.  Kill!
21591                if (doWakeKills && realtimeSince > 0
21592                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
21593                    synchronized (stats) {
21594                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21595                                realtimeSince, wtimeUsed);
21596                    }
21597                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21598                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21599                } else if (doCpuKills && uptimeSince > 0
21600                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
21601                    synchronized (stats) {
21602                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21603                                uptimeSince, cputimeUsed);
21604                    }
21605                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21606                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21607                } else {
21608                    app.lastWakeTime = wtime;
21609                    app.lastCpuTime = app.curCpuTime;
21610                }
21611            }
21612        }
21613    }
21614
21615    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21616            long nowElapsed) {
21617        boolean success = true;
21618
21619        if (app.curRawAdj != app.setRawAdj) {
21620            app.setRawAdj = app.curRawAdj;
21621        }
21622
21623        int changes = 0;
21624
21625        if (app.curAdj != app.setAdj) {
21626            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21627            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21628                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21629                    + app.adjType);
21630            app.setAdj = app.curAdj;
21631            app.verifiedAdj = ProcessList.INVALID_ADJ;
21632        }
21633
21634        if (app.setSchedGroup != app.curSchedGroup) {
21635            int oldSchedGroup = app.setSchedGroup;
21636            app.setSchedGroup = app.curSchedGroup;
21637            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21638                    "Setting sched group of " + app.processName
21639                    + " to " + app.curSchedGroup);
21640            if (app.waitingToKill != null && app.curReceivers.isEmpty()
21641                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21642                app.kill(app.waitingToKill, true);
21643                success = false;
21644            } else {
21645                int processGroup;
21646                switch (app.curSchedGroup) {
21647                    case ProcessList.SCHED_GROUP_BACKGROUND:
21648                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
21649                        break;
21650                    case ProcessList.SCHED_GROUP_TOP_APP:
21651                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21652                        processGroup = THREAD_GROUP_TOP_APP;
21653                        break;
21654                    default:
21655                        processGroup = THREAD_GROUP_DEFAULT;
21656                        break;
21657                }
21658                long oldId = Binder.clearCallingIdentity();
21659                try {
21660                    setProcessGroup(app.pid, processGroup);
21661                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21662                        // do nothing if we already switched to RT
21663                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21664                            mVrController.onTopProcChangedLocked(app);
21665                            if (mUseFifoUiScheduling) {
21666                                // Switch UI pipeline for app to SCHED_FIFO
21667                                app.savedPriority = Process.getThreadPriority(app.pid);
21668                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
21669                                if (app.renderThreadTid != 0) {
21670                                    scheduleAsFifoPriority(app.renderThreadTid,
21671                                        /* suppressLogs */true);
21672                                    if (DEBUG_OOM_ADJ) {
21673                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
21674                                            app.renderThreadTid + ") to FIFO");
21675                                    }
21676                                } else {
21677                                    if (DEBUG_OOM_ADJ) {
21678                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
21679                                    }
21680                                }
21681                            } else {
21682                                // Boost priority for top app UI and render threads
21683                                setThreadPriority(app.pid, -10);
21684                                if (app.renderThreadTid != 0) {
21685                                    try {
21686                                        setThreadPriority(app.renderThreadTid, -10);
21687                                    } catch (IllegalArgumentException e) {
21688                                        // thread died, ignore
21689                                    }
21690                                }
21691                            }
21692                        }
21693                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
21694                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21695                        mVrController.onTopProcChangedLocked(app);
21696                        if (mUseFifoUiScheduling) {
21697                            // Reset UI pipeline to SCHED_OTHER
21698                            setThreadScheduler(app.pid, SCHED_OTHER, 0);
21699                            setThreadPriority(app.pid, app.savedPriority);
21700                            if (app.renderThreadTid != 0) {
21701                                setThreadScheduler(app.renderThreadTid,
21702                                    SCHED_OTHER, 0);
21703                                setThreadPriority(app.renderThreadTid, -4);
21704                            }
21705                        } else {
21706                            // Reset priority for top app UI and render threads
21707                            setThreadPriority(app.pid, 0);
21708                            if (app.renderThreadTid != 0) {
21709                                setThreadPriority(app.renderThreadTid, 0);
21710                            }
21711                        }
21712                    }
21713                } catch (Exception e) {
21714                    if (false) {
21715                        Slog.w(TAG, "Failed setting process group of " + app.pid
21716                                + " to " + app.curSchedGroup);
21717                        Slog.w(TAG, "at location", e);
21718                    }
21719                } finally {
21720                    Binder.restoreCallingIdentity(oldId);
21721                }
21722            }
21723        }
21724        if (app.repForegroundActivities != app.foregroundActivities) {
21725            app.repForegroundActivities = app.foregroundActivities;
21726            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
21727        }
21728        if (app.repProcState != app.curProcState) {
21729            app.repProcState = app.curProcState;
21730            if (app.thread != null) {
21731                try {
21732                    if (false) {
21733                        //RuntimeException h = new RuntimeException("here");
21734                        Slog.i(TAG, "Sending new process state " + app.repProcState
21735                                + " to " + app /*, h*/);
21736                    }
21737                    app.thread.setProcessState(app.repProcState);
21738                } catch (RemoteException e) {
21739                }
21740            }
21741        }
21742        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
21743                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
21744            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
21745                // Experimental code to more aggressively collect pss while
21746                // running test...  the problem is that this tends to collect
21747                // the data right when a process is transitioning between process
21748                // states, which well tend to give noisy data.
21749                long start = SystemClock.uptimeMillis();
21750                long pss = Debug.getPss(app.pid, mTmpLong, null);
21751                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
21752                mPendingPssProcesses.remove(app);
21753                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
21754                        + " to " + app.curProcState + ": "
21755                        + (SystemClock.uptimeMillis()-start) + "ms");
21756            }
21757            app.lastStateTime = now;
21758            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21759                    mTestPssMode, isSleepingLocked(), now);
21760            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
21761                    + ProcessList.makeProcStateString(app.setProcState) + " to "
21762                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
21763                    + (app.nextPssTime-now) + ": " + app);
21764        } else {
21765            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
21766                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
21767                    mTestPssMode)))) {
21768                requestPssLocked(app, app.setProcState);
21769                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
21770                        mTestPssMode, isSleepingLocked(), now);
21771            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
21772                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
21773        }
21774        if (app.setProcState != app.curProcState) {
21775            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21776                    "Proc state change of " + app.processName
21777                            + " to " + app.curProcState);
21778            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
21779            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
21780            if (setImportant && !curImportant) {
21781                // This app is no longer something we consider important enough to allow to
21782                // use arbitrary amounts of battery power.  Note
21783                // its current wake lock time to later know to kill it if
21784                // it is not behaving well.
21785                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21786                synchronized (stats) {
21787                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
21788                            app.pid, nowElapsed);
21789                }
21790                app.lastCpuTime = app.curCpuTime;
21791
21792            }
21793            // Inform UsageStats of important process state change
21794            // Must be called before updating setProcState
21795            maybeUpdateUsageStatsLocked(app, nowElapsed);
21796
21797            app.setProcState = app.curProcState;
21798            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21799                app.notCachedSinceIdle = false;
21800            }
21801            if (!doingAll) {
21802                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
21803            } else {
21804                app.procStateChanged = true;
21805            }
21806        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
21807                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
21808            // For apps that sit around for a long time in the interactive state, we need
21809            // to report this at least once a day so they don't go idle.
21810            maybeUpdateUsageStatsLocked(app, nowElapsed);
21811        }
21812
21813        if (changes != 0) {
21814            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21815                    "Changes in " + app + ": " + changes);
21816            int i = mPendingProcessChanges.size()-1;
21817            ProcessChangeItem item = null;
21818            while (i >= 0) {
21819                item = mPendingProcessChanges.get(i);
21820                if (item.pid == app.pid) {
21821                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21822                            "Re-using existing item: " + item);
21823                    break;
21824                }
21825                i--;
21826            }
21827            if (i < 0) {
21828                // No existing item in pending changes; need a new one.
21829                final int NA = mAvailProcessChanges.size();
21830                if (NA > 0) {
21831                    item = mAvailProcessChanges.remove(NA-1);
21832                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21833                            "Retrieving available item: " + item);
21834                } else {
21835                    item = new ProcessChangeItem();
21836                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21837                            "Allocating new item: " + item);
21838                }
21839                item.changes = 0;
21840                item.pid = app.pid;
21841                item.uid = app.info.uid;
21842                if (mPendingProcessChanges.size() == 0) {
21843                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21844                            "*** Enqueueing dispatch processes changed!");
21845                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
21846                }
21847                mPendingProcessChanges.add(item);
21848            }
21849            item.changes |= changes;
21850            item.foregroundActivities = app.repForegroundActivities;
21851            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21852                    "Item " + Integer.toHexString(System.identityHashCode(item))
21853                    + " " + app.toShortString() + ": changes=" + item.changes
21854                    + " foreground=" + item.foregroundActivities
21855                    + " type=" + app.adjType + " source=" + app.adjSource
21856                    + " target=" + app.adjTarget);
21857        }
21858
21859        return success;
21860    }
21861
21862    private boolean isEphemeralLocked(int uid) {
21863        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
21864        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
21865            return false;
21866        }
21867        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
21868                packages[0]);
21869    }
21870
21871    @VisibleForTesting
21872    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
21873        final UidRecord.ChangeItem pendingChange;
21874        if (uidRec == null || uidRec.pendingChange == null) {
21875            if (mPendingUidChanges.size() == 0) {
21876                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21877                        "*** Enqueueing dispatch uid changed!");
21878                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
21879            }
21880            final int NA = mAvailUidChanges.size();
21881            if (NA > 0) {
21882                pendingChange = mAvailUidChanges.remove(NA-1);
21883                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21884                        "Retrieving available item: " + pendingChange);
21885            } else {
21886                pendingChange = new UidRecord.ChangeItem();
21887                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21888                        "Allocating new item: " + pendingChange);
21889            }
21890            if (uidRec != null) {
21891                uidRec.pendingChange = pendingChange;
21892                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
21893                    // If this uid is going away, and we haven't yet reported it is gone,
21894                    // then do so now.
21895                    change = UidRecord.CHANGE_GONE_IDLE;
21896                }
21897            } else if (uid < 0) {
21898                throw new IllegalArgumentException("No UidRecord or uid");
21899            }
21900            pendingChange.uidRecord = uidRec;
21901            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
21902            mPendingUidChanges.add(pendingChange);
21903        } else {
21904            pendingChange = uidRec.pendingChange;
21905            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
21906                change = UidRecord.CHANGE_GONE_IDLE;
21907            }
21908        }
21909        pendingChange.change = change;
21910        pendingChange.processState = uidRec != null
21911                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
21912        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
21913        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
21914        if (uidRec != null) {
21915            uidRec.updateLastDispatchedProcStateSeq(change);
21916        }
21917
21918        // Directly update the power manager, since we sit on top of it and it is critical
21919        // it be kept in sync (so wake locks will be held as soon as appropriate).
21920        if (mLocalPowerManager != null) {
21921            switch (change) {
21922                case UidRecord.CHANGE_GONE:
21923                case UidRecord.CHANGE_GONE_IDLE:
21924                    mLocalPowerManager.uidGone(pendingChange.uid);
21925                    break;
21926                case UidRecord.CHANGE_IDLE:
21927                    mLocalPowerManager.uidIdle(pendingChange.uid);
21928                    break;
21929                case UidRecord.CHANGE_ACTIVE:
21930                    mLocalPowerManager.uidActive(pendingChange.uid);
21931                    break;
21932                default:
21933                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
21934                            pendingChange.processState);
21935                    break;
21936            }
21937        }
21938    }
21939
21940    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
21941            String authority) {
21942        if (app == null) return;
21943        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21944            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
21945            if (userState == null) return;
21946            final long now = SystemClock.elapsedRealtime();
21947            Long lastReported = userState.mProviderLastReportedFg.get(authority);
21948            if (lastReported == null || lastReported < now - 60 * 1000L) {
21949                if (mSystemReady) {
21950                    // Cannot touch the user stats if not system ready
21951                    mUsageStatsService.reportContentProviderUsage(
21952                            authority, providerPkgName, app.userId);
21953                }
21954                userState.mProviderLastReportedFg.put(authority, now);
21955            }
21956        }
21957    }
21958
21959    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
21960        if (DEBUG_USAGE_STATS) {
21961            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
21962                    + "] state changes: old = " + app.setProcState + ", new = "
21963                    + app.curProcState);
21964        }
21965        if (mUsageStatsService == null) {
21966            return;
21967        }
21968        boolean isInteraction;
21969        // To avoid some abuse patterns, we are going to be careful about what we consider
21970        // to be an app interaction.  Being the top activity doesn't count while the display
21971        // is sleeping, nor do short foreground services.
21972        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
21973            isInteraction = true;
21974            app.fgInteractionTime = 0;
21975        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
21976            if (app.fgInteractionTime == 0) {
21977                app.fgInteractionTime = nowElapsed;
21978                isInteraction = false;
21979            } else {
21980                isInteraction = nowElapsed > app.fgInteractionTime
21981                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
21982            }
21983        } else {
21984            // If the app was being forced to the foreground, by say a Toast, then
21985            // no need to treat it as an interaction
21986            isInteraction = app.forcingToForeground == null
21987                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21988            app.fgInteractionTime = 0;
21989        }
21990        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
21991                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
21992            app.interactionEventTime = nowElapsed;
21993            String[] packages = app.getPackageList();
21994            if (packages != null) {
21995                for (int i = 0; i < packages.length; i++) {
21996                    mUsageStatsService.reportEvent(packages[i], app.userId,
21997                            UsageEvents.Event.SYSTEM_INTERACTION);
21998                }
21999            }
22000        }
22001        app.reportedInteraction = isInteraction;
22002        if (!isInteraction) {
22003            app.interactionEventTime = 0;
22004        }
22005    }
22006
22007    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22008        if (proc.thread != null) {
22009            if (proc.baseProcessTracker != null) {
22010                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22011            }
22012        }
22013    }
22014
22015    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22016            ProcessRecord TOP_APP, boolean doingAll, long now) {
22017        if (app.thread == null) {
22018            return false;
22019        }
22020
22021        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22022
22023        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22024    }
22025
22026    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22027            boolean oomAdj) {
22028        if (isForeground != proc.foregroundServices) {
22029            proc.foregroundServices = isForeground;
22030            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22031                    proc.info.uid);
22032            if (isForeground) {
22033                if (curProcs == null) {
22034                    curProcs = new ArrayList<ProcessRecord>();
22035                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22036                }
22037                if (!curProcs.contains(proc)) {
22038                    curProcs.add(proc);
22039                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22040                            proc.info.packageName, proc.info.uid);
22041                }
22042            } else {
22043                if (curProcs != null) {
22044                    if (curProcs.remove(proc)) {
22045                        mBatteryStatsService.noteEvent(
22046                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22047                                proc.info.packageName, proc.info.uid);
22048                        if (curProcs.size() <= 0) {
22049                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22050                        }
22051                    }
22052                }
22053            }
22054            if (oomAdj) {
22055                updateOomAdjLocked();
22056            }
22057        }
22058    }
22059
22060    private final ActivityRecord resumedAppLocked() {
22061        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22062        String pkg;
22063        int uid;
22064        if (act != null) {
22065            pkg = act.packageName;
22066            uid = act.info.applicationInfo.uid;
22067        } else {
22068            pkg = null;
22069            uid = -1;
22070        }
22071        // Has the UID or resumed package name changed?
22072        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22073                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22074            if (mCurResumedPackage != null) {
22075                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22076                        mCurResumedPackage, mCurResumedUid);
22077            }
22078            mCurResumedPackage = pkg;
22079            mCurResumedUid = uid;
22080            if (mCurResumedPackage != null) {
22081                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22082                        mCurResumedPackage, mCurResumedUid);
22083            }
22084        }
22085        return act;
22086    }
22087
22088    final boolean updateOomAdjLocked(ProcessRecord app) {
22089        final ActivityRecord TOP_ACT = resumedAppLocked();
22090        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22091        final boolean wasCached = app.cached;
22092
22093        mAdjSeq++;
22094
22095        // This is the desired cached adjusment we want to tell it to use.
22096        // If our app is currently cached, we know it, and that is it.  Otherwise,
22097        // we don't know it yet, and it needs to now be cached we will then
22098        // need to do a complete oom adj.
22099        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22100                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22101        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22102                SystemClock.uptimeMillis());
22103        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
22104            // Changed to/from cached state, so apps after it in the LRU
22105            // list may also be changed.
22106            updateOomAdjLocked();
22107        }
22108        return success;
22109    }
22110
22111    final void updateOomAdjLocked() {
22112        final ActivityRecord TOP_ACT = resumedAppLocked();
22113        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22114        final long now = SystemClock.uptimeMillis();
22115        final long nowElapsed = SystemClock.elapsedRealtime();
22116        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22117        final int N = mLruProcesses.size();
22118
22119        if (false) {
22120            RuntimeException e = new RuntimeException();
22121            e.fillInStackTrace();
22122            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22123        }
22124
22125        // Reset state in all uid records.
22126        for (int i=mActiveUids.size()-1; i>=0; i--) {
22127            final UidRecord uidRec = mActiveUids.valueAt(i);
22128            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22129                    "Starting update of " + uidRec);
22130            uidRec.reset();
22131        }
22132
22133        mStackSupervisor.rankTaskLayersIfNeeded();
22134
22135        mAdjSeq++;
22136        mNewNumServiceProcs = 0;
22137        mNewNumAServiceProcs = 0;
22138
22139        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22140        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22141
22142        // Let's determine how many processes we have running vs.
22143        // how many slots we have for background processes; we may want
22144        // to put multiple processes in a slot of there are enough of
22145        // them.
22146        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22147                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22148        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22149        if (numEmptyProcs > cachedProcessLimit) {
22150            // If there are more empty processes than our limit on cached
22151            // processes, then use the cached process limit for the factor.
22152            // This ensures that the really old empty processes get pushed
22153            // down to the bottom, so if we are running low on memory we will
22154            // have a better chance at keeping around more cached processes
22155            // instead of a gazillion empty processes.
22156            numEmptyProcs = cachedProcessLimit;
22157        }
22158        int emptyFactor = numEmptyProcs/numSlots;
22159        if (emptyFactor < 1) emptyFactor = 1;
22160        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22161        if (cachedFactor < 1) cachedFactor = 1;
22162        int stepCached = 0;
22163        int stepEmpty = 0;
22164        int numCached = 0;
22165        int numEmpty = 0;
22166        int numTrimming = 0;
22167
22168        mNumNonCachedProcs = 0;
22169        mNumCachedHiddenProcs = 0;
22170
22171        // First update the OOM adjustment for each of the
22172        // application processes based on their current state.
22173        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22174        int nextCachedAdj = curCachedAdj+1;
22175        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22176        int nextEmptyAdj = curEmptyAdj+2;
22177        for (int i=N-1; i>=0; i--) {
22178            ProcessRecord app = mLruProcesses.get(i);
22179            if (!app.killedByAm && app.thread != null) {
22180                app.procStateChanged = false;
22181                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22182
22183                // If we haven't yet assigned the final cached adj
22184                // to the process, do that now.
22185                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22186                    switch (app.curProcState) {
22187                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22188                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22189                            // This process is a cached process holding activities...
22190                            // assign it the next cached value for that type, and then
22191                            // step that cached level.
22192                            app.curRawAdj = curCachedAdj;
22193                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22194                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22195                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22196                                    + ")");
22197                            if (curCachedAdj != nextCachedAdj) {
22198                                stepCached++;
22199                                if (stepCached >= cachedFactor) {
22200                                    stepCached = 0;
22201                                    curCachedAdj = nextCachedAdj;
22202                                    nextCachedAdj += 2;
22203                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22204                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22205                                    }
22206                                }
22207                            }
22208                            break;
22209                        default:
22210                            // For everything else, assign next empty cached process
22211                            // level and bump that up.  Note that this means that
22212                            // long-running services that have dropped down to the
22213                            // cached level will be treated as empty (since their process
22214                            // state is still as a service), which is what we want.
22215                            app.curRawAdj = curEmptyAdj;
22216                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22217                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22218                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22219                                    + ")");
22220                            if (curEmptyAdj != nextEmptyAdj) {
22221                                stepEmpty++;
22222                                if (stepEmpty >= emptyFactor) {
22223                                    stepEmpty = 0;
22224                                    curEmptyAdj = nextEmptyAdj;
22225                                    nextEmptyAdj += 2;
22226                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22227                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22228                                    }
22229                                }
22230                            }
22231                            break;
22232                    }
22233                }
22234
22235                applyOomAdjLocked(app, true, now, nowElapsed);
22236
22237                // Count the number of process types.
22238                switch (app.curProcState) {
22239                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22240                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22241                        mNumCachedHiddenProcs++;
22242                        numCached++;
22243                        if (numCached > cachedProcessLimit) {
22244                            app.kill("cached #" + numCached, true);
22245                        }
22246                        break;
22247                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22248                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22249                                && app.lastActivityTime < oldTime) {
22250                            app.kill("empty for "
22251                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22252                                    / 1000) + "s", true);
22253                        } else {
22254                            numEmpty++;
22255                            if (numEmpty > emptyProcessLimit) {
22256                                app.kill("empty #" + numEmpty, true);
22257                            }
22258                        }
22259                        break;
22260                    default:
22261                        mNumNonCachedProcs++;
22262                        break;
22263                }
22264
22265                if (app.isolated && app.services.size() <= 0) {
22266                    // If this is an isolated process, and there are no
22267                    // services running in it, then the process is no longer
22268                    // needed.  We agressively kill these because we can by
22269                    // definition not re-use the same process again, and it is
22270                    // good to avoid having whatever code was running in them
22271                    // left sitting around after no longer needed.
22272                    app.kill("isolated not needed", true);
22273                } else {
22274                    // Keeping this process, update its uid.
22275                    final UidRecord uidRec = app.uidRecord;
22276                    if (uidRec != null) {
22277                        uidRec.ephemeral = app.info.isInstantApp();
22278                        if (uidRec.curProcState > app.curProcState) {
22279                            uidRec.curProcState = app.curProcState;
22280                        }
22281                    }
22282                }
22283
22284                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22285                        && !app.killedByAm) {
22286                    numTrimming++;
22287                }
22288            }
22289        }
22290
22291        incrementProcStateSeqAndNotifyAppsLocked();
22292
22293        mNumServiceProcs = mNewNumServiceProcs;
22294
22295        // Now determine the memory trimming level of background processes.
22296        // Unfortunately we need to start at the back of the list to do this
22297        // properly.  We only do this if the number of background apps we
22298        // are managing to keep around is less than half the maximum we desire;
22299        // if we are keeping a good number around, we'll let them use whatever
22300        // memory they want.
22301        final int numCachedAndEmpty = numCached + numEmpty;
22302        int memFactor;
22303        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22304                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22305            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22306                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22307            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22308                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22309            } else {
22310                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22311            }
22312        } else {
22313            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22314        }
22315        // We always allow the memory level to go up (better).  We only allow it to go
22316        // down if we are in a state where that is allowed, *and* the total number of processes
22317        // has gone down since last time.
22318        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22319                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22320                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22321        if (memFactor > mLastMemoryLevel) {
22322            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22323                memFactor = mLastMemoryLevel;
22324                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22325            }
22326        }
22327        if (memFactor != mLastMemoryLevel) {
22328            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22329        }
22330        mLastMemoryLevel = memFactor;
22331        mLastNumProcesses = mLruProcesses.size();
22332        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22333        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22334        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22335            if (mLowRamStartTime == 0) {
22336                mLowRamStartTime = now;
22337            }
22338            int step = 0;
22339            int fgTrimLevel;
22340            switch (memFactor) {
22341                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22342                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22343                    break;
22344                case ProcessStats.ADJ_MEM_FACTOR_LOW:
22345                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22346                    break;
22347                default:
22348                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22349                    break;
22350            }
22351            int factor = numTrimming/3;
22352            int minFactor = 2;
22353            if (mHomeProcess != null) minFactor++;
22354            if (mPreviousProcess != null) minFactor++;
22355            if (factor < minFactor) factor = minFactor;
22356            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22357            for (int i=N-1; i>=0; i--) {
22358                ProcessRecord app = mLruProcesses.get(i);
22359                if (allChanged || app.procStateChanged) {
22360                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22361                    app.procStateChanged = false;
22362                }
22363                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22364                        && !app.killedByAm) {
22365                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
22366                        try {
22367                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22368                                    "Trimming memory of " + app.processName + " to " + curLevel);
22369                            app.thread.scheduleTrimMemory(curLevel);
22370                        } catch (RemoteException e) {
22371                        }
22372                        if (false) {
22373                            // For now we won't do this; our memory trimming seems
22374                            // to be good enough at this point that destroying
22375                            // activities causes more harm than good.
22376                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22377                                    && app != mHomeProcess && app != mPreviousProcess) {
22378                                // Need to do this on its own message because the stack may not
22379                                // be in a consistent state at this point.
22380                                // For these apps we will also finish their activities
22381                                // to help them free memory.
22382                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22383                            }
22384                        }
22385                    }
22386                    app.trimMemoryLevel = curLevel;
22387                    step++;
22388                    if (step >= factor) {
22389                        step = 0;
22390                        switch (curLevel) {
22391                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22392                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22393                                break;
22394                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22395                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22396                                break;
22397                        }
22398                    }
22399                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22400                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22401                            && app.thread != null) {
22402                        try {
22403                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22404                                    "Trimming memory of heavy-weight " + app.processName
22405                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22406                            app.thread.scheduleTrimMemory(
22407                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22408                        } catch (RemoteException e) {
22409                        }
22410                    }
22411                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22412                } else {
22413                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22414                            || app.systemNoUi) && app.pendingUiClean) {
22415                        // If this application is now in the background and it
22416                        // had done UI, then give it the special trim level to
22417                        // have it free UI resources.
22418                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22419                        if (app.trimMemoryLevel < level && app.thread != null) {
22420                            try {
22421                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22422                                        "Trimming memory of bg-ui " + app.processName
22423                                        + " to " + level);
22424                                app.thread.scheduleTrimMemory(level);
22425                            } catch (RemoteException e) {
22426                            }
22427                        }
22428                        app.pendingUiClean = false;
22429                    }
22430                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22431                        try {
22432                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22433                                    "Trimming memory of fg " + app.processName
22434                                    + " to " + fgTrimLevel);
22435                            app.thread.scheduleTrimMemory(fgTrimLevel);
22436                        } catch (RemoteException e) {
22437                        }
22438                    }
22439                    app.trimMemoryLevel = fgTrimLevel;
22440                }
22441            }
22442        } else {
22443            if (mLowRamStartTime != 0) {
22444                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22445                mLowRamStartTime = 0;
22446            }
22447            for (int i=N-1; i>=0; i--) {
22448                ProcessRecord app = mLruProcesses.get(i);
22449                if (allChanged || app.procStateChanged) {
22450                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22451                    app.procStateChanged = false;
22452                }
22453                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22454                        || app.systemNoUi) && app.pendingUiClean) {
22455                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22456                            && app.thread != null) {
22457                        try {
22458                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22459                                    "Trimming memory of ui hidden " + app.processName
22460                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22461                            app.thread.scheduleTrimMemory(
22462                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22463                        } catch (RemoteException e) {
22464                        }
22465                    }
22466                    app.pendingUiClean = false;
22467                }
22468                app.trimMemoryLevel = 0;
22469            }
22470        }
22471
22472        if (mAlwaysFinishActivities) {
22473            // Need to do this on its own message because the stack may not
22474            // be in a consistent state at this point.
22475            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22476        }
22477
22478        if (allChanged) {
22479            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22480        }
22481
22482        // Update from any uid changes.
22483        if (mLocalPowerManager != null) {
22484            mLocalPowerManager.startUidChanges();
22485        }
22486        for (int i=mActiveUids.size()-1; i>=0; i--) {
22487            final UidRecord uidRec = mActiveUids.valueAt(i);
22488            int uidChange = UidRecord.CHANGE_PROCSTATE;
22489            if (uidRec.setProcState != uidRec.curProcState
22490                    || uidRec.setWhitelist != uidRec.curWhitelist) {
22491                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22492                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22493                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22494                        + " to " + uidRec.curWhitelist);
22495                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22496                        && !uidRec.curWhitelist) {
22497                    // UID is now in the background (and not on the temp whitelist).  Was it
22498                    // previously in the foreground (or on the temp whitelist)?
22499                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22500                            || uidRec.setWhitelist) {
22501                        uidRec.lastBackgroundTime = nowElapsed;
22502                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22503                            // Note: the background settle time is in elapsed realtime, while
22504                            // the handler time base is uptime.  All this means is that we may
22505                            // stop background uids later than we had intended, but that only
22506                            // happens because the device was sleeping so we are okay anyway.
22507                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22508                                    mConstants.BACKGROUND_SETTLE_TIME);
22509                        }
22510                    }
22511                } else {
22512                    if (uidRec.idle) {
22513                        uidChange = UidRecord.CHANGE_ACTIVE;
22514                        uidRec.idle = false;
22515                    }
22516                    uidRec.lastBackgroundTime = 0;
22517                }
22518                uidRec.setProcState = uidRec.curProcState;
22519                uidRec.setWhitelist = uidRec.curWhitelist;
22520                enqueueUidChangeLocked(uidRec, -1, uidChange);
22521                noteUidProcessState(uidRec.uid, uidRec.curProcState);
22522            }
22523        }
22524        if (mLocalPowerManager != null) {
22525            mLocalPowerManager.finishUidChanges();
22526        }
22527
22528        if (mProcessStats.shouldWriteNowLocked(now)) {
22529            mHandler.post(new Runnable() {
22530                @Override public void run() {
22531                    synchronized (ActivityManagerService.this) {
22532                        mProcessStats.writeStateAsyncLocked();
22533                    }
22534                }
22535            });
22536        }
22537
22538        if (DEBUG_OOM_ADJ) {
22539            final long duration = SystemClock.uptimeMillis() - now;
22540            if (false) {
22541                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22542                        new RuntimeException("here").fillInStackTrace());
22543            } else {
22544                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22545            }
22546        }
22547    }
22548
22549    @Override
22550    public void makePackageIdle(String packageName, int userId) {
22551        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22552                != PackageManager.PERMISSION_GRANTED) {
22553            String msg = "Permission Denial: makePackageIdle() from pid="
22554                    + Binder.getCallingPid()
22555                    + ", uid=" + Binder.getCallingUid()
22556                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22557            Slog.w(TAG, msg);
22558            throw new SecurityException(msg);
22559        }
22560        final int callingPid = Binder.getCallingPid();
22561        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22562                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22563        long callingId = Binder.clearCallingIdentity();
22564        synchronized(this) {
22565            try {
22566                IPackageManager pm = AppGlobals.getPackageManager();
22567                int pkgUid = -1;
22568                try {
22569                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22570                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22571                } catch (RemoteException e) {
22572                }
22573                if (pkgUid == -1) {
22574                    throw new IllegalArgumentException("Unknown package name " + packageName);
22575                }
22576
22577                if (mLocalPowerManager != null) {
22578                    mLocalPowerManager.startUidChanges();
22579                }
22580                final int appId = UserHandle.getAppId(pkgUid);
22581                final int N = mActiveUids.size();
22582                for (int i=N-1; i>=0; i--) {
22583                    final UidRecord uidRec = mActiveUids.valueAt(i);
22584                    final long bgTime = uidRec.lastBackgroundTime;
22585                    if (bgTime > 0 && !uidRec.idle) {
22586                        if (UserHandle.getAppId(uidRec.uid) == appId) {
22587                            if (userId == UserHandle.USER_ALL ||
22588                                    userId == UserHandle.getUserId(uidRec.uid)) {
22589                                uidRec.idle = true;
22590                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22591                                        + " from package " + packageName + " user " + userId);
22592                                doStopUidLocked(uidRec.uid, uidRec);
22593                            }
22594                        }
22595                    }
22596                }
22597            } finally {
22598                if (mLocalPowerManager != null) {
22599                    mLocalPowerManager.finishUidChanges();
22600                }
22601                Binder.restoreCallingIdentity(callingId);
22602            }
22603        }
22604    }
22605
22606    final void idleUids() {
22607        synchronized (this) {
22608            final int N = mActiveUids.size();
22609            if (N <= 0) {
22610                return;
22611            }
22612            final long nowElapsed = SystemClock.elapsedRealtime();
22613            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
22614            long nextTime = 0;
22615            if (mLocalPowerManager != null) {
22616                mLocalPowerManager.startUidChanges();
22617            }
22618            for (int i=N-1; i>=0; i--) {
22619                final UidRecord uidRec = mActiveUids.valueAt(i);
22620                final long bgTime = uidRec.lastBackgroundTime;
22621                if (bgTime > 0 && !uidRec.idle) {
22622                    if (bgTime <= maxBgTime) {
22623                        uidRec.idle = true;
22624                        doStopUidLocked(uidRec.uid, uidRec);
22625                    } else {
22626                        if (nextTime == 0 || nextTime > bgTime) {
22627                            nextTime = bgTime;
22628                        }
22629                    }
22630                }
22631            }
22632            if (mLocalPowerManager != null) {
22633                mLocalPowerManager.finishUidChanges();
22634            }
22635            if (nextTime > 0) {
22636                mHandler.removeMessages(IDLE_UIDS_MSG);
22637                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22638                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
22639            }
22640        }
22641    }
22642
22643    /**
22644     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
22645     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
22646     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
22647     */
22648    @VisibleForTesting
22649    @GuardedBy("this")
22650    void incrementProcStateSeqAndNotifyAppsLocked() {
22651        if (mWaitForNetworkTimeoutMs <= 0) {
22652            return;
22653        }
22654        // Used for identifying which uids need to block for network.
22655        ArrayList<Integer> blockingUids = null;
22656        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
22657            final UidRecord uidRec = mActiveUids.valueAt(i);
22658            // If the network is not restricted for uid, then nothing to do here.
22659            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
22660                continue;
22661            }
22662            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
22663                continue;
22664            }
22665            // If process state is not changed, then there's nothing to do.
22666            if (uidRec.setProcState == uidRec.curProcState) {
22667                continue;
22668            }
22669            final int blockState = getBlockStateForUid(uidRec);
22670            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
22671            // there's nothing the app needs to do in this scenario.
22672            if (blockState == NETWORK_STATE_NO_CHANGE) {
22673                continue;
22674            }
22675            synchronized (uidRec.networkStateLock) {
22676                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
22677                if (blockState == NETWORK_STATE_BLOCK) {
22678                    if (blockingUids == null) {
22679                        blockingUids = new ArrayList<>();
22680                    }
22681                    blockingUids.add(uidRec.uid);
22682                } else {
22683                    if (DEBUG_NETWORK) {
22684                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
22685                                + " threads for uid: " + uidRec);
22686                    }
22687                    if (uidRec.waitingForNetwork) {
22688                        uidRec.networkStateLock.notifyAll();
22689                    }
22690                }
22691            }
22692        }
22693
22694        // There are no uids that need to block, so nothing more to do.
22695        if (blockingUids == null) {
22696            return;
22697        }
22698
22699        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
22700            final ProcessRecord app = mLruProcesses.get(i);
22701            if (!blockingUids.contains(app.uid)) {
22702                continue;
22703            }
22704            if (!app.killedByAm && app.thread != null) {
22705                final UidRecord uidRec = mActiveUids.get(app.uid);
22706                try {
22707                    if (DEBUG_NETWORK) {
22708                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
22709                                + uidRec);
22710                    }
22711                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
22712                } catch (RemoteException ignored) {
22713                }
22714            }
22715        }
22716    }
22717
22718    /**
22719     * Checks if the uid is coming from background to foreground or vice versa and returns
22720     * appropriate block state based on this.
22721     *
22722     * @return blockState based on whether the uid is coming from background to foreground or
22723     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
22724     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
22725     *         {@link #NETWORK_STATE_NO_CHANGE}.
22726     */
22727    @VisibleForTesting
22728    int getBlockStateForUid(UidRecord uidRec) {
22729        // Denotes whether uid's process state is currently allowed network access.
22730        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
22731                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
22732        // Denotes whether uid's process state was previously allowed network access.
22733        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
22734                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
22735
22736        // When the uid is coming to foreground, AMS should inform the app thread that it should
22737        // block for the network rules to get updated before launching an activity.
22738        if (!wasAllowed && isAllowed) {
22739            return NETWORK_STATE_BLOCK;
22740        }
22741        // When the uid is going to background, AMS should inform the app thread that if an
22742        // activity launch is blocked for the network rules to get updated, it should be unblocked.
22743        if (wasAllowed && !isAllowed) {
22744            return NETWORK_STATE_UNBLOCK;
22745        }
22746        return NETWORK_STATE_NO_CHANGE;
22747    }
22748
22749    final void runInBackgroundDisabled(int uid) {
22750        synchronized (this) {
22751            UidRecord uidRec = mActiveUids.get(uid);
22752            if (uidRec != null) {
22753                // This uid is actually running...  should it be considered background now?
22754                if (uidRec.idle) {
22755                    doStopUidLocked(uidRec.uid, uidRec);
22756                }
22757            } else {
22758                // This uid isn't actually running...  still send a report about it being "stopped".
22759                doStopUidLocked(uid, null);
22760            }
22761        }
22762    }
22763
22764    final void doStopUidLocked(int uid, final UidRecord uidRec) {
22765        mServices.stopInBackgroundLocked(uid);
22766        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
22767    }
22768
22769    /**
22770     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
22771     */
22772    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
22773            long duration, String tag) {
22774        if (DEBUG_WHITELISTS) {
22775            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
22776                    + targetUid + ", " + duration + ")");
22777        }
22778
22779        synchronized (mPidsSelfLocked) {
22780            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
22781            if (pr == null) {
22782                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
22783                        + callerPid);
22784                return;
22785            }
22786            if (!pr.whitelistManager) {
22787                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
22788                        != PackageManager.PERMISSION_GRANTED) {
22789                    if (DEBUG_WHITELISTS) {
22790                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
22791                                + ": pid " + callerPid + " is not allowed");
22792                    }
22793                    return;
22794                }
22795            }
22796        }
22797
22798        tempWhitelistUidLocked(targetUid, duration, tag);
22799    }
22800
22801    /**
22802     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
22803     */
22804    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
22805        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
22806        setUidTempWhitelistStateLocked(targetUid, true);
22807        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
22808    }
22809
22810    void pushTempWhitelist() {
22811        final int N;
22812        final PendingTempWhitelist[] list;
22813
22814        // First copy out the pending changes...  we need to leave them in the map for now,
22815        // in case someone needs to check what is coming up while we don't have the lock held.
22816        synchronized(this) {
22817            N = mPendingTempWhitelist.size();
22818            list = new PendingTempWhitelist[N];
22819            for (int i = 0; i < N; i++) {
22820                list[i] = mPendingTempWhitelist.valueAt(i);
22821            }
22822        }
22823
22824        // Now safely dispatch changes to device idle controller.
22825        for (int i = 0; i < N; i++) {
22826            PendingTempWhitelist ptw = list[i];
22827            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
22828                    ptw.duration, true, ptw.tag);
22829        }
22830
22831        // And now we can safely remove them from the map.
22832        synchronized(this) {
22833            for (int i = 0; i < N; i++) {
22834                PendingTempWhitelist ptw = list[i];
22835                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
22836                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
22837                    mPendingTempWhitelist.removeAt(index);
22838                }
22839            }
22840        }
22841    }
22842
22843    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
22844        boolean changed = false;
22845        for (int i=mActiveUids.size()-1; i>=0; i--) {
22846            final UidRecord uidRec = mActiveUids.valueAt(i);
22847            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
22848                uidRec.curWhitelist = onWhitelist;
22849                changed = true;
22850            }
22851        }
22852        if (changed) {
22853            updateOomAdjLocked();
22854        }
22855    }
22856
22857    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
22858        boolean changed = false;
22859        final UidRecord uidRec = mActiveUids.get(uid);
22860        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
22861            uidRec.curWhitelist = onWhitelist;
22862            updateOomAdjLocked();
22863        }
22864    }
22865
22866    final void trimApplications() {
22867        synchronized (this) {
22868            int i;
22869
22870            // First remove any unused application processes whose package
22871            // has been removed.
22872            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
22873                final ProcessRecord app = mRemovedProcesses.get(i);
22874                if (app.activities.size() == 0
22875                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
22876                    Slog.i(
22877                        TAG, "Exiting empty application process "
22878                        + app.toShortString() + " ("
22879                        + (app.thread != null ? app.thread.asBinder() : null)
22880                        + ")\n");
22881                    if (app.pid > 0 && app.pid != MY_PID) {
22882                        app.kill("empty", false);
22883                    } else {
22884                        try {
22885                            app.thread.scheduleExit();
22886                        } catch (Exception e) {
22887                            // Ignore exceptions.
22888                        }
22889                    }
22890                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
22891                    mRemovedProcesses.remove(i);
22892
22893                    if (app.persistent) {
22894                        addAppLocked(app.info, null, false, null /* ABI override */);
22895                    }
22896                }
22897            }
22898
22899            // Now update the oom adj for all processes.
22900            updateOomAdjLocked();
22901        }
22902    }
22903
22904    /** This method sends the specified signal to each of the persistent apps */
22905    public void signalPersistentProcesses(int sig) throws RemoteException {
22906        if (sig != SIGNAL_USR1) {
22907            throw new SecurityException("Only SIGNAL_USR1 is allowed");
22908        }
22909
22910        synchronized (this) {
22911            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
22912                    != PackageManager.PERMISSION_GRANTED) {
22913                throw new SecurityException("Requires permission "
22914                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
22915            }
22916
22917            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
22918                ProcessRecord r = mLruProcesses.get(i);
22919                if (r.thread != null && r.persistent) {
22920                    sendSignal(r.pid, sig);
22921                }
22922            }
22923        }
22924    }
22925
22926    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
22927        if (proc == null || proc == mProfileProc) {
22928            proc = mProfileProc;
22929            profileType = mProfileType;
22930            clearProfilerLocked();
22931        }
22932        if (proc == null) {
22933            return;
22934        }
22935        try {
22936            proc.thread.profilerControl(false, null, profileType);
22937        } catch (RemoteException e) {
22938            throw new IllegalStateException("Process disappeared");
22939        }
22940    }
22941
22942    private void clearProfilerLocked() {
22943        if (mProfileFd != null) {
22944            try {
22945                mProfileFd.close();
22946            } catch (IOException e) {
22947            }
22948        }
22949        mProfileApp = null;
22950        mProfileProc = null;
22951        mProfileFile = null;
22952        mProfileType = 0;
22953        mAutoStopProfiler = false;
22954        mStreamingOutput = false;
22955        mSamplingInterval = 0;
22956    }
22957
22958    public boolean profileControl(String process, int userId, boolean start,
22959            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
22960
22961        try {
22962            synchronized (this) {
22963                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
22964                // its own permission.
22965                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22966                        != PackageManager.PERMISSION_GRANTED) {
22967                    throw new SecurityException("Requires permission "
22968                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22969                }
22970
22971                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
22972                    throw new IllegalArgumentException("null profile info or fd");
22973                }
22974
22975                ProcessRecord proc = null;
22976                if (process != null) {
22977                    proc = findProcessLocked(process, userId, "profileControl");
22978                }
22979
22980                if (start && (proc == null || proc.thread == null)) {
22981                    throw new IllegalArgumentException("Unknown process: " + process);
22982                }
22983
22984                if (start) {
22985                    stopProfilerLocked(null, 0);
22986                    setProfileApp(proc.info, proc.processName, profilerInfo);
22987                    mProfileProc = proc;
22988                    mProfileType = profileType;
22989                    ParcelFileDescriptor fd = profilerInfo.profileFd;
22990                    try {
22991                        fd = fd.dup();
22992                    } catch (IOException e) {
22993                        fd = null;
22994                    }
22995                    profilerInfo.profileFd = fd;
22996                    proc.thread.profilerControl(start, profilerInfo, profileType);
22997                    fd = null;
22998                    try {
22999                        mProfileFd.close();
23000                    } catch (IOException e) {
23001                    }
23002                    mProfileFd = null;
23003                } else {
23004                    stopProfilerLocked(proc, profileType);
23005                    if (profilerInfo != null && profilerInfo.profileFd != null) {
23006                        try {
23007                            profilerInfo.profileFd.close();
23008                        } catch (IOException e) {
23009                        }
23010                    }
23011                }
23012
23013                return true;
23014            }
23015        } catch (RemoteException e) {
23016            throw new IllegalStateException("Process disappeared");
23017        } finally {
23018            if (profilerInfo != null && profilerInfo.profileFd != null) {
23019                try {
23020                    profilerInfo.profileFd.close();
23021                } catch (IOException e) {
23022                }
23023            }
23024        }
23025    }
23026
23027    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23028        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23029                userId, true, ALLOW_FULL_ONLY, callName, null);
23030        ProcessRecord proc = null;
23031        try {
23032            int pid = Integer.parseInt(process);
23033            synchronized (mPidsSelfLocked) {
23034                proc = mPidsSelfLocked.get(pid);
23035            }
23036        } catch (NumberFormatException e) {
23037        }
23038
23039        if (proc == null) {
23040            ArrayMap<String, SparseArray<ProcessRecord>> all
23041                    = mProcessNames.getMap();
23042            SparseArray<ProcessRecord> procs = all.get(process);
23043            if (procs != null && procs.size() > 0) {
23044                proc = procs.valueAt(0);
23045                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23046                    for (int i=1; i<procs.size(); i++) {
23047                        ProcessRecord thisProc = procs.valueAt(i);
23048                        if (thisProc.userId == userId) {
23049                            proc = thisProc;
23050                            break;
23051                        }
23052                    }
23053                }
23054            }
23055        }
23056
23057        return proc;
23058    }
23059
23060    public boolean dumpHeap(String process, int userId, boolean managed,
23061            String path, ParcelFileDescriptor fd) throws RemoteException {
23062
23063        try {
23064            synchronized (this) {
23065                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23066                // its own permission (same as profileControl).
23067                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23068                        != PackageManager.PERMISSION_GRANTED) {
23069                    throw new SecurityException("Requires permission "
23070                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23071                }
23072
23073                if (fd == null) {
23074                    throw new IllegalArgumentException("null fd");
23075                }
23076
23077                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23078                if (proc == null || proc.thread == null) {
23079                    throw new IllegalArgumentException("Unknown process: " + process);
23080                }
23081
23082                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23083                if (!isDebuggable) {
23084                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23085                        throw new SecurityException("Process not debuggable: " + proc);
23086                    }
23087                }
23088
23089                proc.thread.dumpHeap(managed, path, fd);
23090                fd = null;
23091                return true;
23092            }
23093        } catch (RemoteException e) {
23094            throw new IllegalStateException("Process disappeared");
23095        } finally {
23096            if (fd != null) {
23097                try {
23098                    fd.close();
23099                } catch (IOException e) {
23100                }
23101            }
23102        }
23103    }
23104
23105    @Override
23106    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23107            String reportPackage) {
23108        if (processName != null) {
23109            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23110                    "setDumpHeapDebugLimit()");
23111        } else {
23112            synchronized (mPidsSelfLocked) {
23113                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23114                if (proc == null) {
23115                    throw new SecurityException("No process found for calling pid "
23116                            + Binder.getCallingPid());
23117                }
23118                if (!Build.IS_DEBUGGABLE
23119                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23120                    throw new SecurityException("Not running a debuggable build");
23121                }
23122                processName = proc.processName;
23123                uid = proc.uid;
23124                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23125                    throw new SecurityException("Package " + reportPackage + " is not running in "
23126                            + proc);
23127                }
23128            }
23129        }
23130        synchronized (this) {
23131            if (maxMemSize > 0) {
23132                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23133            } else {
23134                if (uid != 0) {
23135                    mMemWatchProcesses.remove(processName, uid);
23136                } else {
23137                    mMemWatchProcesses.getMap().remove(processName);
23138                }
23139            }
23140        }
23141    }
23142
23143    @Override
23144    public void dumpHeapFinished(String path) {
23145        synchronized (this) {
23146            if (Binder.getCallingPid() != mMemWatchDumpPid) {
23147                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23148                        + " does not match last pid " + mMemWatchDumpPid);
23149                return;
23150            }
23151            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23152                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23153                        + " does not match last path " + mMemWatchDumpFile);
23154                return;
23155            }
23156            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23157            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23158        }
23159    }
23160
23161    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23162    public void monitor() {
23163        synchronized (this) { }
23164    }
23165
23166    void onCoreSettingsChange(Bundle settings) {
23167        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23168            ProcessRecord processRecord = mLruProcesses.get(i);
23169            try {
23170                if (processRecord.thread != null) {
23171                    processRecord.thread.setCoreSettings(settings);
23172                }
23173            } catch (RemoteException re) {
23174                /* ignore */
23175            }
23176        }
23177    }
23178
23179    // Multi-user methods
23180
23181    /**
23182     * Start user, if its not already running, but don't bring it to foreground.
23183     */
23184    @Override
23185    public boolean startUserInBackground(final int userId) {
23186        return mUserController.startUser(userId, /* foreground */ false);
23187    }
23188
23189    @Override
23190    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23191        return mUserController.unlockUser(userId, token, secret, listener);
23192    }
23193
23194    @Override
23195    public boolean switchUser(final int targetUserId) {
23196        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23197        int currentUserId;
23198        UserInfo targetUserInfo;
23199        synchronized (this) {
23200            currentUserId = mUserController.getCurrentUserIdLocked();
23201            targetUserInfo = mUserController.getUserInfo(targetUserId);
23202            if (targetUserId == currentUserId) {
23203                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23204                return true;
23205            }
23206            if (targetUserInfo == null) {
23207                Slog.w(TAG, "No user info for user #" + targetUserId);
23208                return false;
23209            }
23210            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23211                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23212                        + " when device is in demo mode");
23213                return false;
23214            }
23215            if (!targetUserInfo.supportsSwitchTo()) {
23216                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23217                return false;
23218            }
23219            if (targetUserInfo.isManagedProfile()) {
23220                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23221                return false;
23222            }
23223            mUserController.setTargetUserIdLocked(targetUserId);
23224        }
23225        if (mUserController.mUserSwitchUiEnabled) {
23226            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23227            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23228            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23229            mUiHandler.sendMessage(mHandler.obtainMessage(
23230                    START_USER_SWITCH_UI_MSG, userNames));
23231        } else {
23232            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23233            mHandler.sendMessage(mHandler.obtainMessage(
23234                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
23235        }
23236        return true;
23237    }
23238
23239    void scheduleStartProfilesLocked() {
23240        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23241            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23242                    DateUtils.SECOND_IN_MILLIS);
23243        }
23244    }
23245
23246    @Override
23247    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23248        return mUserController.stopUser(userId, force, callback);
23249    }
23250
23251    @Override
23252    public UserInfo getCurrentUser() {
23253        return mUserController.getCurrentUser();
23254    }
23255
23256    String getStartedUserState(int userId) {
23257        synchronized (this) {
23258            final UserState userState = mUserController.getStartedUserStateLocked(userId);
23259            return UserState.stateToString(userState.state);
23260        }
23261    }
23262
23263    @Override
23264    public boolean isUserRunning(int userId, int flags) {
23265        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23266                && checkCallingPermission(INTERACT_ACROSS_USERS)
23267                    != PackageManager.PERMISSION_GRANTED) {
23268            String msg = "Permission Denial: isUserRunning() from pid="
23269                    + Binder.getCallingPid()
23270                    + ", uid=" + Binder.getCallingUid()
23271                    + " requires " + INTERACT_ACROSS_USERS;
23272            Slog.w(TAG, msg);
23273            throw new SecurityException(msg);
23274        }
23275        synchronized (this) {
23276            return mUserController.isUserRunningLocked(userId, flags);
23277        }
23278    }
23279
23280    @Override
23281    public int[] getRunningUserIds() {
23282        if (checkCallingPermission(INTERACT_ACROSS_USERS)
23283                != PackageManager.PERMISSION_GRANTED) {
23284            String msg = "Permission Denial: isUserRunning() from pid="
23285                    + Binder.getCallingPid()
23286                    + ", uid=" + Binder.getCallingUid()
23287                    + " requires " + INTERACT_ACROSS_USERS;
23288            Slog.w(TAG, msg);
23289            throw new SecurityException(msg);
23290        }
23291        synchronized (this) {
23292            return mUserController.getStartedUserArrayLocked();
23293        }
23294    }
23295
23296    @Override
23297    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23298        mUserController.registerUserSwitchObserver(observer, name);
23299    }
23300
23301    @Override
23302    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23303        mUserController.unregisterUserSwitchObserver(observer);
23304    }
23305
23306    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23307        if (info == null) return null;
23308        ApplicationInfo newInfo = new ApplicationInfo(info);
23309        newInfo.initForUser(userId);
23310        return newInfo;
23311    }
23312
23313    public boolean isUserStopped(int userId) {
23314        synchronized (this) {
23315            return mUserController.getStartedUserStateLocked(userId) == null;
23316        }
23317    }
23318
23319    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23320        if (aInfo == null
23321                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23322            return aInfo;
23323        }
23324
23325        ActivityInfo info = new ActivityInfo(aInfo);
23326        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23327        return info;
23328    }
23329
23330    private boolean processSanityChecksLocked(ProcessRecord process) {
23331        if (process == null || process.thread == null) {
23332            return false;
23333        }
23334
23335        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23336        if (!isDebuggable) {
23337            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23338                return false;
23339            }
23340        }
23341
23342        return true;
23343    }
23344
23345    public boolean startBinderTracking() throws RemoteException {
23346        synchronized (this) {
23347            mBinderTransactionTrackingEnabled = true;
23348            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23349            // permission (same as profileControl).
23350            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23351                    != PackageManager.PERMISSION_GRANTED) {
23352                throw new SecurityException("Requires permission "
23353                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23354            }
23355
23356            for (int i = 0; i < mLruProcesses.size(); i++) {
23357                ProcessRecord process = mLruProcesses.get(i);
23358                if (!processSanityChecksLocked(process)) {
23359                    continue;
23360                }
23361                try {
23362                    process.thread.startBinderTracking();
23363                } catch (RemoteException e) {
23364                    Log.v(TAG, "Process disappared");
23365                }
23366            }
23367            return true;
23368        }
23369    }
23370
23371    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23372        try {
23373            synchronized (this) {
23374                mBinderTransactionTrackingEnabled = false;
23375                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23376                // permission (same as profileControl).
23377                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23378                        != PackageManager.PERMISSION_GRANTED) {
23379                    throw new SecurityException("Requires permission "
23380                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23381                }
23382
23383                if (fd == null) {
23384                    throw new IllegalArgumentException("null fd");
23385                }
23386
23387                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23388                pw.println("Binder transaction traces for all processes.\n");
23389                for (ProcessRecord process : mLruProcesses) {
23390                    if (!processSanityChecksLocked(process)) {
23391                        continue;
23392                    }
23393
23394                    pw.println("Traces for process: " + process.processName);
23395                    pw.flush();
23396                    try {
23397                        TransferPipe tp = new TransferPipe();
23398                        try {
23399                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23400                            tp.go(fd.getFileDescriptor());
23401                        } finally {
23402                            tp.kill();
23403                        }
23404                    } catch (IOException e) {
23405                        pw.println("Failure while dumping IPC traces from " + process +
23406                                ".  Exception: " + e);
23407                        pw.flush();
23408                    } catch (RemoteException e) {
23409                        pw.println("Got a RemoteException while dumping IPC traces from " +
23410                                process + ".  Exception: " + e);
23411                        pw.flush();
23412                    }
23413                }
23414                fd = null;
23415                return true;
23416            }
23417        } finally {
23418            if (fd != null) {
23419                try {
23420                    fd.close();
23421                } catch (IOException e) {
23422                }
23423            }
23424        }
23425    }
23426
23427    @VisibleForTesting
23428    final class LocalService extends ActivityManagerInternal {
23429        @Override
23430        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23431                int targetUserId) {
23432            synchronized (ActivityManagerService.this) {
23433                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23434                        targetPkg, intent, null, targetUserId);
23435            }
23436        }
23437
23438        @Override
23439        public String checkContentProviderAccess(String authority, int userId) {
23440            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23441        }
23442
23443        @Override
23444        public void onWakefulnessChanged(int wakefulness) {
23445            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23446        }
23447
23448        @Override
23449        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23450                String processName, String abiOverride, int uid, Runnable crashHandler) {
23451            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23452                    processName, abiOverride, uid, crashHandler);
23453        }
23454
23455        @Override
23456        public SleepToken acquireSleepToken(String tag) {
23457            Preconditions.checkNotNull(tag);
23458
23459            synchronized (ActivityManagerService.this) {
23460                SleepTokenImpl token = new SleepTokenImpl(tag);
23461                mSleepTokens.add(token);
23462                updateSleepIfNeededLocked();
23463                return token;
23464            }
23465        }
23466
23467        @Override
23468        public ComponentName getHomeActivityForUser(int userId) {
23469            synchronized (ActivityManagerService.this) {
23470                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23471                return homeActivity == null ? null : homeActivity.realActivity;
23472            }
23473        }
23474
23475        @Override
23476        public void onUserRemoved(int userId) {
23477            synchronized (ActivityManagerService.this) {
23478                ActivityManagerService.this.onUserStoppedLocked(userId);
23479            }
23480        }
23481
23482        @Override
23483        public void onLocalVoiceInteractionStarted(IBinder activity,
23484                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23485            synchronized (ActivityManagerService.this) {
23486                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23487                        voiceSession, voiceInteractor);
23488            }
23489        }
23490
23491        @Override
23492        public void notifyAppTransitionStarting(SparseIntArray reasons) {
23493            synchronized (ActivityManagerService.this) {
23494                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reasons);
23495            }
23496        }
23497
23498        @Override
23499        public void notifyAppTransitionFinished() {
23500            synchronized (ActivityManagerService.this) {
23501                mStackSupervisor.notifyAppTransitionDone();
23502            }
23503        }
23504
23505        @Override
23506        public void notifyAppTransitionCancelled() {
23507            synchronized (ActivityManagerService.this) {
23508                mStackSupervisor.notifyAppTransitionDone();
23509            }
23510        }
23511
23512        @Override
23513        public List<IBinder> getTopVisibleActivities() {
23514            synchronized (ActivityManagerService.this) {
23515                return mStackSupervisor.getTopVisibleActivities();
23516            }
23517        }
23518
23519        @Override
23520        public void notifyDockedStackMinimizedChanged(boolean minimized) {
23521            synchronized (ActivityManagerService.this) {
23522                mStackSupervisor.setDockedStackMinimized(minimized);
23523            }
23524        }
23525
23526        @Override
23527        public void killForegroundAppsForUser(int userHandle) {
23528            synchronized (ActivityManagerService.this) {
23529                final ArrayList<ProcessRecord> procs = new ArrayList<>();
23530                final int NP = mProcessNames.getMap().size();
23531                for (int ip = 0; ip < NP; ip++) {
23532                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23533                    final int NA = apps.size();
23534                    for (int ia = 0; ia < NA; ia++) {
23535                        final ProcessRecord app = apps.valueAt(ia);
23536                        if (app.persistent) {
23537                            // We don't kill persistent processes.
23538                            continue;
23539                        }
23540                        if (app.removed) {
23541                            procs.add(app);
23542                        } else if (app.userId == userHandle && app.foregroundActivities) {
23543                            app.removed = true;
23544                            procs.add(app);
23545                        }
23546                    }
23547                }
23548
23549                final int N = procs.size();
23550                for (int i = 0; i < N; i++) {
23551                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
23552                }
23553            }
23554        }
23555
23556        @Override
23557        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
23558            if (!(target instanceof PendingIntentRecord)) {
23559                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23560                return;
23561            }
23562            ((PendingIntentRecord) target).setWhitelistDurationLocked(duration);
23563        }
23564
23565        @Override
23566        public void setDeviceIdleWhitelist(int[] appids) {
23567            synchronized (ActivityManagerService.this) {
23568                mDeviceIdleWhitelist = appids;
23569            }
23570        }
23571
23572        @Override
23573        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23574            synchronized (ActivityManagerService.this) {
23575                mDeviceIdleTempWhitelist = appids;
23576                setAppIdTempWhitelistStateLocked(changingAppId, adding);
23577            }
23578        }
23579
23580        @Override
23581        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23582                int userId) {
23583            Preconditions.checkNotNull(values, "Configuration must not be null");
23584            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23585            synchronized (ActivityManagerService.this) {
23586                updateConfigurationLocked(values, null, false, true, userId,
23587                        false /* deferResume */);
23588            }
23589        }
23590
23591        @Override
23592        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23593                Bundle bOptions) {
23594            Preconditions.checkNotNull(intents, "intents");
23595            final String[] resolvedTypes = new String[intents.length];
23596            for (int i = 0; i < intents.length; i++) {
23597                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23598            }
23599
23600            // UID of the package on user userId.
23601            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23602            // packageUid may not be initialized.
23603            int packageUid = 0;
23604            try {
23605                packageUid = AppGlobals.getPackageManager().getPackageUid(
23606                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23607            } catch (RemoteException e) {
23608                // Shouldn't happen.
23609            }
23610
23611            synchronized (ActivityManagerService.this) {
23612                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23613                        /*resultTo*/ null, bOptions, userId);
23614            }
23615        }
23616
23617        @Override
23618        public int getUidProcessState(int uid) {
23619            return getUidState(uid);
23620        }
23621
23622        @Override
23623        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23624            synchronized (ActivityManagerService.this) {
23625
23626                // We might change the visibilities here, so prepare an empty app transition which
23627                // might be overridden later if we actually change visibilities.
23628                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
23629                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23630                mWindowManager.executeAppTransition();
23631            }
23632            if (callback != null) {
23633                callback.run();
23634            }
23635        }
23636
23637        @Override
23638        public boolean isSystemReady() {
23639            // no need to synchronize(this) just to read & return the value
23640            return mSystemReady;
23641        }
23642
23643        @Override
23644        public void notifyKeyguardTrustedChanged() {
23645            synchronized (ActivityManagerService.this) {
23646                if (mKeyguardController.isKeyguardShowing()) {
23647                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23648                }
23649            }
23650        }
23651
23652        /**
23653         * Sets if the given pid has an overlay UI or not.
23654         *
23655         * @param pid The pid we are setting overlay UI for.
23656         * @param hasOverlayUi True if the process has overlay UI.
23657         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
23658         */
23659        @Override
23660        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
23661            synchronized (ActivityManagerService.this) {
23662                final ProcessRecord pr;
23663                synchronized (mPidsSelfLocked) {
23664                    pr = mPidsSelfLocked.get(pid);
23665                    if (pr == null) {
23666                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
23667                        return;
23668                    }
23669                }
23670                if (pr.hasOverlayUi == hasOverlayUi) {
23671                    return;
23672                }
23673                pr.hasOverlayUi = hasOverlayUi;
23674                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
23675                updateOomAdjLocked(pr);
23676            }
23677        }
23678
23679        /**
23680         * Called after the network policy rules are updated by
23681         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
23682         * and {@param procStateSeq}.
23683         */
23684        @Override
23685        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
23686            if (DEBUG_NETWORK) {
23687                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
23688                        + uid + " seq: " + procStateSeq);
23689            }
23690            UidRecord record;
23691            synchronized (ActivityManagerService.this) {
23692                record = mActiveUids.get(uid);
23693                if (record == null) {
23694                    if (DEBUG_NETWORK) {
23695                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
23696                                + " procStateSeq: " + procStateSeq);
23697                    }
23698                    return;
23699                }
23700            }
23701            synchronized (record.networkStateLock) {
23702                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23703                    if (DEBUG_NETWORK) {
23704                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
23705                                + " been handled for uid: " + uid);
23706                    }
23707                    return;
23708                }
23709                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
23710                if (record.curProcStateSeq > procStateSeq) {
23711                    if (DEBUG_NETWORK) {
23712                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
23713                                + ", curProcstateSeq: " + record.curProcStateSeq
23714                                + ", procStateSeq: " + procStateSeq);
23715                    }
23716                    return;
23717                }
23718                if (record.waitingForNetwork) {
23719                    if (DEBUG_NETWORK) {
23720                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
23721                                + ", procStateSeq: " + procStateSeq);
23722                    }
23723                    record.networkStateLock.notifyAll();
23724                }
23725            }
23726        }
23727
23728        /**
23729         * Called after virtual display Id is updated by
23730         * {@link com.android.server.vr.Vr2dDisplay} with a specific
23731         * {@param vrVr2dDisplayId}.
23732         */
23733        @Override
23734        public void setVr2dDisplayId(int vr2dDisplayId) {
23735            if (DEBUG_STACK) {
23736                Slog.d(TAG, "setVr2dDisplayId called for: " +
23737                        vr2dDisplayId);
23738            }
23739            synchronized (ActivityManagerService.this) {
23740                mVr2dDisplayId = vr2dDisplayId;
23741            }
23742        }
23743    }
23744
23745    /**
23746     * Called by app main thread to wait for the network policy rules to get udpated.
23747     *
23748     * @param procStateSeq The sequence number indicating the process state change that the main
23749     *                     thread is interested in.
23750     */
23751    @Override
23752    public void waitForNetworkStateUpdate(long procStateSeq) {
23753        final int callingUid = Binder.getCallingUid();
23754        if (DEBUG_NETWORK) {
23755            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
23756        }
23757        UidRecord record;
23758        synchronized (this) {
23759            record = mActiveUids.get(callingUid);
23760            if (record == null) {
23761                return;
23762            }
23763        }
23764        synchronized (record.networkStateLock) {
23765            if (record.lastDispatchedProcStateSeq < procStateSeq) {
23766                if (DEBUG_NETWORK) {
23767                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
23768                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
23769                            + " lastProcStateSeqDispatchedToObservers: "
23770                            + record.lastDispatchedProcStateSeq);
23771                }
23772                return;
23773            }
23774            if (record.curProcStateSeq > procStateSeq) {
23775                if (DEBUG_NETWORK) {
23776                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
23777                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
23778                            + ", procStateSeq: " + procStateSeq);
23779                }
23780                return;
23781            }
23782            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23783                if (DEBUG_NETWORK) {
23784                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
23785                            + procStateSeq + ", so no need to wait. Uid: "
23786                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
23787                            + record.lastNetworkUpdatedProcStateSeq);
23788                }
23789                return;
23790            }
23791            try {
23792                if (DEBUG_NETWORK) {
23793                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
23794                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
23795                }
23796                final long startTime = SystemClock.uptimeMillis();
23797                record.waitingForNetwork = true;
23798                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
23799                record.waitingForNetwork = false;
23800                final long totalTime = SystemClock.uptimeMillis() - startTime;
23801                if (totalTime >= mWaitForNetworkTimeoutMs) {
23802                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
23803                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
23804                            + procStateSeq + " UidRec: " + record
23805                            + " validateUidRec: " + mValidateUids.get(callingUid));
23806                }
23807            } catch (InterruptedException e) {
23808                Thread.currentThread().interrupt();
23809            }
23810        }
23811    }
23812
23813    /**
23814     * Return the user id of the last resumed activity.
23815     */
23816    @Override
23817    public @UserIdInt int getLastResumedActivityUserId() {
23818        enforceCallingPermission(
23819                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
23820        synchronized (this) {
23821            if (mLastResumedActivity == null) {
23822                return mUserController.getCurrentUserIdLocked();
23823            }
23824            return mLastResumedActivity.userId;
23825        }
23826    }
23827
23828    private final class SleepTokenImpl extends SleepToken {
23829        private final String mTag;
23830        private final long mAcquireTime;
23831
23832        public SleepTokenImpl(String tag) {
23833            mTag = tag;
23834            mAcquireTime = SystemClock.uptimeMillis();
23835        }
23836
23837        @Override
23838        public void release() {
23839            synchronized (ActivityManagerService.this) {
23840                if (mSleepTokens.remove(this)) {
23841                    updateSleepIfNeededLocked();
23842                }
23843            }
23844        }
23845
23846        @Override
23847        public String toString() {
23848            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
23849        }
23850    }
23851
23852    /**
23853     * An implementation of IAppTask, that allows an app to manage its own tasks via
23854     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
23855     * only the process that calls getAppTasks() can call the AppTask methods.
23856     */
23857    class AppTaskImpl extends IAppTask.Stub {
23858        private int mTaskId;
23859        private int mCallingUid;
23860
23861        public AppTaskImpl(int taskId, int callingUid) {
23862            mTaskId = taskId;
23863            mCallingUid = callingUid;
23864        }
23865
23866        private void checkCaller() {
23867            if (mCallingUid != Binder.getCallingUid()) {
23868                throw new SecurityException("Caller " + mCallingUid
23869                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
23870            }
23871        }
23872
23873        @Override
23874        public void finishAndRemoveTask() {
23875            checkCaller();
23876
23877            synchronized (ActivityManagerService.this) {
23878                long origId = Binder.clearCallingIdentity();
23879                try {
23880                    // We remove the task from recents to preserve backwards
23881                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
23882                            REMOVE_FROM_RECENTS)) {
23883                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23884                    }
23885                } finally {
23886                    Binder.restoreCallingIdentity(origId);
23887                }
23888            }
23889        }
23890
23891        @Override
23892        public ActivityManager.RecentTaskInfo getTaskInfo() {
23893            checkCaller();
23894
23895            synchronized (ActivityManagerService.this) {
23896                long origId = Binder.clearCallingIdentity();
23897                try {
23898                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23899                    if (tr == null) {
23900                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23901                    }
23902                    return createRecentTaskInfoFromTaskRecord(tr);
23903                } finally {
23904                    Binder.restoreCallingIdentity(origId);
23905                }
23906            }
23907        }
23908
23909        @Override
23910        public void moveToFront() {
23911            checkCaller();
23912            // Will bring task to front if it already has a root activity.
23913            final long origId = Binder.clearCallingIdentity();
23914            try {
23915                synchronized (this) {
23916                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
23917                }
23918            } finally {
23919                Binder.restoreCallingIdentity(origId);
23920            }
23921        }
23922
23923        @Override
23924        public int startActivity(IBinder whoThread, String callingPackage,
23925                Intent intent, String resolvedType, Bundle bOptions) {
23926            checkCaller();
23927
23928            int callingUser = UserHandle.getCallingUserId();
23929            TaskRecord tr;
23930            IApplicationThread appThread;
23931            synchronized (ActivityManagerService.this) {
23932                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23933                if (tr == null) {
23934                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23935                }
23936                appThread = IApplicationThread.Stub.asInterface(whoThread);
23937                if (appThread == null) {
23938                    throw new IllegalArgumentException("Bad app thread " + appThread);
23939                }
23940            }
23941            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
23942                    resolvedType, null, null, null, null, 0, 0, null, null,
23943                    null, bOptions, false, callingUser, null, tr);
23944        }
23945
23946        @Override
23947        public void setExcludeFromRecents(boolean exclude) {
23948            checkCaller();
23949
23950            synchronized (ActivityManagerService.this) {
23951                long origId = Binder.clearCallingIdentity();
23952                try {
23953                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23954                    if (tr == null) {
23955                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23956                    }
23957                    Intent intent = tr.getBaseIntent();
23958                    if (exclude) {
23959                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23960                    } else {
23961                        intent.setFlags(intent.getFlags()
23962                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23963                    }
23964                } finally {
23965                    Binder.restoreCallingIdentity(origId);
23966                }
23967            }
23968        }
23969    }
23970
23971    /**
23972     * Kill processes for the user with id userId and that depend on the package named packageName
23973     */
23974    @Override
23975    public void killPackageDependents(String packageName, int userId) {
23976        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
23977        if (packageName == null) {
23978            throw new NullPointerException(
23979                    "Cannot kill the dependents of a package without its name.");
23980        }
23981
23982        long callingId = Binder.clearCallingIdentity();
23983        IPackageManager pm = AppGlobals.getPackageManager();
23984        int pkgUid = -1;
23985        try {
23986            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
23987        } catch (RemoteException e) {
23988        }
23989        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
23990            throw new IllegalArgumentException(
23991                    "Cannot kill dependents of non-existing package " + packageName);
23992        }
23993        try {
23994            synchronized(this) {
23995                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
23996                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
23997                        "dep: " + packageName);
23998            }
23999        } finally {
24000            Binder.restoreCallingIdentity(callingId);
24001        }
24002    }
24003
24004    @Override
24005    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24006            throws RemoteException {
24007        final long callingId = Binder.clearCallingIdentity();
24008        try {
24009            mKeyguardController.dismissKeyguard(token, callback);
24010        } finally {
24011            Binder.restoreCallingIdentity(callingId);
24012        }
24013    }
24014
24015    @Override
24016    public int restartUserInBackground(final int userId) {
24017        return mUserController.restartUser(userId, /* foreground */ false);
24018    }
24019
24020    @Override
24021    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24022        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24023                "scheduleApplicationInfoChanged()");
24024
24025        synchronized (this) {
24026            final long origId = Binder.clearCallingIdentity();
24027            try {
24028                updateApplicationInfoLocked(packageNames, userId);
24029            } finally {
24030                Binder.restoreCallingIdentity(origId);
24031            }
24032        }
24033    }
24034
24035    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24036        final PackageManagerInternal packageManager = getPackageManagerInternalLocked();
24037        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24038        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24039            final ProcessRecord app = mLruProcesses.get(i);
24040            if (app.thread == null) {
24041                continue;
24042            }
24043
24044            if (userId != UserHandle.USER_ALL && app.userId != userId) {
24045                continue;
24046            }
24047
24048            final int packageCount = app.pkgList.size();
24049            for (int j = 0; j < packageCount; j++) {
24050                final String packageName = app.pkgList.keyAt(j);
24051                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24052                    try {
24053                        final ApplicationInfo ai = packageManager.getApplicationInfo(
24054                                packageName, app.userId);
24055                        if (ai != null) {
24056                            app.thread.scheduleApplicationInfoChanged(ai);
24057                        }
24058                    } catch (RemoteException e) {
24059                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24060                                    packageName, app));
24061                    }
24062                }
24063            }
24064        }
24065    }
24066
24067    /**
24068     * Attach an agent to the specified process (proces name or PID)
24069     */
24070    public void attachAgent(String process, String path) {
24071        try {
24072            synchronized (this) {
24073                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24074                if (proc == null || proc.thread == null) {
24075                    throw new IllegalArgumentException("Unknown process: " + process);
24076                }
24077
24078                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24079                if (!isDebuggable) {
24080                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24081                        throw new SecurityException("Process not debuggable: " + proc);
24082                    }
24083                }
24084
24085                proc.thread.attachAgent(path);
24086            }
24087        } catch (RemoteException e) {
24088            throw new IllegalStateException("Process disappeared");
24089        }
24090    }
24091
24092    @VisibleForTesting
24093    public static class Injector {
24094        private NetworkManagementInternal mNmi;
24095
24096        public Context getContext() {
24097            return null;
24098        }
24099
24100        public AppOpsService getAppOpsService(File file, Handler handler) {
24101            return new AppOpsService(file, handler);
24102        }
24103
24104        public Handler getUiHandler(ActivityManagerService service) {
24105            return service.new UiHandler();
24106        }
24107
24108        public boolean isNetworkRestrictedForUid(int uid) {
24109            if (ensureHasNetworkManagementInternal()) {
24110                return mNmi.isNetworkRestrictedForUid(uid);
24111            }
24112            return false;
24113        }
24114
24115        private boolean ensureHasNetworkManagementInternal() {
24116            if (mNmi == null) {
24117                mNmi = LocalServices.getService(NetworkManagementInternal.class);
24118            }
24119            return mNmi != null;
24120        }
24121    }
24122}
24123