ActivityManagerService.java revision 2f5c306b82eda6d213dae1d6dd53389a551201e3
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.CHANGE_CONFIGURATION;
20import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21import static android.Manifest.permission.INTERACT_ACROSS_USERS;
22import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
23import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
24import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
25import static android.Manifest.permission.READ_FRAME_BUFFER;
26import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
27import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
28import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
29import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
30import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
31import static android.app.ActivityManager.StackId.FIRST_DYNAMIC_STACK_ID;
32import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
33import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
34import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
35import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
36import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
37import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
38import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
39import static android.content.pm.PackageManager.GET_PROVIDERS;
40import static android.content.pm.PackageManager.MATCH_ANY_USER;
41import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
42import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
43import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
44import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
45import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
46import static android.content.pm.PackageManager.PERMISSION_GRANTED;
47import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
48import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
49import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
50import static android.os.Build.VERSION_CODES.N;
51import static android.os.Process.BLUETOOTH_UID;
52import static android.os.Process.FIRST_APPLICATION_UID;
53import static android.os.Process.FIRST_ISOLATED_UID;
54import static android.os.Process.LAST_ISOLATED_UID;
55import static android.os.Process.NFC_UID;
56import static android.os.Process.PHONE_UID;
57import static android.os.Process.PROC_CHAR;
58import static android.os.Process.PROC_OUT_LONG;
59import static android.os.Process.PROC_PARENS;
60import static android.os.Process.PROC_SPACE_TERM;
61import static android.os.Process.ProcessStartResult;
62import static android.os.Process.ROOT_UID;
63import static android.os.Process.SCHED_FIFO;
64import static android.os.Process.SCHED_OTHER;
65import static android.os.Process.SCHED_RESET_ON_FORK;
66import static android.os.Process.SHELL_UID;
67import static android.os.Process.SIGNAL_QUIT;
68import static android.os.Process.SIGNAL_USR1;
69import static android.os.Process.SYSTEM_UID;
70import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
71import static android.os.Process.THREAD_GROUP_DEFAULT;
72import static android.os.Process.THREAD_GROUP_TOP_APP;
73import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
74import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
75import static android.os.Process.getFreeMemory;
76import static android.os.Process.getTotalMemory;
77import static android.os.Process.isThreadInProcess;
78import static android.os.Process.killProcess;
79import static android.os.Process.killProcessQuiet;
80import static android.os.Process.myPid;
81import static android.os.Process.myUid;
82import static android.os.Process.readProcFile;
83import static android.os.Process.removeAllProcessGroups;
84import static android.os.Process.sendSignal;
85import static android.os.Process.setProcessGroup;
86import static android.os.Process.setThreadPriority;
87import static android.os.Process.setThreadScheduler;
88import static android.os.Process.startWebView;
89import static android.os.Process.zygoteProcess;
90import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
91import static android.provider.Settings.Global.DEBUG_APP;
92import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
93import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
94import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
95import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
96import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
97import static android.provider.Settings.System.FONT_SCALE;
98import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
99import static android.text.format.DateUtils.DAY_IN_MILLIS;
100import static android.view.Display.DEFAULT_DISPLAY;
101import static android.view.Display.INVALID_DISPLAY;
102import static com.android.internal.util.XmlUtils.readBooleanAttribute;
103import static com.android.internal.util.XmlUtils.readIntAttribute;
104import static com.android.internal.util.XmlUtils.readLongAttribute;
105import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
106import static com.android.internal.util.XmlUtils.writeIntAttribute;
107import static com.android.internal.util.XmlUtils.writeLongAttribute;
108import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
109import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
110import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
111import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
112import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
113import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
114import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
115import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
116import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
117import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
118import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
119import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
120import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
121import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
122import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
123import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
124import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
125import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
126import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
127import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
128import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
129import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
130import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
131import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
132import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
133import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
134import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
135import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
136import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
137import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
138import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
139import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
140import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
141import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
142import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
143import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
144import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
145import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
146import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
147import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
148import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
149import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
150import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
151import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
152import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
153import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
154import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
155import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
156import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
157import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
158import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
159import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
160import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
161import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
162import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
163import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
164import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
165import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
166import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
167import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
168import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
169import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
170import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
171import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
172import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
173import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
174import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
175import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
176import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
177import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
178import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
179import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
180import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
181import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
182import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
183import static com.android.server.wm.AppTransition.TRANSIT_NONE;
184import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
185import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
186import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
187import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
188import static org.xmlpull.v1.XmlPullParser.START_TAG;
189
190import android.Manifest;
191import android.Manifest.permission;
192import android.annotation.NonNull;
193import android.annotation.Nullable;
194import android.annotation.UserIdInt;
195import android.app.Activity;
196import android.app.ActivityManager;
197import android.app.ActivityManager.RunningTaskInfo;
198import android.app.ActivityManager.StackId;
199import android.app.ActivityManager.StackInfo;
200import android.app.ActivityManager.TaskSnapshot;
201import android.app.ActivityManager.TaskThumbnailInfo;
202import android.app.ActivityManagerInternal;
203import android.app.ActivityManagerInternal.SleepToken;
204import android.app.ActivityOptions;
205import android.app.ActivityThread;
206import android.app.AlertDialog;
207import android.app.AppGlobals;
208import android.app.AppOpsManager;
209import android.app.ApplicationErrorReport;
210import android.app.ApplicationThreadConstants;
211import android.app.BroadcastOptions;
212import android.app.ContentProviderHolder;
213import android.app.Dialog;
214import android.app.IActivityController;
215import android.app.IActivityManager;
216import android.app.IAppTask;
217import android.app.IApplicationThread;
218import android.app.IInstrumentationWatcher;
219import android.app.INotificationManager;
220import android.app.IProcessObserver;
221import android.app.IServiceConnection;
222import android.app.IStopUserCallback;
223import android.app.ITaskStackListener;
224import android.app.IUiAutomationConnection;
225import android.app.IUidObserver;
226import android.app.IUserSwitchObserver;
227import android.app.Instrumentation;
228import android.app.Notification;
229import android.app.NotificationManager;
230import android.app.PendingIntent;
231import android.app.PictureInPictureParams;
232import android.app.ProfilerInfo;
233import android.app.RemoteAction;
234import android.app.WaitResult;
235import android.app.admin.DevicePolicyManager;
236import android.app.assist.AssistContent;
237import android.app.assist.AssistStructure;
238import android.app.backup.IBackupManager;
239import android.app.usage.UsageEvents;
240import android.app.usage.UsageStatsManagerInternal;
241import android.appwidget.AppWidgetManager;
242import android.content.ActivityNotFoundException;
243import android.content.BroadcastReceiver;
244import android.content.ClipData;
245import android.content.ComponentCallbacks2;
246import android.content.ComponentName;
247import android.content.ContentProvider;
248import android.content.ContentResolver;
249import android.content.Context;
250import android.content.DialogInterface;
251import android.content.IContentProvider;
252import android.content.IIntentReceiver;
253import android.content.IIntentSender;
254import android.content.Intent;
255import android.content.IntentFilter;
256import android.content.pm.ActivityInfo;
257import android.content.pm.ApplicationInfo;
258import android.content.pm.ConfigurationInfo;
259import android.content.pm.IPackageDataObserver;
260import android.content.pm.IPackageManager;
261import android.content.pm.InstrumentationInfo;
262import android.content.pm.PackageInfo;
263import android.content.pm.PackageManager;
264import android.content.pm.PackageManager.NameNotFoundException;
265import android.content.pm.PackageManagerInternal;
266import android.content.pm.ParceledListSlice;
267import android.content.pm.PathPermission;
268import android.content.pm.PermissionInfo;
269import android.content.pm.ProviderInfo;
270import android.content.pm.ResolveInfo;
271import android.content.pm.SELinuxUtil;
272import android.content.pm.ServiceInfo;
273import android.content.pm.UserInfo;
274import android.content.res.CompatibilityInfo;
275import android.content.res.Configuration;
276import android.content.res.Resources;
277import android.database.ContentObserver;
278import android.graphics.Bitmap;
279import android.graphics.Point;
280import android.graphics.Rect;
281import android.location.LocationManager;
282import android.media.audiofx.AudioEffect;
283import android.metrics.LogMaker;
284import android.net.Proxy;
285import android.net.ProxyInfo;
286import android.net.Uri;
287import android.os.BatteryStats;
288import android.os.Binder;
289import android.os.Build;
290import android.os.Bundle;
291import android.os.Debug;
292import android.os.DropBoxManager;
293import android.os.Environment;
294import android.os.FactoryTest;
295import android.os.FileObserver;
296import android.os.FileUtils;
297import android.os.Handler;
298import android.os.IBinder;
299import android.os.IDeviceIdentifiersPolicyService;
300import android.os.IPermissionController;
301import android.os.IProcessInfoService;
302import android.os.IProgressListener;
303import android.os.LocaleList;
304import android.os.Looper;
305import android.os.Message;
306import android.os.Parcel;
307import android.os.ParcelFileDescriptor;
308import android.os.PersistableBundle;
309import android.os.PowerManager;
310import android.os.PowerManagerInternal;
311import android.os.Process;
312import android.os.RemoteCallbackList;
313import android.os.RemoteException;
314import android.os.ResultReceiver;
315import android.os.ServiceManager;
316import android.os.ShellCallback;
317import android.os.StrictMode;
318import android.os.SystemClock;
319import android.os.SystemProperties;
320import android.os.Trace;
321import android.os.TransactionTooLargeException;
322import android.os.UpdateLock;
323import android.os.UserHandle;
324import android.os.UserManager;
325import android.os.WorkSource;
326import android.os.storage.IStorageManager;
327import android.os.storage.StorageManager;
328import android.os.storage.StorageManagerInternal;
329import android.provider.Downloads;
330import android.provider.Settings;
331import android.service.voice.IVoiceInteractionSession;
332import android.service.voice.VoiceInteractionManagerInternal;
333import android.service.voice.VoiceInteractionSession;
334import android.telecom.TelecomManager;
335import android.text.TextUtils;
336import android.text.format.DateUtils;
337import android.text.format.Time;
338import android.text.style.SuggestionSpan;
339import android.util.ArrayMap;
340import android.util.ArraySet;
341import android.util.AtomicFile;
342import android.util.TimingsTraceLog;
343import android.util.DebugUtils;
344import android.util.DisplayMetrics;
345import android.util.EventLog;
346import android.util.Log;
347import android.util.Pair;
348import android.util.PrintWriterPrinter;
349import android.util.Slog;
350import android.util.SparseArray;
351import android.util.SparseIntArray;
352import android.util.TimeUtils;
353import android.util.Xml;
354import android.view.Gravity;
355import android.view.LayoutInflater;
356import android.view.View;
357import android.view.WindowManager;
358
359import com.android.server.job.JobSchedulerInternal;
360import com.google.android.collect.Lists;
361import com.google.android.collect.Maps;
362
363import com.android.internal.R;
364import com.android.internal.annotations.GuardedBy;
365import com.android.internal.annotations.VisibleForTesting;
366import com.android.internal.app.AssistUtils;
367import com.android.internal.app.DumpHeapActivity;
368import com.android.internal.app.IAppOpsCallback;
369import com.android.internal.app.IAppOpsService;
370import com.android.internal.app.IVoiceInteractor;
371import com.android.internal.app.ProcessMap;
372import com.android.internal.app.SystemUserHomeActivity;
373import com.android.internal.app.procstats.ProcessStats;
374import com.android.internal.logging.MetricsLogger;
375import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
376import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
377import com.android.internal.notification.SystemNotificationChannels;
378import com.android.internal.os.BackgroundThread;
379import com.android.internal.os.BatteryStatsImpl;
380import com.android.internal.os.IResultReceiver;
381import com.android.internal.os.ProcessCpuTracker;
382import com.android.internal.os.TransferPipe;
383import com.android.internal.os.Zygote;
384import com.android.internal.policy.IKeyguardDismissCallback;
385import com.android.internal.telephony.TelephonyIntents;
386import com.android.internal.util.ArrayUtils;
387import com.android.internal.util.DumpUtils;
388import com.android.internal.util.FastPrintWriter;
389import com.android.internal.util.FastXmlSerializer;
390import com.android.internal.util.MemInfoReader;
391import com.android.internal.util.Preconditions;
392import com.android.server.AppOpsService;
393import com.android.server.AttributeCache;
394import com.android.server.DeviceIdleController;
395import com.android.server.IntentResolver;
396import com.android.server.LocalServices;
397import com.android.server.LockGuard;
398import com.android.server.NetworkManagementInternal;
399import com.android.server.RescueParty;
400import com.android.server.ServiceThread;
401import com.android.server.SystemConfig;
402import com.android.server.SystemService;
403import com.android.server.SystemServiceManager;
404import com.android.server.ThreadPriorityBooster;
405import com.android.server.Watchdog;
406import com.android.server.am.ActivityStack.ActivityState;
407import com.android.server.firewall.IntentFirewall;
408import com.android.server.pm.Installer;
409import com.android.server.pm.Installer.InstallerException;
410import com.android.server.statusbar.StatusBarManagerInternal;
411import com.android.server.vr.VrManagerInternal;
412import com.android.server.wm.PinnedStackWindowController;
413import com.android.server.wm.WindowManagerService;
414
415import java.text.SimpleDateFormat;
416import org.xmlpull.v1.XmlPullParser;
417import org.xmlpull.v1.XmlPullParserException;
418import org.xmlpull.v1.XmlSerializer;
419
420import java.io.File;
421import java.io.FileDescriptor;
422import java.io.FileInputStream;
423import java.io.FileNotFoundException;
424import java.io.FileOutputStream;
425import java.io.IOException;
426import java.io.InputStreamReader;
427import java.io.PrintWriter;
428import java.io.StringWriter;
429import java.io.UnsupportedEncodingException;
430import java.lang.ref.WeakReference;
431import java.nio.charset.StandardCharsets;
432import java.text.DateFormat;
433import java.util.ArrayList;
434import java.util.Arrays;
435import java.util.Collections;
436import java.util.Comparator;
437import java.util.Date;
438import java.util.HashMap;
439import java.util.HashSet;
440import java.util.Iterator;
441import java.util.List;
442import java.util.Locale;
443import java.util.Map;
444import java.util.Objects;
445import java.util.Set;
446import java.util.concurrent.CountDownLatch;
447import java.util.concurrent.atomic.AtomicBoolean;
448import java.util.concurrent.atomic.AtomicLong;
449
450import dalvik.system.VMRuntime;
451import libcore.io.IoUtils;
452import libcore.util.EmptyArray;
453
454public class ActivityManagerService extends IActivityManager.Stub
455        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
456
457    /**
458     * Priority we boost main thread and RT of top app to.
459     */
460    public static final int TOP_APP_PRIORITY_BOOST = -10;
461
462    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
463    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
464    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
465    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
466    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
467    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
468    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
469    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
470    private static final String TAG_LRU = TAG + POSTFIX_LRU;
471    private static final String TAG_MU = TAG + POSTFIX_MU;
472    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
473    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
474    private static final String TAG_POWER = TAG + POSTFIX_POWER;
475    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
476    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
477    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
478    private static final String TAG_PSS = TAG + POSTFIX_PSS;
479    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
480    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
481    private static final String TAG_STACK = TAG + POSTFIX_STACK;
482    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
483    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
484    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
485    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
486
487    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
488    // here so that while the job scheduler can depend on AMS, the other way around
489    // need not be the case.
490    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
491
492    /** Control over CPU and battery monitoring */
493    // write battery stats every 30 minutes.
494    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
495    static final boolean MONITOR_CPU_USAGE = true;
496    // don't sample cpu less than every 5 seconds.
497    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
498    // wait possibly forever for next cpu sample.
499    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
500    static final boolean MONITOR_THREAD_CPU_USAGE = false;
501
502    // The flags that are set for all calls we make to the package manager.
503    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
504
505    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
506
507    // Amount of time after a call to stopAppSwitches() during which we will
508    // prevent further untrusted switches from happening.
509    static final long APP_SWITCH_DELAY_TIME = 5*1000;
510
511    // How long we wait for a launched process to attach to the activity manager
512    // before we decide it's never going to come up for real.
513    static final int PROC_START_TIMEOUT = 10*1000;
514    // How long we wait for an attached process to publish its content providers
515    // before we decide it must be hung.
516    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
517
518    // How long we wait for a launched process to attach to the activity manager
519    // before we decide it's never going to come up for real, when the process was
520    // started with a wrapper for instrumentation (such as Valgrind) because it
521    // could take much longer than usual.
522    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
523
524    // How long we allow a receiver to run before giving up on it.
525    static final int BROADCAST_FG_TIMEOUT = 10*1000;
526    static final int BROADCAST_BG_TIMEOUT = 60*1000;
527
528    // How long we wait until we timeout on key dispatching.
529    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
530
531    // How long we wait until we timeout on key dispatching during instrumentation.
532    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
533
534    // How long to wait in getAssistContextExtras for the activity and foreground services
535    // to respond with the result.
536    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
537
538    // How long top wait when going through the modern assist (which doesn't need to block
539    // on getting this result before starting to launch its UI).
540    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
541
542    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
543    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
544
545    // Maximum number of persisted Uri grants a package is allowed
546    static final int MAX_PERSISTED_URI_GRANTS = 128;
547
548    static final int MY_PID = myPid();
549
550    static final String[] EMPTY_STRING_ARRAY = new String[0];
551
552    // How many bytes to write into the dropbox log before truncating
553    static final int DROPBOX_MAX_SIZE = 192 * 1024;
554    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
555    // as one line, but close enough for now.
556    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
557
558    // Access modes for handleIncomingUser.
559    static final int ALLOW_NON_FULL = 0;
560    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
561    static final int ALLOW_FULL_ONLY = 2;
562
563    // Necessary ApplicationInfo flags to mark an app as persistent
564    private static final int PERSISTENT_MASK =
565            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
566
567    // Intent sent when remote bugreport collection has been completed
568    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
569            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
570
571    // Used to indicate that an app transition should be animated.
572    static final boolean ANIMATE = true;
573
574    // Determines whether to take full screen screenshots
575    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
576
577    /**
578     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
579     */
580    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
581
582    /**
583     * State indicating that there is no need for any blocking for network.
584     */
585    @VisibleForTesting
586    static final int NETWORK_STATE_NO_CHANGE = 0;
587
588    /**
589     * State indicating that the main thread needs to be informed about the network wait.
590     */
591    @VisibleForTesting
592    static final int NETWORK_STATE_BLOCK = 1;
593
594    /**
595     * State indicating that any threads waiting for network state to get updated can be unblocked.
596     */
597    @VisibleForTesting
598    static final int NETWORK_STATE_UNBLOCK = 2;
599
600    // Max character limit for a notification title. If the notification title is larger than this
601    // the notification will not be legible to the user.
602    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
603
604    private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
605
606    /** All system services */
607    SystemServiceManager mSystemServiceManager;
608    AssistUtils mAssistUtils;
609
610    private Installer mInstaller;
611
612    /** Run all ActivityStacks through this */
613    final ActivityStackSupervisor mStackSupervisor;
614    private final KeyguardController mKeyguardController;
615
616    final ActivityStarter mActivityStarter;
617
618    final TaskChangeNotificationController mTaskChangeNotificationController;
619
620    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
621
622    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
623
624    public final IntentFirewall mIntentFirewall;
625
626    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
627    // default action automatically.  Important for devices without direct input
628    // devices.
629    private boolean mShowDialogs = true;
630
631    private final VrController mVrController;
632
633    // VR Vr2d Display Id.
634    int mVr2dDisplayId = INVALID_DISPLAY;
635
636    // Whether we should use SCHED_FIFO for UI and RenderThreads.
637    private boolean mUseFifoUiScheduling = false;
638
639    BroadcastQueue mFgBroadcastQueue;
640    BroadcastQueue mBgBroadcastQueue;
641    // Convenient for easy iteration over the queues. Foreground is first
642    // so that dispatch of foreground broadcasts gets precedence.
643    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
644
645    BroadcastStats mLastBroadcastStats;
646    BroadcastStats mCurBroadcastStats;
647
648    BroadcastQueue broadcastQueueForIntent(Intent intent) {
649        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
650        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
651                "Broadcast intent " + intent + " on "
652                + (isFg ? "foreground" : "background") + " queue");
653        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
654    }
655
656    /**
657     * The last resumed activity. This is identical to the current resumed activity most
658     * of the time but could be different when we're pausing one activity before we resume
659     * another activity.
660     */
661    private ActivityRecord mLastResumedActivity;
662
663    /**
664     * If non-null, we are tracking the time the user spends in the currently focused app.
665     */
666    private AppTimeTracker mCurAppTimeTracker;
667
668    /**
669     * List of intents that were used to start the most recent tasks.
670     */
671    final RecentTasks mRecentTasks;
672
673    /**
674     * For addAppTask: cached of the last activity component that was added.
675     */
676    ComponentName mLastAddedTaskComponent;
677
678    /**
679     * For addAppTask: cached of the last activity uid that was added.
680     */
681    int mLastAddedTaskUid;
682
683    /**
684     * For addAppTask: cached of the last ActivityInfo that was added.
685     */
686    ActivityInfo mLastAddedTaskActivity;
687
688    /**
689     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
690     */
691    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
692
693    /**
694     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
695     */
696    String mDeviceOwnerName;
697
698    final UserController mUserController;
699
700    final AppErrors mAppErrors;
701
702    /**
703     * Dump of the activity state at the time of the last ANR. Cleared after
704     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
705     */
706    String mLastANRState;
707
708    /**
709     * Indicates the maximum time spent waiting for the network rules to get updated.
710     */
711    @VisibleForTesting
712    long mWaitForNetworkTimeoutMs;
713
714    public boolean canShowErrorDialogs() {
715        return mShowDialogs && !mSleeping && !mShuttingDown
716                && !mKeyguardController.isKeyguardShowing()
717                && !(UserManager.isDeviceInDemoMode(mContext)
718                        && mUserController.getCurrentUser().isDemo());
719    }
720
721    private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
722            THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
723
724    static void boostPriorityForLockedSection() {
725        sThreadPriorityBooster.boost();
726    }
727
728    static void resetPriorityAfterLockedSection() {
729        sThreadPriorityBooster.reset();
730    }
731
732    public class PendingAssistExtras extends Binder implements Runnable {
733        public final ActivityRecord activity;
734        public boolean isHome;
735        public final Bundle extras;
736        public final Intent intent;
737        public final String hint;
738        public final IResultReceiver receiver;
739        public final int userHandle;
740        public boolean haveResult = false;
741        public Bundle result = null;
742        public AssistStructure structure = null;
743        public AssistContent content = null;
744        public Bundle receiverExtras;
745
746        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
747                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
748            activity = _activity;
749            extras = _extras;
750            intent = _intent;
751            hint = _hint;
752            receiver = _receiver;
753            receiverExtras = _receiverExtras;
754            userHandle = _userHandle;
755        }
756
757        @Override
758        public void run() {
759            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
760            synchronized (this) {
761                haveResult = true;
762                notifyAll();
763            }
764            pendingAssistExtrasTimedOut(this);
765        }
766    }
767
768    final ArrayList<PendingAssistExtras> mPendingAssistExtras
769            = new ArrayList<PendingAssistExtras>();
770
771    /**
772     * Process management.
773     */
774    final ProcessList mProcessList = new ProcessList();
775
776    /**
777     * All of the applications we currently have running organized by name.
778     * The keys are strings of the application package name (as
779     * returned by the package manager), and the keys are ApplicationRecord
780     * objects.
781     */
782    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
783
784    /**
785     * Tracking long-term execution of processes to look for abuse and other
786     * bad app behavior.
787     */
788    final ProcessStatsService mProcessStats;
789
790    /**
791     * The currently running isolated processes.
792     */
793    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
794
795    /**
796     * Counter for assigning isolated process uids, to avoid frequently reusing the
797     * same ones.
798     */
799    int mNextIsolatedProcessUid = 0;
800
801    /**
802     * The currently running heavy-weight process, if any.
803     */
804    ProcessRecord mHeavyWeightProcess = null;
805
806    /**
807     * Non-persistent appId whitelist for background restrictions
808     */
809    int[] mBackgroundAppIdWhitelist = new int[] {
810            BLUETOOTH_UID
811    };
812
813    /**
814     * Broadcast actions that will always be deliverable to unlaunched/background apps
815     */
816    ArraySet<String> mBackgroundLaunchBroadcasts;
817
818    /**
819     * All of the processes we currently have running organized by pid.
820     * The keys are the pid running the application.
821     *
822     * <p>NOTE: This object is protected by its own lock, NOT the global
823     * activity manager lock!
824     */
825    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
826
827    /**
828     * All of the processes that have been forced to be important.  The key
829     * is the pid of the caller who requested it (we hold a death
830     * link on it).
831     */
832    abstract class ImportanceToken implements IBinder.DeathRecipient {
833        final int pid;
834        final IBinder token;
835        final String reason;
836
837        ImportanceToken(int _pid, IBinder _token, String _reason) {
838            pid = _pid;
839            token = _token;
840            reason = _reason;
841        }
842
843        @Override
844        public String toString() {
845            return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
846                    + " " + reason + " " + pid + " " + token + " }";
847        }
848    }
849    final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
850
851    /**
852     * List of records for processes that someone had tried to start before the
853     * system was ready.  We don't start them at that point, but ensure they
854     * are started by the time booting is complete.
855     */
856    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
857
858    /**
859     * List of persistent applications that are in the process
860     * of being started.
861     */
862    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
863
864    /**
865     * Processes that are being forcibly torn down.
866     */
867    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
868
869    /**
870     * List of running applications, sorted by recent usage.
871     * The first entry in the list is the least recently used.
872     */
873    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
874
875    /**
876     * Where in mLruProcesses that the processes hosting activities start.
877     */
878    int mLruProcessActivityStart = 0;
879
880    /**
881     * Where in mLruProcesses that the processes hosting services start.
882     * This is after (lower index) than mLruProcessesActivityStart.
883     */
884    int mLruProcessServiceStart = 0;
885
886    /**
887     * List of processes that should gc as soon as things are idle.
888     */
889    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
890
891    /**
892     * Processes we want to collect PSS data from.
893     */
894    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
895
896    private boolean mBinderTransactionTrackingEnabled = false;
897
898    /**
899     * Last time we requested PSS data of all processes.
900     */
901    long mLastFullPssTime = SystemClock.uptimeMillis();
902
903    /**
904     * If set, the next time we collect PSS data we should do a full collection
905     * with data from native processes and the kernel.
906     */
907    boolean mFullPssPending = false;
908
909    /**
910     * This is the process holding what we currently consider to be
911     * the "home" activity.
912     */
913    ProcessRecord mHomeProcess;
914
915    /**
916     * This is the process holding the activity the user last visited that
917     * is in a different process from the one they are currently in.
918     */
919    ProcessRecord mPreviousProcess;
920
921    /**
922     * The time at which the previous process was last visible.
923     */
924    long mPreviousProcessVisibleTime;
925
926    /**
927     * Track all uids that have actively running processes.
928     */
929    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
930
931    /**
932     * This is for verifying the UID report flow.
933     */
934    static final boolean VALIDATE_UID_STATES = true;
935    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
936
937    /**
938     * Packages that the user has asked to have run in screen size
939     * compatibility mode instead of filling the screen.
940     */
941    final CompatModePackages mCompatModePackages;
942
943    /**
944     * Set of IntentSenderRecord objects that are currently active.
945     */
946    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
947            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
948
949    /**
950     * Fingerprints (hashCode()) of stack traces that we've
951     * already logged DropBox entries for.  Guarded by itself.  If
952     * something (rogue user app) forces this over
953     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
954     */
955    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
956    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
957
958    /**
959     * Strict Mode background batched logging state.
960     *
961     * The string buffer is guarded by itself, and its lock is also
962     * used to determine if another batched write is already
963     * in-flight.
964     */
965    private final StringBuilder mStrictModeBuffer = new StringBuilder();
966
967    /**
968     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
969     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
970     */
971    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
972
973    /**
974     * Resolver for broadcast intents to registered receivers.
975     * Holds BroadcastFilter (subclass of IntentFilter).
976     */
977    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
978            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
979        @Override
980        protected boolean allowFilterResult(
981                BroadcastFilter filter, List<BroadcastFilter> dest) {
982            IBinder target = filter.receiverList.receiver.asBinder();
983            for (int i = dest.size() - 1; i >= 0; i--) {
984                if (dest.get(i).receiverList.receiver.asBinder() == target) {
985                    return false;
986                }
987            }
988            return true;
989        }
990
991        @Override
992        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
993            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
994                    || userId == filter.owningUserId) {
995                return super.newResult(filter, match, userId);
996            }
997            return null;
998        }
999
1000        @Override
1001        protected BroadcastFilter[] newArray(int size) {
1002            return new BroadcastFilter[size];
1003        }
1004
1005        @Override
1006        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1007            return packageName.equals(filter.packageName);
1008        }
1009    };
1010
1011    /**
1012     * State of all active sticky broadcasts per user.  Keys are the action of the
1013     * sticky Intent, values are an ArrayList of all broadcasted intents with
1014     * that action (which should usually be one).  The SparseArray is keyed
1015     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1016     * for stickies that are sent to all users.
1017     */
1018    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1019            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1020
1021    final ActiveServices mServices;
1022
1023    final static class Association {
1024        final int mSourceUid;
1025        final String mSourceProcess;
1026        final int mTargetUid;
1027        final ComponentName mTargetComponent;
1028        final String mTargetProcess;
1029
1030        int mCount;
1031        long mTime;
1032
1033        int mNesting;
1034        long mStartTime;
1035
1036        // states of the source process when the bind occurred.
1037        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1038        long mLastStateUptime;
1039        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1040                - ActivityManager.MIN_PROCESS_STATE+1];
1041
1042        Association(int sourceUid, String sourceProcess, int targetUid,
1043                ComponentName targetComponent, String targetProcess) {
1044            mSourceUid = sourceUid;
1045            mSourceProcess = sourceProcess;
1046            mTargetUid = targetUid;
1047            mTargetComponent = targetComponent;
1048            mTargetProcess = targetProcess;
1049        }
1050    }
1051
1052    /**
1053     * When service association tracking is enabled, this is all of the associations we
1054     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1055     * -> association data.
1056     */
1057    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1058            mAssociations = new SparseArray<>();
1059    boolean mTrackingAssociations;
1060
1061    /**
1062     * Backup/restore process management
1063     */
1064    String mBackupAppName = null;
1065    BackupRecord mBackupTarget = null;
1066
1067    final ProviderMap mProviderMap;
1068
1069    /**
1070     * List of content providers who have clients waiting for them.  The
1071     * application is currently being launched and the provider will be
1072     * removed from this list once it is published.
1073     */
1074    final ArrayList<ContentProviderRecord> mLaunchingProviders
1075            = new ArrayList<ContentProviderRecord>();
1076
1077    /**
1078     * File storing persisted {@link #mGrantedUriPermissions}.
1079     */
1080    private final AtomicFile mGrantFile;
1081
1082    /** XML constants used in {@link #mGrantFile} */
1083    private static final String TAG_URI_GRANTS = "uri-grants";
1084    private static final String TAG_URI_GRANT = "uri-grant";
1085    private static final String ATTR_USER_HANDLE = "userHandle";
1086    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1087    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1088    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1089    private static final String ATTR_TARGET_PKG = "targetPkg";
1090    private static final String ATTR_URI = "uri";
1091    private static final String ATTR_MODE_FLAGS = "modeFlags";
1092    private static final String ATTR_CREATED_TIME = "createdTime";
1093    private static final String ATTR_PREFIX = "prefix";
1094
1095    /**
1096     * Global set of specific {@link Uri} permissions that have been granted.
1097     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1098     * to {@link UriPermission#uri} to {@link UriPermission}.
1099     */
1100    @GuardedBy("this")
1101    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1102            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1103
1104    public static class GrantUri {
1105        public final int sourceUserId;
1106        public final Uri uri;
1107        public boolean prefix;
1108
1109        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1110            this.sourceUserId = sourceUserId;
1111            this.uri = uri;
1112            this.prefix = prefix;
1113        }
1114
1115        @Override
1116        public int hashCode() {
1117            int hashCode = 1;
1118            hashCode = 31 * hashCode + sourceUserId;
1119            hashCode = 31 * hashCode + uri.hashCode();
1120            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1121            return hashCode;
1122        }
1123
1124        @Override
1125        public boolean equals(Object o) {
1126            if (o instanceof GrantUri) {
1127                GrantUri other = (GrantUri) o;
1128                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1129                        && prefix == other.prefix;
1130            }
1131            return false;
1132        }
1133
1134        @Override
1135        public String toString() {
1136            String result = uri.toString() + " [user " + sourceUserId + "]";
1137            if (prefix) result += " [prefix]";
1138            return result;
1139        }
1140
1141        public String toSafeString() {
1142            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1143            if (prefix) result += " [prefix]";
1144            return result;
1145        }
1146
1147        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1148            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1149                    ContentProvider.getUriWithoutUserId(uri), false);
1150        }
1151    }
1152
1153    CoreSettingsObserver mCoreSettingsObserver;
1154
1155    FontScaleSettingObserver mFontScaleSettingObserver;
1156
1157    private final class FontScaleSettingObserver extends ContentObserver {
1158        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1159
1160        public FontScaleSettingObserver() {
1161            super(mHandler);
1162            ContentResolver resolver = mContext.getContentResolver();
1163            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1164        }
1165
1166        @Override
1167        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1168            if (mFontScaleUri.equals(uri)) {
1169                updateFontScaleIfNeeded(userId);
1170            }
1171        }
1172    }
1173
1174    /**
1175     * Thread-local storage used to carry caller permissions over through
1176     * indirect content-provider access.
1177     */
1178    private class Identity {
1179        public final IBinder token;
1180        public final int pid;
1181        public final int uid;
1182
1183        Identity(IBinder _token, int _pid, int _uid) {
1184            token = _token;
1185            pid = _pid;
1186            uid = _uid;
1187        }
1188    }
1189
1190    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1191
1192    /**
1193     * All information we have collected about the runtime performance of
1194     * any user id that can impact battery performance.
1195     */
1196    final BatteryStatsService mBatteryStatsService;
1197
1198    /**
1199     * Information about component usage
1200     */
1201    UsageStatsManagerInternal mUsageStatsService;
1202
1203    /**
1204     * Access to DeviceIdleController service.
1205     */
1206    DeviceIdleController.LocalService mLocalDeviceIdleController;
1207
1208    /**
1209     * Set of app ids that are whitelisted for device idle and thus background check.
1210     */
1211    int[] mDeviceIdleWhitelist = new int[0];
1212
1213    /**
1214     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1215     */
1216    int[] mDeviceIdleTempWhitelist = new int[0];
1217
1218    static final class PendingTempWhitelist {
1219        final int targetUid;
1220        final long duration;
1221        final String tag;
1222
1223        PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1224            targetUid = _targetUid;
1225            duration = _duration;
1226            tag = _tag;
1227        }
1228    }
1229
1230    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1231
1232    /**
1233     * Information about and control over application operations
1234     */
1235    final AppOpsService mAppOpsService;
1236
1237    /** Current sequencing integer of the configuration, for skipping old configurations. */
1238    private int mConfigurationSeq;
1239
1240    /**
1241     * Temp object used when global and/or display override configuration is updated. It is also
1242     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1243     * anyone...
1244     */
1245    private Configuration mTempConfig = new Configuration();
1246
1247    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1248            new UpdateConfigurationResult();
1249    private static final class UpdateConfigurationResult {
1250        // Configuration changes that were updated.
1251        int changes;
1252        // If the activity was relaunched to match the new configuration.
1253        boolean activityRelaunched;
1254
1255        void reset() {
1256            changes = 0;
1257            activityRelaunched = false;
1258        }
1259    }
1260
1261    boolean mSuppressResizeConfigChanges;
1262
1263    /**
1264     * Hardware-reported OpenGLES version.
1265     */
1266    final int GL_ES_VERSION;
1267
1268    /**
1269     * List of initialization arguments to pass to all processes when binding applications to them.
1270     * For example, references to the commonly used services.
1271     */
1272    HashMap<String, IBinder> mAppBindArgs;
1273    HashMap<String, IBinder> mIsolatedAppBindArgs;
1274
1275    /**
1276     * Temporary to avoid allocations.  Protected by main lock.
1277     */
1278    final StringBuilder mStringBuilder = new StringBuilder(256);
1279
1280    /**
1281     * Used to control how we initialize the service.
1282     */
1283    ComponentName mTopComponent;
1284    String mTopAction = Intent.ACTION_MAIN;
1285    String mTopData;
1286
1287    volatile boolean mProcessesReady = false;
1288    volatile boolean mSystemReady = false;
1289    volatile boolean mOnBattery = false;
1290    volatile int mFactoryTest;
1291
1292    @GuardedBy("this") boolean mBooting = false;
1293    @GuardedBy("this") boolean mCallFinishBooting = false;
1294    @GuardedBy("this") boolean mBootAnimationComplete = false;
1295    @GuardedBy("this") boolean mLaunchWarningShown = false;
1296    @GuardedBy("this") boolean mCheckedForSetup = false;
1297
1298    final Context mContext;
1299
1300    /**
1301     * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1302     * change at runtime. Use mContext for non-UI purposes.
1303     */
1304    final Context mUiContext;
1305
1306    /**
1307     * The time at which we will allow normal application switches again,
1308     * after a call to {@link #stopAppSwitches()}.
1309     */
1310    long mAppSwitchesAllowedTime;
1311
1312    /**
1313     * This is set to true after the first switch after mAppSwitchesAllowedTime
1314     * is set; any switches after that will clear the time.
1315     */
1316    boolean mDidAppSwitch;
1317
1318    /**
1319     * Last time (in uptime) at which we checked for power usage.
1320     */
1321    long mLastPowerCheckUptime;
1322
1323    /**
1324     * Set while we are wanting to sleep, to prevent any
1325     * activities from being started/resumed.
1326     *
1327     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1328     *
1329     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1330     * while in the sleep state until there is a pending transition out of sleep, in which case
1331     * mSleeping is set to false, and remains false while awake.
1332     *
1333     * Whether mSleeping can quickly toggled between true/false without the device actually
1334     * display changing states is undefined.
1335     */
1336    private boolean mSleeping = false;
1337
1338    /**
1339     * The process state used for processes that are running the top activities.
1340     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1341     */
1342    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1343
1344    /**
1345     * Set while we are running a voice interaction.  This overrides
1346     * sleeping while it is active.
1347     */
1348    IVoiceInteractionSession mRunningVoice;
1349
1350    /**
1351     * For some direct access we need to power manager.
1352     */
1353    PowerManagerInternal mLocalPowerManager;
1354
1355    /**
1356     * We want to hold a wake lock while running a voice interaction session, since
1357     * this may happen with the screen off and we need to keep the CPU running to
1358     * be able to continue to interact with the user.
1359     */
1360    PowerManager.WakeLock mVoiceWakeLock;
1361
1362    /**
1363     * State of external calls telling us if the device is awake or asleep.
1364     */
1365    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1366
1367    /**
1368     * Set if we are shutting down the system, similar to sleeping.
1369     */
1370    boolean mShuttingDown = false;
1371
1372    /**
1373     * Current sequence id for oom_adj computation traversal.
1374     */
1375    int mAdjSeq = 0;
1376
1377    /**
1378     * Current sequence id for process LRU updating.
1379     */
1380    int mLruSeq = 0;
1381
1382    /**
1383     * Keep track of the non-cached/empty process we last found, to help
1384     * determine how to distribute cached/empty processes next time.
1385     */
1386    int mNumNonCachedProcs = 0;
1387
1388    /**
1389     * Keep track of the number of cached hidden procs, to balance oom adj
1390     * distribution between those and empty procs.
1391     */
1392    int mNumCachedHiddenProcs = 0;
1393
1394    /**
1395     * Keep track of the number of service processes we last found, to
1396     * determine on the next iteration which should be B services.
1397     */
1398    int mNumServiceProcs = 0;
1399    int mNewNumAServiceProcs = 0;
1400    int mNewNumServiceProcs = 0;
1401
1402    /**
1403     * Allow the current computed overall memory level of the system to go down?
1404     * This is set to false when we are killing processes for reasons other than
1405     * memory management, so that the now smaller process list will not be taken as
1406     * an indication that memory is tighter.
1407     */
1408    boolean mAllowLowerMemLevel = false;
1409
1410    /**
1411     * The last computed memory level, for holding when we are in a state that
1412     * processes are going away for other reasons.
1413     */
1414    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1415
1416    /**
1417     * The last total number of process we have, to determine if changes actually look
1418     * like a shrinking number of process due to lower RAM.
1419     */
1420    int mLastNumProcesses;
1421
1422    /**
1423     * The uptime of the last time we performed idle maintenance.
1424     */
1425    long mLastIdleTime = SystemClock.uptimeMillis();
1426
1427    /**
1428     * Total time spent with RAM that has been added in the past since the last idle time.
1429     */
1430    long mLowRamTimeSinceLastIdle = 0;
1431
1432    /**
1433     * If RAM is currently low, when that horrible situation started.
1434     */
1435    long mLowRamStartTime = 0;
1436
1437    /**
1438     * For reporting to battery stats the current top application.
1439     */
1440    private String mCurResumedPackage = null;
1441    private int mCurResumedUid = -1;
1442
1443    /**
1444     * For reporting to battery stats the apps currently running foreground
1445     * service.  The ProcessMap is package/uid tuples; each of these contain
1446     * an array of the currently foreground processes.
1447     */
1448    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1449            = new ProcessMap<ArrayList<ProcessRecord>>();
1450
1451    /**
1452     * Set if the systemServer made a call to enterSafeMode.
1453     */
1454    boolean mSafeMode;
1455
1456    /**
1457     * If true, we are running under a test environment so will sample PSS from processes
1458     * much more rapidly to try to collect better data when the tests are rapidly
1459     * running through apps.
1460     */
1461    boolean mTestPssMode = false;
1462
1463    String mDebugApp = null;
1464    boolean mWaitForDebugger = false;
1465    boolean mDebugTransient = false;
1466    String mOrigDebugApp = null;
1467    boolean mOrigWaitForDebugger = false;
1468    boolean mAlwaysFinishActivities = false;
1469    boolean mForceResizableActivities;
1470    /**
1471     * Flag that indicates if multi-window is enabled.
1472     *
1473     * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1474     * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1475     * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1476     * At least one of the forms of multi-window must be enabled in order for this flag to be
1477     * initialized to 'true'.
1478     *
1479     * @see #mSupportsSplitScreenMultiWindow
1480     * @see #mSupportsFreeformWindowManagement
1481     * @see #mSupportsPictureInPicture
1482     * @see #mSupportsMultiDisplay
1483     */
1484    boolean mSupportsMultiWindow;
1485    boolean mSupportsSplitScreenMultiWindow;
1486    boolean mSupportsFreeformWindowManagement;
1487    boolean mSupportsPictureInPicture;
1488    boolean mSupportsMultiDisplay;
1489    boolean mSupportsLeanbackOnly;
1490    IActivityController mController = null;
1491    boolean mControllerIsAMonkey = false;
1492    String mProfileApp = null;
1493    ProcessRecord mProfileProc = null;
1494    ProfilerInfo mProfilerInfo = null;
1495    int mProfileType = 0;
1496    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1497    String mMemWatchDumpProcName;
1498    String mMemWatchDumpFile;
1499    int mMemWatchDumpPid;
1500    int mMemWatchDumpUid;
1501    String mTrackAllocationApp = null;
1502    String mNativeDebuggingApp = null;
1503
1504    final long[] mTmpLong = new long[2];
1505
1506    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1507
1508    /**
1509     * A global counter for generating sequence numbers.
1510     * This value will be used when incrementing sequence numbers in individual uidRecords.
1511     *
1512     * Having a global counter ensures that seq numbers are monotonically increasing for a
1513     * particular uid even when the uidRecord is re-created.
1514     */
1515    @GuardedBy("this")
1516    @VisibleForTesting
1517    long mProcStateSeqCounter = 0;
1518
1519    private final Injector mInjector;
1520
1521    static final class ProcessChangeItem {
1522        static final int CHANGE_ACTIVITIES = 1<<0;
1523        int changes;
1524        int uid;
1525        int pid;
1526        int processState;
1527        boolean foregroundActivities;
1528    }
1529
1530    static final class UidObserverRegistration {
1531        final int uid;
1532        final String pkg;
1533        final int which;
1534        final int cutpoint;
1535
1536        final SparseIntArray lastProcStates;
1537
1538        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1539            uid = _uid;
1540            pkg = _pkg;
1541            which = _which;
1542            cutpoint = _cutpoint;
1543            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1544                lastProcStates = new SparseIntArray();
1545            } else {
1546                lastProcStates = null;
1547            }
1548        }
1549    }
1550
1551    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1552    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1553
1554    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1555    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1556
1557    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1558    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1559
1560    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1561    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1562
1563    OomAdjObserver mCurOomAdjObserver;
1564    int mCurOomAdjUid;
1565
1566    interface OomAdjObserver {
1567        void onOomAdjMessage(String msg);
1568    }
1569
1570    /**
1571     * Runtime CPU use collection thread.  This object's lock is used to
1572     * perform synchronization with the thread (notifying it to run).
1573     */
1574    final Thread mProcessCpuThread;
1575
1576    /**
1577     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1578     * Must acquire this object's lock when accessing it.
1579     * NOTE: this lock will be held while doing long operations (trawling
1580     * through all processes in /proc), so it should never be acquired by
1581     * any critical paths such as when holding the main activity manager lock.
1582     */
1583    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1584            MONITOR_THREAD_CPU_USAGE);
1585    final AtomicLong mLastCpuTime = new AtomicLong(0);
1586    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1587    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1588
1589    long mLastWriteTime = 0;
1590
1591    /**
1592     * Used to retain an update lock when the foreground activity is in
1593     * immersive mode.
1594     */
1595    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1596
1597    /**
1598     * Set to true after the system has finished booting.
1599     */
1600    boolean mBooted = false;
1601
1602    WindowManagerService mWindowManager;
1603    final ActivityThread mSystemThread;
1604
1605    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1606        final ProcessRecord mApp;
1607        final int mPid;
1608        final IApplicationThread mAppThread;
1609
1610        AppDeathRecipient(ProcessRecord app, int pid,
1611                IApplicationThread thread) {
1612            if (DEBUG_ALL) Slog.v(
1613                TAG, "New death recipient " + this
1614                + " for thread " + thread.asBinder());
1615            mApp = app;
1616            mPid = pid;
1617            mAppThread = thread;
1618        }
1619
1620        @Override
1621        public void binderDied() {
1622            if (DEBUG_ALL) Slog.v(
1623                TAG, "Death received in " + this
1624                + " for thread " + mAppThread.asBinder());
1625            synchronized(ActivityManagerService.this) {
1626                appDiedLocked(mApp, mPid, mAppThread, true);
1627            }
1628        }
1629    }
1630
1631    static final int SHOW_ERROR_UI_MSG = 1;
1632    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1633    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1634    static final int UPDATE_CONFIGURATION_MSG = 4;
1635    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1636    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1637    static final int SERVICE_TIMEOUT_MSG = 12;
1638    static final int UPDATE_TIME_ZONE = 13;
1639    static final int SHOW_UID_ERROR_UI_MSG = 14;
1640    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1641    static final int PROC_START_TIMEOUT_MSG = 20;
1642    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1643    static final int KILL_APPLICATION_MSG = 22;
1644    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1645    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1646    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1647    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1648    static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1649    static final int CLEAR_DNS_CACHE_MSG = 28;
1650    static final int UPDATE_HTTP_PROXY_MSG = 29;
1651    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1652    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1653    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1654    static final int REPORT_MEM_USAGE_MSG = 33;
1655    static final int REPORT_USER_SWITCH_MSG = 34;
1656    static final int CONTINUE_USER_SWITCH_MSG = 35;
1657    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1658    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1659    static final int PERSIST_URI_GRANTS_MSG = 38;
1660    static final int REQUEST_ALL_PSS_MSG = 39;
1661    static final int START_PROFILES_MSG = 40;
1662    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1663    static final int SYSTEM_USER_START_MSG = 42;
1664    static final int SYSTEM_USER_CURRENT_MSG = 43;
1665    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1666    static final int FINISH_BOOTING_MSG = 45;
1667    static final int START_USER_SWITCH_UI_MSG = 46;
1668    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1669    static final int DISMISS_DIALOG_UI_MSG = 48;
1670    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1671    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1672    static final int DELETE_DUMPHEAP_MSG = 51;
1673    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1674    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1675    static final int REPORT_TIME_TRACKER_MSG = 54;
1676    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1677    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1678    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1679    static final int IDLE_UIDS_MSG = 58;
1680    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1681    static final int LOG_STACK_STATE = 60;
1682    static final int VR_MODE_CHANGE_MSG = 61;
1683    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1684    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1685    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1686    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1687    static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1688    static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1689    static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1690    static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1691    static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1692    static final int START_USER_SWITCH_FG_MSG = 712;
1693
1694    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1695    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1696    static final int FIRST_COMPAT_MODE_MSG = 300;
1697    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1698
1699    static ServiceThread sKillThread = null;
1700    static KillHandler sKillHandler = null;
1701
1702    CompatModeDialog mCompatModeDialog;
1703    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1704    long mLastMemUsageReportTime = 0;
1705
1706    /**
1707     * Flag whether the current user is a "monkey", i.e. whether
1708     * the UI is driven by a UI automation tool.
1709     */
1710    private boolean mUserIsMonkey;
1711
1712    /** Flag whether the device has a Recents UI */
1713    boolean mHasRecents;
1714
1715    /** The dimensions of the thumbnails in the Recents UI. */
1716    int mThumbnailWidth;
1717    int mThumbnailHeight;
1718    float mFullscreenThumbnailScale;
1719
1720    final ServiceThread mHandlerThread;
1721    final MainHandler mHandler;
1722    final Handler mUiHandler;
1723
1724    final ActivityManagerConstants mConstants;
1725
1726    PackageManagerInternal mPackageManagerInt;
1727
1728    // VoiceInteraction session ID that changes for each new request except when
1729    // being called for multiwindow assist in a single session.
1730    private int mViSessionId = 1000;
1731
1732    final boolean mPermissionReviewRequired;
1733
1734    private static String sTheRealBuildSerial = Build.UNKNOWN;
1735
1736    /**
1737     * Current global configuration information. Contains general settings for the entire system,
1738     * also corresponds to the merged configuration of the default display.
1739     */
1740    Configuration getGlobalConfiguration() {
1741        return mStackSupervisor.getConfiguration();
1742    }
1743
1744    final class KillHandler extends Handler {
1745        static final int KILL_PROCESS_GROUP_MSG = 4000;
1746
1747        public KillHandler(Looper looper) {
1748            super(looper, null, true);
1749        }
1750
1751        @Override
1752        public void handleMessage(Message msg) {
1753            switch (msg.what) {
1754                case KILL_PROCESS_GROUP_MSG:
1755                {
1756                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1757                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1758                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1759                }
1760                break;
1761
1762                default:
1763                    super.handleMessage(msg);
1764            }
1765        }
1766    }
1767
1768    final class UiHandler extends Handler {
1769        public UiHandler() {
1770            super(com.android.server.UiThread.get().getLooper(), null, true);
1771        }
1772
1773        @Override
1774        public void handleMessage(Message msg) {
1775            switch (msg.what) {
1776            case SHOW_ERROR_UI_MSG: {
1777                mAppErrors.handleShowAppErrorUi(msg);
1778                ensureBootCompleted();
1779            } break;
1780            case SHOW_NOT_RESPONDING_UI_MSG: {
1781                mAppErrors.handleShowAnrUi(msg);
1782                ensureBootCompleted();
1783            } break;
1784            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1785                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1786                synchronized (ActivityManagerService.this) {
1787                    ProcessRecord proc = (ProcessRecord) data.get("app");
1788                    if (proc == null) {
1789                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1790                        break;
1791                    }
1792                    if (proc.crashDialog != null) {
1793                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1794                        return;
1795                    }
1796                    AppErrorResult res = (AppErrorResult) data.get("result");
1797                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1798                        Dialog d = new StrictModeViolationDialog(mUiContext,
1799                                ActivityManagerService.this, res, proc);
1800                        d.show();
1801                        proc.crashDialog = d;
1802                    } else {
1803                        // The device is asleep, so just pretend that the user
1804                        // saw a crash dialog and hit "force quit".
1805                        res.set(0);
1806                    }
1807                }
1808                ensureBootCompleted();
1809            } break;
1810            case SHOW_FACTORY_ERROR_UI_MSG: {
1811                Dialog d = new FactoryErrorDialog(
1812                        mUiContext, msg.getData().getCharSequence("msg"));
1813                d.show();
1814                ensureBootCompleted();
1815            } break;
1816            case WAIT_FOR_DEBUGGER_UI_MSG: {
1817                synchronized (ActivityManagerService.this) {
1818                    ProcessRecord app = (ProcessRecord)msg.obj;
1819                    if (msg.arg1 != 0) {
1820                        if (!app.waitedForDebugger) {
1821                            Dialog d = new AppWaitingForDebuggerDialog(
1822                                    ActivityManagerService.this,
1823                                    mUiContext, app);
1824                            app.waitDialog = d;
1825                            app.waitedForDebugger = true;
1826                            d.show();
1827                        }
1828                    } else {
1829                        if (app.waitDialog != null) {
1830                            app.waitDialog.dismiss();
1831                            app.waitDialog = null;
1832                        }
1833                    }
1834                }
1835            } break;
1836            case SHOW_UID_ERROR_UI_MSG: {
1837                if (mShowDialogs) {
1838                    AlertDialog d = new BaseErrorDialog(mUiContext);
1839                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1840                    d.setCancelable(false);
1841                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1842                    d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1843                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1844                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1845                    d.show();
1846                }
1847            } break;
1848            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1849                if (mShowDialogs) {
1850                    AlertDialog d = new BaseErrorDialog(mUiContext);
1851                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1852                    d.setCancelable(false);
1853                    d.setTitle(mUiContext.getText(R.string.android_system_label));
1854                    d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1855                    d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1856                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1857                    d.show();
1858                }
1859            } break;
1860            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1861                synchronized (ActivityManagerService.this) {
1862                    ActivityRecord ar = (ActivityRecord) msg.obj;
1863                    if (mCompatModeDialog != null) {
1864                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1865                                ar.info.applicationInfo.packageName)) {
1866                            return;
1867                        }
1868                        mCompatModeDialog.dismiss();
1869                        mCompatModeDialog = null;
1870                    }
1871                    if (ar != null && false) {
1872                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1873                                ar.packageName)) {
1874                            int mode = mCompatModePackages.computeCompatModeLocked(
1875                                    ar.info.applicationInfo);
1876                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1877                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1878                                mCompatModeDialog = new CompatModeDialog(
1879                                        ActivityManagerService.this, mUiContext,
1880                                        ar.info.applicationInfo);
1881                                mCompatModeDialog.show();
1882                            }
1883                        }
1884                    }
1885                }
1886                break;
1887            }
1888            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1889                synchronized (ActivityManagerService.this) {
1890                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1891                    if (mUnsupportedDisplaySizeDialog != null) {
1892                        mUnsupportedDisplaySizeDialog.dismiss();
1893                        mUnsupportedDisplaySizeDialog = null;
1894                    }
1895                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1896                            ar.packageName)) {
1897                        // TODO(multi-display): Show dialog on appropriate display.
1898                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1899                                ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1900                        mUnsupportedDisplaySizeDialog.show();
1901                    }
1902                }
1903                break;
1904            }
1905            case START_USER_SWITCH_UI_MSG: {
1906                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1907                break;
1908            }
1909            case DISMISS_DIALOG_UI_MSG: {
1910                final Dialog d = (Dialog) msg.obj;
1911                d.dismiss();
1912                break;
1913            }
1914            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1915                dispatchProcessesChanged();
1916                break;
1917            }
1918            case DISPATCH_PROCESS_DIED_UI_MSG: {
1919                final int pid = msg.arg1;
1920                final int uid = msg.arg2;
1921                dispatchProcessDied(pid, uid);
1922                break;
1923            }
1924            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1925                dispatchUidsChanged();
1926            } break;
1927            case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1928                dispatchOomAdjObserver((String)msg.obj);
1929            } break;
1930            case PUSH_TEMP_WHITELIST_UI_MSG: {
1931                pushTempWhitelist();
1932            } break;
1933            }
1934        }
1935    }
1936
1937    final class MainHandler extends Handler {
1938        public MainHandler(Looper looper) {
1939            super(looper, null, true);
1940        }
1941
1942        @Override
1943        public void handleMessage(Message msg) {
1944            switch (msg.what) {
1945            case UPDATE_CONFIGURATION_MSG: {
1946                final ContentResolver resolver = mContext.getContentResolver();
1947                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1948                        msg.arg1);
1949            } break;
1950            case GC_BACKGROUND_PROCESSES_MSG: {
1951                synchronized (ActivityManagerService.this) {
1952                    performAppGcsIfAppropriateLocked();
1953                }
1954            } break;
1955            case SERVICE_TIMEOUT_MSG: {
1956                mServices.serviceTimeout((ProcessRecord)msg.obj);
1957            } break;
1958            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1959                mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1960            } break;
1961            case SERVICE_FOREGROUND_CRASH_MSG: {
1962                mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1963            } break;
1964            case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1965                RemoteCallbackList<IResultReceiver> callbacks
1966                        = (RemoteCallbackList<IResultReceiver>)msg.obj;
1967                int N = callbacks.beginBroadcast();
1968                for (int i = 0; i < N; i++) {
1969                    try {
1970                        callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1971                    } catch (RemoteException e) {
1972                    }
1973                }
1974                callbacks.finishBroadcast();
1975            } break;
1976            case UPDATE_TIME_ZONE: {
1977                synchronized (ActivityManagerService.this) {
1978                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1979                        ProcessRecord r = mLruProcesses.get(i);
1980                        if (r.thread != null) {
1981                            try {
1982                                r.thread.updateTimeZone();
1983                            } catch (RemoteException ex) {
1984                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1985                            }
1986                        }
1987                    }
1988                }
1989            } break;
1990            case CLEAR_DNS_CACHE_MSG: {
1991                synchronized (ActivityManagerService.this) {
1992                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1993                        ProcessRecord r = mLruProcesses.get(i);
1994                        if (r.thread != null) {
1995                            try {
1996                                r.thread.clearDnsCache();
1997                            } catch (RemoteException ex) {
1998                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1999                            }
2000                        }
2001                    }
2002                }
2003            } break;
2004            case UPDATE_HTTP_PROXY_MSG: {
2005                ProxyInfo proxy = (ProxyInfo)msg.obj;
2006                String host = "";
2007                String port = "";
2008                String exclList = "";
2009                Uri pacFileUrl = Uri.EMPTY;
2010                if (proxy != null) {
2011                    host = proxy.getHost();
2012                    port = Integer.toString(proxy.getPort());
2013                    exclList = proxy.getExclusionListAsString();
2014                    pacFileUrl = proxy.getPacFileUrl();
2015                }
2016                synchronized (ActivityManagerService.this) {
2017                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2018                        ProcessRecord r = mLruProcesses.get(i);
2019                        if (r.thread != null) {
2020                            try {
2021                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2022                            } catch (RemoteException ex) {
2023                                Slog.w(TAG, "Failed to update http proxy for: " +
2024                                        r.info.processName);
2025                            }
2026                        }
2027                    }
2028                }
2029            } break;
2030            case PROC_START_TIMEOUT_MSG: {
2031                ProcessRecord app = (ProcessRecord)msg.obj;
2032                synchronized (ActivityManagerService.this) {
2033                    processStartTimedOutLocked(app);
2034                }
2035            } break;
2036            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2037                ProcessRecord app = (ProcessRecord)msg.obj;
2038                synchronized (ActivityManagerService.this) {
2039                    processContentProviderPublishTimedOutLocked(app);
2040                }
2041            } break;
2042            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2043                synchronized (ActivityManagerService.this) {
2044                    mActivityStarter.doPendingActivityLaunchesLocked(true);
2045                }
2046            } break;
2047            case KILL_APPLICATION_MSG: {
2048                synchronized (ActivityManagerService.this) {
2049                    final int appId = msg.arg1;
2050                    final int userId = msg.arg2;
2051                    Bundle bundle = (Bundle)msg.obj;
2052                    String pkg = bundle.getString("pkg");
2053                    String reason = bundle.getString("reason");
2054                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2055                            false, userId, reason);
2056                }
2057            } break;
2058            case FINALIZE_PENDING_INTENT_MSG: {
2059                ((PendingIntentRecord)msg.obj).completeFinalize();
2060            } break;
2061            case POST_HEAVY_NOTIFICATION_MSG: {
2062                INotificationManager inm = NotificationManager.getService();
2063                if (inm == null) {
2064                    return;
2065                }
2066
2067                ActivityRecord root = (ActivityRecord)msg.obj;
2068                ProcessRecord process = root.app;
2069                if (process == null) {
2070                    return;
2071                }
2072
2073                try {
2074                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2075                    String text = mContext.getString(R.string.heavy_weight_notification,
2076                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2077                    Notification notification =
2078                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2079                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2080                            .setWhen(0)
2081                            .setOngoing(true)
2082                            .setTicker(text)
2083                            .setColor(mContext.getColor(
2084                                    com.android.internal.R.color.system_notification_accent_color))
2085                            .setContentTitle(text)
2086                            .setContentText(
2087                                    mContext.getText(R.string.heavy_weight_notification_detail))
2088                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2089                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2090                                    new UserHandle(root.userId)))
2091                            .build();
2092                    try {
2093                        inm.enqueueNotificationWithTag("android", "android", null,
2094                                SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2095                                notification, root.userId);
2096                    } catch (RuntimeException e) {
2097                        Slog.w(ActivityManagerService.TAG,
2098                                "Error showing notification for heavy-weight app", e);
2099                    } catch (RemoteException e) {
2100                    }
2101                } catch (NameNotFoundException e) {
2102                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2103                }
2104            } break;
2105            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2106                INotificationManager inm = NotificationManager.getService();
2107                if (inm == null) {
2108                    return;
2109                }
2110                try {
2111                    inm.cancelNotificationWithTag("android", null,
2112                            SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2113                } catch (RuntimeException e) {
2114                    Slog.w(ActivityManagerService.TAG,
2115                            "Error canceling notification for service", e);
2116                } catch (RemoteException e) {
2117                }
2118            } break;
2119            case CHECK_EXCESSIVE_POWER_USE_MSG: {
2120                synchronized (ActivityManagerService.this) {
2121                    checkExcessivePowerUsageLocked();
2122                    removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2123                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2124                    sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2125                }
2126            } break;
2127            case REPORT_MEM_USAGE_MSG: {
2128                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2129                Thread thread = new Thread() {
2130                    @Override public void run() {
2131                        reportMemUsage(memInfos);
2132                    }
2133                };
2134                thread.start();
2135                break;
2136            }
2137            case START_USER_SWITCH_FG_MSG: {
2138                mUserController.startUserInForeground(msg.arg1);
2139                break;
2140            }
2141            case REPORT_USER_SWITCH_MSG: {
2142                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2143                break;
2144            }
2145            case CONTINUE_USER_SWITCH_MSG: {
2146                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2147                break;
2148            }
2149            case USER_SWITCH_TIMEOUT_MSG: {
2150                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2151                break;
2152            }
2153            case IMMERSIVE_MODE_LOCK_MSG: {
2154                final boolean nextState = (msg.arg1 != 0);
2155                if (mUpdateLock.isHeld() != nextState) {
2156                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2157                            "Applying new update lock state '" + nextState
2158                            + "' for " + (ActivityRecord)msg.obj);
2159                    if (nextState) {
2160                        mUpdateLock.acquire();
2161                    } else {
2162                        mUpdateLock.release();
2163                    }
2164                }
2165                break;
2166            }
2167            case PERSIST_URI_GRANTS_MSG: {
2168                writeGrantedUriPermissions();
2169                break;
2170            }
2171            case REQUEST_ALL_PSS_MSG: {
2172                synchronized (ActivityManagerService.this) {
2173                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2174                }
2175                break;
2176            }
2177            case START_PROFILES_MSG: {
2178                synchronized (ActivityManagerService.this) {
2179                    mUserController.startProfilesLocked();
2180                }
2181                break;
2182            }
2183            case UPDATE_TIME_PREFERENCE_MSG: {
2184                // The user's time format preference might have changed.
2185                // For convenience we re-use the Intent extra values.
2186                synchronized (ActivityManagerService.this) {
2187                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2188                        ProcessRecord r = mLruProcesses.get(i);
2189                        if (r.thread != null) {
2190                            try {
2191                                r.thread.updateTimePrefs(msg.arg1);
2192                            } catch (RemoteException ex) {
2193                                Slog.w(TAG, "Failed to update preferences for: "
2194                                        + r.info.processName);
2195                            }
2196                        }
2197                    }
2198                }
2199                break;
2200            }
2201            case SYSTEM_USER_START_MSG: {
2202                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2203                        Integer.toString(msg.arg1), msg.arg1);
2204                mSystemServiceManager.startUser(msg.arg1);
2205                break;
2206            }
2207            case SYSTEM_USER_UNLOCK_MSG: {
2208                final int userId = msg.arg1;
2209                mSystemServiceManager.unlockUser(userId);
2210                synchronized (ActivityManagerService.this) {
2211                    mRecentTasks.loadUserRecentsLocked(userId);
2212                }
2213                if (userId == UserHandle.USER_SYSTEM) {
2214                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2215                }
2216                installEncryptionUnawareProviders(userId);
2217                mUserController.finishUserUnlocked((UserState) msg.obj);
2218                break;
2219            }
2220            case SYSTEM_USER_CURRENT_MSG: {
2221                mBatteryStatsService.noteEvent(
2222                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2223                        Integer.toString(msg.arg2), msg.arg2);
2224                mBatteryStatsService.noteEvent(
2225                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2226                        Integer.toString(msg.arg1), msg.arg1);
2227                mSystemServiceManager.switchUser(msg.arg1);
2228                break;
2229            }
2230            case ENTER_ANIMATION_COMPLETE_MSG: {
2231                synchronized (ActivityManagerService.this) {
2232                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2233                    if (r != null && r.app != null && r.app.thread != null) {
2234                        try {
2235                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2236                        } catch (RemoteException e) {
2237                        }
2238                    }
2239                }
2240                break;
2241            }
2242            case FINISH_BOOTING_MSG: {
2243                if (msg.arg1 != 0) {
2244                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2245                    finishBooting();
2246                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2247                }
2248                if (msg.arg2 != 0) {
2249                    enableScreenAfterBoot();
2250                }
2251                break;
2252            }
2253            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2254                try {
2255                    Locale l = (Locale) msg.obj;
2256                    IBinder service = ServiceManager.getService("mount");
2257                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2258                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2259                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2260                } catch (RemoteException e) {
2261                    Log.e(TAG, "Error storing locale for decryption UI", e);
2262                }
2263                break;
2264            }
2265            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2266                final int uid = msg.arg1;
2267                final byte[] firstPacket = (byte[]) msg.obj;
2268
2269                synchronized (mPidsSelfLocked) {
2270                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2271                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2272                        if (p.uid == uid) {
2273                            try {
2274                                p.thread.notifyCleartextNetwork(firstPacket);
2275                            } catch (RemoteException ignored) {
2276                            }
2277                        }
2278                    }
2279                }
2280                break;
2281            }
2282            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2283                final String procName;
2284                final int uid;
2285                final long memLimit;
2286                final String reportPackage;
2287                synchronized (ActivityManagerService.this) {
2288                    procName = mMemWatchDumpProcName;
2289                    uid = mMemWatchDumpUid;
2290                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2291                    if (val == null) {
2292                        val = mMemWatchProcesses.get(procName, 0);
2293                    }
2294                    if (val != null) {
2295                        memLimit = val.first;
2296                        reportPackage = val.second;
2297                    } else {
2298                        memLimit = 0;
2299                        reportPackage = null;
2300                    }
2301                }
2302                if (procName == null) {
2303                    return;
2304                }
2305
2306                if (DEBUG_PSS) Slog.d(TAG_PSS,
2307                        "Showing dump heap notification from " + procName + "/" + uid);
2308
2309                INotificationManager inm = NotificationManager.getService();
2310                if (inm == null) {
2311                    return;
2312                }
2313
2314                String text = mContext.getString(R.string.dump_heap_notification, procName);
2315
2316
2317                Intent deleteIntent = new Intent();
2318                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2319                Intent intent = new Intent();
2320                intent.setClassName("android", DumpHeapActivity.class.getName());
2321                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2322                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2323                if (reportPackage != null) {
2324                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2325                }
2326                int userId = UserHandle.getUserId(uid);
2327                Notification notification =
2328                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2329                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2330                        .setWhen(0)
2331                        .setOngoing(true)
2332                        .setAutoCancel(true)
2333                        .setTicker(text)
2334                        .setColor(mContext.getColor(
2335                                com.android.internal.R.color.system_notification_accent_color))
2336                        .setContentTitle(text)
2337                        .setContentText(
2338                                mContext.getText(R.string.dump_heap_notification_detail))
2339                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2340                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2341                                new UserHandle(userId)))
2342                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2343                                deleteIntent, 0, UserHandle.SYSTEM))
2344                        .build();
2345
2346                try {
2347                    inm.enqueueNotificationWithTag("android", "android", null,
2348                            SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2349                            notification, userId);
2350                } catch (RuntimeException e) {
2351                    Slog.w(ActivityManagerService.TAG,
2352                            "Error showing notification for dump heap", e);
2353                } catch (RemoteException e) {
2354                }
2355            } break;
2356            case DELETE_DUMPHEAP_MSG: {
2357                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2358                        null, DumpHeapActivity.JAVA_URI,
2359                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2360                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2361                        UserHandle.myUserId());
2362                synchronized (ActivityManagerService.this) {
2363                    mMemWatchDumpFile = null;
2364                    mMemWatchDumpProcName = null;
2365                    mMemWatchDumpPid = -1;
2366                    mMemWatchDumpUid = -1;
2367                }
2368            } break;
2369            case FOREGROUND_PROFILE_CHANGED_MSG: {
2370                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2371            } break;
2372            case REPORT_TIME_TRACKER_MSG: {
2373                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2374                tracker.deliverResult(mContext);
2375            } break;
2376            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2377                mUserController.dispatchUserSwitchComplete(msg.arg1);
2378            } break;
2379            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2380                mUserController.dispatchLockedBootComplete(msg.arg1);
2381            } break;
2382            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2383                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2384                try {
2385                    connection.shutdown();
2386                } catch (RemoteException e) {
2387                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2388                }
2389                // Only a UiAutomation can set this flag and now that
2390                // it is finished we make sure it is reset to its default.
2391                mUserIsMonkey = false;
2392            } break;
2393            case IDLE_UIDS_MSG: {
2394                idleUids();
2395            } break;
2396            case VR_MODE_CHANGE_MSG: {
2397                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2398                    return;
2399                }
2400                synchronized (ActivityManagerService.this) {
2401                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2402                    mWindowManager.disableNonVrUi(disableNonVrUi);
2403                    if (disableNonVrUi) {
2404                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2405                        // then remove the pinned stack.
2406                        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2407                                PINNED_STACK_ID);
2408                        if (pinnedStack != null) {
2409                            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2410                        }
2411                    }
2412                }
2413            } break;
2414            case NOTIFY_VR_SLEEPING_MSG: {
2415                notifyVrManagerOfSleepState(msg.arg1 != 0);
2416            } break;
2417            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2418                synchronized (ActivityManagerService.this) {
2419                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2420                        ProcessRecord r = mLruProcesses.get(i);
2421                        if (r.thread != null) {
2422                            try {
2423                                r.thread.handleTrustStorageUpdate();
2424                            } catch (RemoteException ex) {
2425                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2426                                        r.info.processName);
2427                            }
2428                        }
2429                    }
2430                }
2431            } break;
2432            }
2433        }
2434    };
2435
2436    static final int COLLECT_PSS_BG_MSG = 1;
2437
2438    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2439        @Override
2440        public void handleMessage(Message msg) {
2441            switch (msg.what) {
2442            case COLLECT_PSS_BG_MSG: {
2443                long start = SystemClock.uptimeMillis();
2444                MemInfoReader memInfo = null;
2445                synchronized (ActivityManagerService.this) {
2446                    if (mFullPssPending) {
2447                        mFullPssPending = false;
2448                        memInfo = new MemInfoReader();
2449                    }
2450                }
2451                if (memInfo != null) {
2452                    updateCpuStatsNow();
2453                    long nativeTotalPss = 0;
2454                    final List<ProcessCpuTracker.Stats> stats;
2455                    synchronized (mProcessCpuTracker) {
2456                        stats = mProcessCpuTracker.getStats( (st)-> {
2457                            return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2458                        });
2459                    }
2460                    final int N = stats.size();
2461                    for (int j = 0; j < N; j++) {
2462                        synchronized (mPidsSelfLocked) {
2463                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2464                                // This is one of our own processes; skip it.
2465                                continue;
2466                            }
2467                        }
2468                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2469                    }
2470                    memInfo.readMemInfo();
2471                    synchronized (ActivityManagerService.this) {
2472                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2473                                + (SystemClock.uptimeMillis()-start) + "ms");
2474                        final long cachedKb = memInfo.getCachedSizeKb();
2475                        final long freeKb = memInfo.getFreeSizeKb();
2476                        final long zramKb = memInfo.getZramTotalSizeKb();
2477                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2478                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2479                                kernelKb*1024, nativeTotalPss*1024);
2480                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2481                                nativeTotalPss);
2482                    }
2483                }
2484
2485                int num = 0;
2486                long[] tmp = new long[2];
2487                do {
2488                    ProcessRecord proc;
2489                    int procState;
2490                    int pid;
2491                    long lastPssTime;
2492                    synchronized (ActivityManagerService.this) {
2493                        if (mPendingPssProcesses.size() <= 0) {
2494                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2495                                    "Collected PSS of " + num + " processes in "
2496                                    + (SystemClock.uptimeMillis() - start) + "ms");
2497                            mPendingPssProcesses.clear();
2498                            return;
2499                        }
2500                        proc = mPendingPssProcesses.remove(0);
2501                        procState = proc.pssProcState;
2502                        lastPssTime = proc.lastPssTime;
2503                        if (proc.thread != null && procState == proc.setProcState
2504                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2505                                        < SystemClock.uptimeMillis()) {
2506                            pid = proc.pid;
2507                        } else {
2508                            proc = null;
2509                            pid = 0;
2510                        }
2511                    }
2512                    if (proc != null) {
2513                        long pss = Debug.getPss(pid, tmp, null);
2514                        synchronized (ActivityManagerService.this) {
2515                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2516                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2517                                num++;
2518                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2519                                        SystemClock.uptimeMillis());
2520                            }
2521                        }
2522                    }
2523                } while (true);
2524            }
2525            }
2526        }
2527    };
2528
2529    public void setSystemProcess() {
2530        try {
2531            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2532            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2533            ServiceManager.addService("meminfo", new MemBinder(this));
2534            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2535            ServiceManager.addService("dbinfo", new DbBinder(this));
2536            if (MONITOR_CPU_USAGE) {
2537                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2538            }
2539            ServiceManager.addService("permission", new PermissionController(this));
2540            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2541
2542            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2543                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2544            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2545
2546            synchronized (this) {
2547                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2548                app.persistent = true;
2549                app.pid = MY_PID;
2550                app.maxAdj = ProcessList.SYSTEM_ADJ;
2551                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2552                synchronized (mPidsSelfLocked) {
2553                    mPidsSelfLocked.put(app.pid, app);
2554                }
2555                updateLruProcessLocked(app, false, null);
2556                updateOomAdjLocked();
2557            }
2558        } catch (PackageManager.NameNotFoundException e) {
2559            throw new RuntimeException(
2560                    "Unable to find android system package", e);
2561        }
2562    }
2563
2564    public void setWindowManager(WindowManagerService wm) {
2565        mWindowManager = wm;
2566        mStackSupervisor.setWindowManager(wm);
2567        mActivityStarter.setWindowManager(wm);
2568    }
2569
2570    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2571        mUsageStatsService = usageStatsManager;
2572    }
2573
2574    public void startObservingNativeCrashes() {
2575        final NativeCrashListener ncl = new NativeCrashListener(this);
2576        ncl.start();
2577    }
2578
2579    public IAppOpsService getAppOpsService() {
2580        return mAppOpsService;
2581    }
2582
2583    static class MemBinder extends Binder {
2584        ActivityManagerService mActivityManagerService;
2585        MemBinder(ActivityManagerService activityManagerService) {
2586            mActivityManagerService = activityManagerService;
2587        }
2588
2589        @Override
2590        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2591            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2592                    "meminfo", pw)) return;
2593            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2594        }
2595    }
2596
2597    static class GraphicsBinder extends Binder {
2598        ActivityManagerService mActivityManagerService;
2599        GraphicsBinder(ActivityManagerService activityManagerService) {
2600            mActivityManagerService = activityManagerService;
2601        }
2602
2603        @Override
2604        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2605            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2606                    "gfxinfo", pw)) return;
2607            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2608        }
2609    }
2610
2611    static class DbBinder extends Binder {
2612        ActivityManagerService mActivityManagerService;
2613        DbBinder(ActivityManagerService activityManagerService) {
2614            mActivityManagerService = activityManagerService;
2615        }
2616
2617        @Override
2618        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2619            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2620                    "dbinfo", pw)) return;
2621            mActivityManagerService.dumpDbInfo(fd, pw, args);
2622        }
2623    }
2624
2625    static class CpuBinder extends Binder {
2626        ActivityManagerService mActivityManagerService;
2627        CpuBinder(ActivityManagerService activityManagerService) {
2628            mActivityManagerService = activityManagerService;
2629        }
2630
2631        @Override
2632        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2633            if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2634                    "cpuinfo", pw)) return;
2635            synchronized (mActivityManagerService.mProcessCpuTracker) {
2636                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2637                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2638                        SystemClock.uptimeMillis()));
2639            }
2640        }
2641    }
2642
2643    public static final class Lifecycle extends SystemService {
2644        private final ActivityManagerService mService;
2645
2646        public Lifecycle(Context context) {
2647            super(context);
2648            mService = new ActivityManagerService(context);
2649        }
2650
2651        @Override
2652        public void onStart() {
2653            mService.start();
2654        }
2655
2656        @Override
2657        public void onCleanupUser(int userId) {
2658            mService.mBatteryStatsService.onCleanupUser(userId);
2659        }
2660
2661        public ActivityManagerService getService() {
2662            return mService;
2663        }
2664    }
2665
2666    @VisibleForTesting
2667    public ActivityManagerService(Injector injector) {
2668        mInjector = injector;
2669        mContext = mInjector.getContext();
2670        mUiContext = null;
2671        GL_ES_VERSION = 0;
2672        mActivityStarter = null;
2673        mAppErrors = null;
2674        mAppOpsService = mInjector.getAppOpsService(null, null);
2675        mBatteryStatsService = null;
2676        mCompatModePackages = null;
2677        mConstants = null;
2678        mGrantFile = null;
2679        mHandler = null;
2680        mHandlerThread = null;
2681        mIntentFirewall = null;
2682        mKeyguardController = null;
2683        mPermissionReviewRequired = false;
2684        mProcessCpuThread = null;
2685        mProcessStats = null;
2686        mProviderMap = null;
2687        mRecentTasks = null;
2688        mServices = null;
2689        mStackSupervisor = null;
2690        mSystemThread = null;
2691        mTaskChangeNotificationController = null;
2692        mUiHandler = injector.getUiHandler(null);
2693        mUserController = null;
2694        mVrController = null;
2695    }
2696
2697    // Note: This method is invoked on the main thread but may need to attach various
2698    // handlers to other threads.  So take care to be explicit about the looper.
2699    public ActivityManagerService(Context systemContext) {
2700        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2701        mInjector = new Injector();
2702        mContext = systemContext;
2703
2704        mFactoryTest = FactoryTest.getMode();
2705        mSystemThread = ActivityThread.currentActivityThread();
2706        mUiContext = mSystemThread.getSystemUiContext();
2707
2708        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2709
2710        mPermissionReviewRequired = mContext.getResources().getBoolean(
2711                com.android.internal.R.bool.config_permissionReviewRequired);
2712
2713        mHandlerThread = new ServiceThread(TAG,
2714                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2715        mHandlerThread.start();
2716        mHandler = new MainHandler(mHandlerThread.getLooper());
2717        mUiHandler = mInjector.getUiHandler(this);
2718
2719        mConstants = new ActivityManagerConstants(this, mHandler);
2720
2721        /* static; one-time init here */
2722        if (sKillHandler == null) {
2723            sKillThread = new ServiceThread(TAG + ":kill",
2724                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2725            sKillThread.start();
2726            sKillHandler = new KillHandler(sKillThread.getLooper());
2727        }
2728
2729        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2730                "foreground", BROADCAST_FG_TIMEOUT, false);
2731        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2732                "background", BROADCAST_BG_TIMEOUT, true);
2733        mBroadcastQueues[0] = mFgBroadcastQueue;
2734        mBroadcastQueues[1] = mBgBroadcastQueue;
2735
2736        mServices = new ActiveServices(this);
2737        mProviderMap = new ProviderMap(this);
2738        mAppErrors = new AppErrors(mUiContext, this);
2739
2740        // TODO: Move creation of battery stats service outside of activity manager service.
2741        File dataDir = Environment.getDataDirectory();
2742        File systemDir = new File(dataDir, "system");
2743        systemDir.mkdirs();
2744        mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2745        mBatteryStatsService.getActiveStatistics().readLocked();
2746        mBatteryStatsService.scheduleWriteToDisk();
2747        mOnBattery = DEBUG_POWER ? true
2748                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2749        mBatteryStatsService.getActiveStatistics().setCallback(this);
2750
2751        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2752
2753        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2754        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2755                new IAppOpsCallback.Stub() {
2756                    @Override public void opChanged(int op, int uid, String packageName) {
2757                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2758                            if (mAppOpsService.checkOperation(op, uid, packageName)
2759                                    != AppOpsManager.MODE_ALLOWED) {
2760                                runInBackgroundDisabled(uid);
2761                            }
2762                        }
2763                    }
2764                });
2765
2766        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2767
2768        mUserController = new UserController(this);
2769
2770        mVrController = new VrController(this);
2771
2772        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2773            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2774
2775        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2776            mUseFifoUiScheduling = true;
2777        }
2778
2779        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2780        mTempConfig.setToDefaults();
2781        mTempConfig.setLocales(LocaleList.getDefault());
2782        mConfigurationSeq = mTempConfig.seq = 1;
2783        mStackSupervisor = createStackSupervisor();
2784        mStackSupervisor.onConfigurationChanged(mTempConfig);
2785        mKeyguardController = mStackSupervisor.mKeyguardController;
2786        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2787        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2788        mTaskChangeNotificationController =
2789                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2790        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2791        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2792
2793        mProcessCpuThread = new Thread("CpuTracker") {
2794            @Override
2795            public void run() {
2796                synchronized (mProcessCpuTracker) {
2797                    mProcessCpuInitLatch.countDown();
2798                    mProcessCpuTracker.init();
2799                }
2800                while (true) {
2801                    try {
2802                        try {
2803                            synchronized(this) {
2804                                final long now = SystemClock.uptimeMillis();
2805                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2806                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2807                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2808                                //        + ", write delay=" + nextWriteDelay);
2809                                if (nextWriteDelay < nextCpuDelay) {
2810                                    nextCpuDelay = nextWriteDelay;
2811                                }
2812                                if (nextCpuDelay > 0) {
2813                                    mProcessCpuMutexFree.set(true);
2814                                    this.wait(nextCpuDelay);
2815                                }
2816                            }
2817                        } catch (InterruptedException e) {
2818                        }
2819                        updateCpuStatsNow();
2820                    } catch (Exception e) {
2821                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2822                    }
2823                }
2824            }
2825        };
2826
2827        Watchdog.getInstance().addMonitor(this);
2828        Watchdog.getInstance().addThread(mHandler);
2829    }
2830
2831    protected ActivityStackSupervisor createStackSupervisor() {
2832        return new ActivityStackSupervisor(this, mHandler.getLooper());
2833    }
2834
2835    public void setSystemServiceManager(SystemServiceManager mgr) {
2836        mSystemServiceManager = mgr;
2837    }
2838
2839    public void setInstaller(Installer installer) {
2840        mInstaller = installer;
2841    }
2842
2843    private void start() {
2844        removeAllProcessGroups();
2845        mProcessCpuThread.start();
2846
2847        mBatteryStatsService.publish();
2848        mAppOpsService.publish(mContext);
2849        Slog.d("AppOps", "AppOpsService published");
2850        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2851        // Wait for the synchronized block started in mProcessCpuThread,
2852        // so that any other acccess to mProcessCpuTracker from main thread
2853        // will be blocked during mProcessCpuTracker initialization.
2854        try {
2855            mProcessCpuInitLatch.await();
2856        } catch (InterruptedException e) {
2857            Slog.wtf(TAG, "Interrupted wait during start", e);
2858            Thread.currentThread().interrupt();
2859            throw new IllegalStateException("Interrupted wait during start");
2860        }
2861    }
2862
2863    void onUserStoppedLocked(int userId) {
2864        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2865    }
2866
2867    public void initPowerManagement() {
2868        mStackSupervisor.initPowerManagement();
2869        mBatteryStatsService.initPowerManagement();
2870        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2871        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2872        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2873        mVoiceWakeLock.setReferenceCounted(false);
2874    }
2875
2876    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2877        if (mBackgroundLaunchBroadcasts == null) {
2878            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2879        }
2880        return mBackgroundLaunchBroadcasts;
2881    }
2882
2883    @Override
2884    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2885            throws RemoteException {
2886        if (code == SYSPROPS_TRANSACTION) {
2887            // We need to tell all apps about the system property change.
2888            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2889            synchronized(this) {
2890                final int NP = mProcessNames.getMap().size();
2891                for (int ip=0; ip<NP; ip++) {
2892                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2893                    final int NA = apps.size();
2894                    for (int ia=0; ia<NA; ia++) {
2895                        ProcessRecord app = apps.valueAt(ia);
2896                        if (app.thread != null) {
2897                            procs.add(app.thread.asBinder());
2898                        }
2899                    }
2900                }
2901            }
2902
2903            int N = procs.size();
2904            for (int i=0; i<N; i++) {
2905                Parcel data2 = Parcel.obtain();
2906                try {
2907                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2908                            Binder.FLAG_ONEWAY);
2909                } catch (RemoteException e) {
2910                }
2911                data2.recycle();
2912            }
2913        }
2914        try {
2915            return super.onTransact(code, data, reply, flags);
2916        } catch (RuntimeException e) {
2917            // The activity manager only throws security exceptions, so let's
2918            // log all others.
2919            if (!(e instanceof SecurityException)) {
2920                Slog.wtf(TAG, "Activity Manager Crash."
2921                        + " UID:" + Binder.getCallingUid()
2922                        + " PID:" + Binder.getCallingPid()
2923                        + " TRANS:" + code, e);
2924            }
2925            throw e;
2926        }
2927    }
2928
2929    void updateCpuStats() {
2930        final long now = SystemClock.uptimeMillis();
2931        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2932            return;
2933        }
2934        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2935            synchronized (mProcessCpuThread) {
2936                mProcessCpuThread.notify();
2937            }
2938        }
2939    }
2940
2941    void updateCpuStatsNow() {
2942        synchronized (mProcessCpuTracker) {
2943            mProcessCpuMutexFree.set(false);
2944            final long now = SystemClock.uptimeMillis();
2945            boolean haveNewCpuStats = false;
2946
2947            if (MONITOR_CPU_USAGE &&
2948                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2949                mLastCpuTime.set(now);
2950                mProcessCpuTracker.update();
2951                if (mProcessCpuTracker.hasGoodLastStats()) {
2952                    haveNewCpuStats = true;
2953                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2954                    //Slog.i(TAG, "Total CPU usage: "
2955                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2956
2957                    // Slog the cpu usage if the property is set.
2958                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2959                        int user = mProcessCpuTracker.getLastUserTime();
2960                        int system = mProcessCpuTracker.getLastSystemTime();
2961                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2962                        int irq = mProcessCpuTracker.getLastIrqTime();
2963                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2964                        int idle = mProcessCpuTracker.getLastIdleTime();
2965
2966                        int total = user + system + iowait + irq + softIrq + idle;
2967                        if (total == 0) total = 1;
2968
2969                        EventLog.writeEvent(EventLogTags.CPU,
2970                                ((user+system+iowait+irq+softIrq) * 100) / total,
2971                                (user * 100) / total,
2972                                (system * 100) / total,
2973                                (iowait * 100) / total,
2974                                (irq * 100) / total,
2975                                (softIrq * 100) / total);
2976                    }
2977                }
2978            }
2979
2980            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2981            synchronized(bstats) {
2982                synchronized(mPidsSelfLocked) {
2983                    if (haveNewCpuStats) {
2984                        if (bstats.startAddingCpuLocked()) {
2985                            int totalUTime = 0;
2986                            int totalSTime = 0;
2987                            final int N = mProcessCpuTracker.countStats();
2988                            for (int i=0; i<N; i++) {
2989                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2990                                if (!st.working) {
2991                                    continue;
2992                                }
2993                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2994                                totalUTime += st.rel_utime;
2995                                totalSTime += st.rel_stime;
2996                                if (pr != null) {
2997                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2998                                    if (ps == null || !ps.isActive()) {
2999                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3000                                                pr.info.uid, pr.processName);
3001                                    }
3002                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3003                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3004                                    if (pr.lastCpuTime == 0) {
3005                                        pr.lastCpuTime = pr.curCpuTime;
3006                                    }
3007                                } else {
3008                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3009                                    if (ps == null || !ps.isActive()) {
3010                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3011                                                bstats.mapUid(st.uid), st.name);
3012                                    }
3013                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3014                                }
3015                            }
3016                            final int userTime = mProcessCpuTracker.getLastUserTime();
3017                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3018                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3019                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3020                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3021                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3022                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3023                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3024                        }
3025                    }
3026                }
3027
3028                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3029                    mLastWriteTime = now;
3030                    mBatteryStatsService.scheduleWriteToDisk();
3031                }
3032            }
3033        }
3034    }
3035
3036    @Override
3037    public void batteryNeedsCpuUpdate() {
3038        updateCpuStatsNow();
3039    }
3040
3041    @Override
3042    public void batteryPowerChanged(boolean onBattery) {
3043        // When plugging in, update the CPU stats first before changing
3044        // the plug state.
3045        updateCpuStatsNow();
3046        synchronized (this) {
3047            synchronized(mPidsSelfLocked) {
3048                mOnBattery = DEBUG_POWER ? true : onBattery;
3049            }
3050        }
3051    }
3052
3053    @Override
3054    public void batterySendBroadcast(Intent intent) {
3055        synchronized (this) {
3056            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3057                    AppOpsManager.OP_NONE, null, false, false,
3058                    -1, SYSTEM_UID, UserHandle.USER_ALL);
3059        }
3060    }
3061
3062    /**
3063     * Initialize the application bind args. These are passed to each
3064     * process when the bindApplication() IPC is sent to the process. They're
3065     * lazily setup to make sure the services are running when they're asked for.
3066     */
3067    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3068        // Isolated processes won't get this optimization, so that we don't
3069        // violate the rules about which services they have access to.
3070        if (isolated) {
3071            if (mIsolatedAppBindArgs == null) {
3072                mIsolatedAppBindArgs = new HashMap<>();
3073                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3074            }
3075            return mIsolatedAppBindArgs;
3076        }
3077
3078        if (mAppBindArgs == null) {
3079            mAppBindArgs = new HashMap<>();
3080
3081            // Setup the application init args
3082            mAppBindArgs.put("package", ServiceManager.getService("package"));
3083            mAppBindArgs.put("window", ServiceManager.getService("window"));
3084            mAppBindArgs.put(Context.ALARM_SERVICE,
3085                    ServiceManager.getService(Context.ALARM_SERVICE));
3086        }
3087        return mAppBindArgs;
3088    }
3089
3090    /**
3091     * Update AMS states when an activity is resumed. This should only be called by
3092     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3093     */
3094    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3095        final TaskRecord task = r.getTask();
3096        if (task.isApplicationTask()) {
3097            if (mCurAppTimeTracker != r.appTimeTracker) {
3098                // We are switching app tracking.  Complete the current one.
3099                if (mCurAppTimeTracker != null) {
3100                    mCurAppTimeTracker.stop();
3101                    mHandler.obtainMessage(
3102                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3103                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3104                    mCurAppTimeTracker = null;
3105                }
3106                if (r.appTimeTracker != null) {
3107                    mCurAppTimeTracker = r.appTimeTracker;
3108                    startTimeTrackingFocusedActivityLocked();
3109                }
3110            } else {
3111                startTimeTrackingFocusedActivityLocked();
3112            }
3113        } else {
3114            r.appTimeTracker = null;
3115        }
3116        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3117        // TODO: Probably not, because we don't want to resume voice on switching
3118        // back to this activity
3119        if (task.voiceInteractor != null) {
3120            startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3121        } else {
3122            finishRunningVoiceLocked();
3123
3124            if (mLastResumedActivity != null) {
3125                final IVoiceInteractionSession session;
3126
3127                final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3128                if (lastResumedActivityTask != null
3129                        && lastResumedActivityTask.voiceSession != null) {
3130                    session = lastResumedActivityTask.voiceSession;
3131                } else {
3132                    session = mLastResumedActivity.voiceSession;
3133                }
3134
3135                if (session != null) {
3136                    // We had been in a voice interaction session, but now focused has
3137                    // move to something different.  Just finish the session, we can't
3138                    // return to it and retain the proper state and synchronization with
3139                    // the voice interaction service.
3140                    finishVoiceTask(session);
3141                }
3142            }
3143        }
3144
3145        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3146            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3147            mHandler.obtainMessage(
3148                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3149        }
3150        mLastResumedActivity = r;
3151
3152        mWindowManager.setFocusedApp(r.appToken, true);
3153
3154        applyUpdateLockStateLocked(r);
3155        applyUpdateVrModeLocked(r);
3156
3157        EventLogTags.writeAmSetResumedActivity(
3158                r == null ? -1 : r.userId,
3159                r == null ? "NULL" : r.shortComponentName,
3160                reason);
3161    }
3162
3163    @Override
3164    public void setFocusedStack(int stackId) {
3165        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3166        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3167        final long callingId = Binder.clearCallingIdentity();
3168        try {
3169            synchronized (this) {
3170                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3171                if (stack == null) {
3172                    return;
3173                }
3174                final ActivityRecord r = stack.topRunningActivityLocked();
3175                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3176                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3177                }
3178            }
3179        } finally {
3180            Binder.restoreCallingIdentity(callingId);
3181        }
3182    }
3183
3184    @Override
3185    public void setFocusedTask(int taskId) {
3186        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3187        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3188        final long callingId = Binder.clearCallingIdentity();
3189        try {
3190            synchronized (this) {
3191                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3192                if (task == null) {
3193                    return;
3194                }
3195                final ActivityRecord r = task.topRunningActivityLocked();
3196                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3197                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3198                }
3199            }
3200        } finally {
3201            Binder.restoreCallingIdentity(callingId);
3202        }
3203    }
3204
3205    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3206    @Override
3207    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3208        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3209        mTaskChangeNotificationController.registerTaskStackListener(listener);
3210    }
3211
3212    /**
3213     * Unregister a task stack listener so that it stops receiving callbacks.
3214     */
3215    @Override
3216    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3217         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3218         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3219     }
3220
3221    @Override
3222    public void notifyActivityDrawn(IBinder token) {
3223        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3224        synchronized (this) {
3225            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3226            if (r != null) {
3227                r.getStack().notifyActivityDrawnLocked(r);
3228            }
3229        }
3230    }
3231
3232    final void applyUpdateLockStateLocked(ActivityRecord r) {
3233        // Modifications to the UpdateLock state are done on our handler, outside
3234        // the activity manager's locks.  The new state is determined based on the
3235        // state *now* of the relevant activity record.  The object is passed to
3236        // the handler solely for logging detail, not to be consulted/modified.
3237        final boolean nextState = r != null && r.immersive;
3238        mHandler.sendMessage(
3239                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3240    }
3241
3242    final void applyUpdateVrModeLocked(ActivityRecord r) {
3243        // VR apps are expected to run in a main display. If an app is turning on VR for
3244        // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3245        // fullscreen stack before enabling VR Mode.
3246        // TODO: The goal of this code is to keep the VR app on the main display. When the
3247        // stack implementation changes in the future, keep in mind that the use of the fullscreen
3248        // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3249        // option would be a better choice here.
3250        if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
3251            Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3252                    + " to main stack for VR");
3253            moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
3254        }
3255        mHandler.sendMessage(
3256                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3257    }
3258
3259    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3260        mHandler.sendMessage(
3261                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3262    }
3263
3264    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3265        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3266        if (vrService == null) {
3267            return;
3268        }
3269        vrService.onSleepStateChanged(isSleeping);
3270    }
3271
3272    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3273        Message msg = Message.obtain();
3274        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3275        msg.obj = r.getTask().askedCompatMode ? null : r;
3276        mUiHandler.sendMessage(msg);
3277    }
3278
3279    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3280        final Configuration globalConfig = getGlobalConfiguration();
3281        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3282                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3283            final Message msg = Message.obtain();
3284            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3285            msg.obj = r;
3286            mUiHandler.sendMessage(msg);
3287        }
3288    }
3289
3290    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3291            String what, Object obj, ProcessRecord srcApp) {
3292        app.lastActivityTime = now;
3293
3294        if (app.activities.size() > 0) {
3295            // Don't want to touch dependent processes that are hosting activities.
3296            return index;
3297        }
3298
3299        int lrui = mLruProcesses.lastIndexOf(app);
3300        if (lrui < 0) {
3301            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3302                    + what + " " + obj + " from " + srcApp);
3303            return index;
3304        }
3305
3306        if (lrui >= index) {
3307            // Don't want to cause this to move dependent processes *back* in the
3308            // list as if they were less frequently used.
3309            return index;
3310        }
3311
3312        if (lrui >= mLruProcessActivityStart) {
3313            // Don't want to touch dependent processes that are hosting activities.
3314            return index;
3315        }
3316
3317        mLruProcesses.remove(lrui);
3318        if (index > 0) {
3319            index--;
3320        }
3321        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3322                + " in LRU list: " + app);
3323        mLruProcesses.add(index, app);
3324        return index;
3325    }
3326
3327    static void killProcessGroup(int uid, int pid) {
3328        if (sKillHandler != null) {
3329            sKillHandler.sendMessage(
3330                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3331        } else {
3332            Slog.w(TAG, "Asked to kill process group before system bringup!");
3333            Process.killProcessGroup(uid, pid);
3334        }
3335    }
3336
3337    final void removeLruProcessLocked(ProcessRecord app) {
3338        int lrui = mLruProcesses.lastIndexOf(app);
3339        if (lrui >= 0) {
3340            if (!app.killed) {
3341                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3342                killProcessQuiet(app.pid);
3343                killProcessGroup(app.uid, app.pid);
3344            }
3345            if (lrui <= mLruProcessActivityStart) {
3346                mLruProcessActivityStart--;
3347            }
3348            if (lrui <= mLruProcessServiceStart) {
3349                mLruProcessServiceStart--;
3350            }
3351            mLruProcesses.remove(lrui);
3352        }
3353    }
3354
3355    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3356            ProcessRecord client) {
3357        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3358                || app.treatLikeActivity;
3359        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3360        if (!activityChange && hasActivity) {
3361            // The process has activities, so we are only allowing activity-based adjustments
3362            // to move it.  It should be kept in the front of the list with other
3363            // processes that have activities, and we don't want those to change their
3364            // order except due to activity operations.
3365            return;
3366        }
3367
3368        mLruSeq++;
3369        final long now = SystemClock.uptimeMillis();
3370        app.lastActivityTime = now;
3371
3372        // First a quick reject: if the app is already at the position we will
3373        // put it, then there is nothing to do.
3374        if (hasActivity) {
3375            final int N = mLruProcesses.size();
3376            if (N > 0 && mLruProcesses.get(N-1) == app) {
3377                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3378                return;
3379            }
3380        } else {
3381            if (mLruProcessServiceStart > 0
3382                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3383                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3384                return;
3385            }
3386        }
3387
3388        int lrui = mLruProcesses.lastIndexOf(app);
3389
3390        if (app.persistent && lrui >= 0) {
3391            // We don't care about the position of persistent processes, as long as
3392            // they are in the list.
3393            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3394            return;
3395        }
3396
3397        /* In progress: compute new position first, so we can avoid doing work
3398           if the process is not actually going to move.  Not yet working.
3399        int addIndex;
3400        int nextIndex;
3401        boolean inActivity = false, inService = false;
3402        if (hasActivity) {
3403            // Process has activities, put it at the very tipsy-top.
3404            addIndex = mLruProcesses.size();
3405            nextIndex = mLruProcessServiceStart;
3406            inActivity = true;
3407        } else if (hasService) {
3408            // Process has services, put it at the top of the service list.
3409            addIndex = mLruProcessActivityStart;
3410            nextIndex = mLruProcessServiceStart;
3411            inActivity = true;
3412            inService = true;
3413        } else  {
3414            // Process not otherwise of interest, it goes to the top of the non-service area.
3415            addIndex = mLruProcessServiceStart;
3416            if (client != null) {
3417                int clientIndex = mLruProcesses.lastIndexOf(client);
3418                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3419                        + app);
3420                if (clientIndex >= 0 && addIndex > clientIndex) {
3421                    addIndex = clientIndex;
3422                }
3423            }
3424            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3425        }
3426
3427        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3428                + mLruProcessActivityStart + "): " + app);
3429        */
3430
3431        if (lrui >= 0) {
3432            if (lrui < mLruProcessActivityStart) {
3433                mLruProcessActivityStart--;
3434            }
3435            if (lrui < mLruProcessServiceStart) {
3436                mLruProcessServiceStart--;
3437            }
3438            /*
3439            if (addIndex > lrui) {
3440                addIndex--;
3441            }
3442            if (nextIndex > lrui) {
3443                nextIndex--;
3444            }
3445            */
3446            mLruProcesses.remove(lrui);
3447        }
3448
3449        /*
3450        mLruProcesses.add(addIndex, app);
3451        if (inActivity) {
3452            mLruProcessActivityStart++;
3453        }
3454        if (inService) {
3455            mLruProcessActivityStart++;
3456        }
3457        */
3458
3459        int nextIndex;
3460        if (hasActivity) {
3461            final int N = mLruProcesses.size();
3462            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3463                // Process doesn't have activities, but has clients with
3464                // activities...  move it up, but one below the top (the top
3465                // should always have a real activity).
3466                if (DEBUG_LRU) Slog.d(TAG_LRU,
3467                        "Adding to second-top of LRU activity list: " + app);
3468                mLruProcesses.add(N - 1, app);
3469                // To keep it from spamming the LRU list (by making a bunch of clients),
3470                // we will push down any other entries owned by the app.
3471                final int uid = app.info.uid;
3472                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3473                    ProcessRecord subProc = mLruProcesses.get(i);
3474                    if (subProc.info.uid == uid) {
3475                        // We want to push this one down the list.  If the process after
3476                        // it is for the same uid, however, don't do so, because we don't
3477                        // want them internally to be re-ordered.
3478                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3479                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3480                                    "Pushing uid " + uid + " swapping at " + i + ": "
3481                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3482                            ProcessRecord tmp = mLruProcesses.get(i);
3483                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3484                            mLruProcesses.set(i - 1, tmp);
3485                            i--;
3486                        }
3487                    } else {
3488                        // A gap, we can stop here.
3489                        break;
3490                    }
3491                }
3492            } else {
3493                // Process has activities, put it at the very tipsy-top.
3494                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3495                mLruProcesses.add(app);
3496            }
3497            nextIndex = mLruProcessServiceStart;
3498        } else if (hasService) {
3499            // Process has services, put it at the top of the service list.
3500            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3501            mLruProcesses.add(mLruProcessActivityStart, app);
3502            nextIndex = mLruProcessServiceStart;
3503            mLruProcessActivityStart++;
3504        } else  {
3505            // Process not otherwise of interest, it goes to the top of the non-service area.
3506            int index = mLruProcessServiceStart;
3507            if (client != null) {
3508                // If there is a client, don't allow the process to be moved up higher
3509                // in the list than that client.
3510                int clientIndex = mLruProcesses.lastIndexOf(client);
3511                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3512                        + " when updating " + app);
3513                if (clientIndex <= lrui) {
3514                    // Don't allow the client index restriction to push it down farther in the
3515                    // list than it already is.
3516                    clientIndex = lrui;
3517                }
3518                if (clientIndex >= 0 && index > clientIndex) {
3519                    index = clientIndex;
3520                }
3521            }
3522            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3523            mLruProcesses.add(index, app);
3524            nextIndex = index-1;
3525            mLruProcessActivityStart++;
3526            mLruProcessServiceStart++;
3527        }
3528
3529        // If the app is currently using a content provider or service,
3530        // bump those processes as well.
3531        for (int j=app.connections.size()-1; j>=0; j--) {
3532            ConnectionRecord cr = app.connections.valueAt(j);
3533            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3534                    && cr.binding.service.app != null
3535                    && cr.binding.service.app.lruSeq != mLruSeq
3536                    && !cr.binding.service.app.persistent) {
3537                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3538                        "service connection", cr, app);
3539            }
3540        }
3541        for (int j=app.conProviders.size()-1; j>=0; j--) {
3542            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3543            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3544                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3545                        "provider reference", cpr, app);
3546            }
3547        }
3548    }
3549
3550    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3551        if (uid == SYSTEM_UID) {
3552            // The system gets to run in any process.  If there are multiple
3553            // processes with the same uid, just pick the first (this
3554            // should never happen).
3555            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3556            if (procs == null) return null;
3557            final int procCount = procs.size();
3558            for (int i = 0; i < procCount; i++) {
3559                final int procUid = procs.keyAt(i);
3560                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3561                    // Don't use an app process or different user process for system component.
3562                    continue;
3563                }
3564                return procs.valueAt(i);
3565            }
3566        }
3567        ProcessRecord proc = mProcessNames.get(processName, uid);
3568        if (false && proc != null && !keepIfLarge
3569                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3570                && proc.lastCachedPss >= 4000) {
3571            // Turn this condition on to cause killing to happen regularly, for testing.
3572            if (proc.baseProcessTracker != null) {
3573                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3574            }
3575            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3576        } else if (proc != null && !keepIfLarge
3577                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3578                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3579            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3580            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3581                if (proc.baseProcessTracker != null) {
3582                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3583                }
3584                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3585            }
3586        }
3587        return proc;
3588    }
3589
3590    void notifyPackageUse(String packageName, int reason) {
3591        synchronized(this) {
3592            getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3593        }
3594    }
3595
3596    boolean isNextTransitionForward() {
3597        int transit = mWindowManager.getPendingAppTransition();
3598        return transit == TRANSIT_ACTIVITY_OPEN
3599                || transit == TRANSIT_TASK_OPEN
3600                || transit == TRANSIT_TASK_TO_FRONT;
3601    }
3602
3603    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3604            String processName, String abiOverride, int uid, Runnable crashHandler) {
3605        synchronized(this) {
3606            ApplicationInfo info = new ApplicationInfo();
3607            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3608            // For isolated processes, the former contains the parent's uid and the latter the
3609            // actual uid of the isolated process.
3610            // In the special case introduced by this method (which is, starting an isolated
3611            // process directly from the SystemServer without an actual parent app process) the
3612            // closest thing to a parent's uid is SYSTEM_UID.
3613            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3614            // the |isolated| logic in the ProcessRecord constructor.
3615            info.uid = SYSTEM_UID;
3616            info.processName = processName;
3617            info.className = entryPoint;
3618            info.packageName = "android";
3619            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3620            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3621                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3622                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3623                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3624                    crashHandler);
3625            return proc != null ? proc.pid : 0;
3626        }
3627    }
3628
3629    final ProcessRecord startProcessLocked(String processName,
3630            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3631            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3632            boolean isolated, boolean keepIfLarge) {
3633        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3634                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3635                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3636                null /* crashHandler */);
3637    }
3638
3639    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3640            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3641            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3642            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3643        long startTime = SystemClock.elapsedRealtime();
3644        ProcessRecord app;
3645        if (!isolated) {
3646            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3647            checkTime(startTime, "startProcess: after getProcessRecord");
3648
3649            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3650                // If we are in the background, then check to see if this process
3651                // is bad.  If so, we will just silently fail.
3652                if (mAppErrors.isBadProcessLocked(info)) {
3653                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3654                            + "/" + info.processName);
3655                    return null;
3656                }
3657            } else {
3658                // When the user is explicitly starting a process, then clear its
3659                // crash count so that we won't make it bad until they see at
3660                // least one crash dialog again, and make the process good again
3661                // if it had been bad.
3662                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3663                        + "/" + info.processName);
3664                mAppErrors.resetProcessCrashTimeLocked(info);
3665                if (mAppErrors.isBadProcessLocked(info)) {
3666                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3667                            UserHandle.getUserId(info.uid), info.uid,
3668                            info.processName);
3669                    mAppErrors.clearBadProcessLocked(info);
3670                    if (app != null) {
3671                        app.bad = false;
3672                    }
3673                }
3674            }
3675        } else {
3676            // If this is an isolated process, it can't re-use an existing process.
3677            app = null;
3678        }
3679
3680        // We don't have to do anything more if:
3681        // (1) There is an existing application record; and
3682        // (2) The caller doesn't think it is dead, OR there is no thread
3683        //     object attached to it so we know it couldn't have crashed; and
3684        // (3) There is a pid assigned to it, so it is either starting or
3685        //     already running.
3686        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3687                + " app=" + app + " knownToBeDead=" + knownToBeDead
3688                + " thread=" + (app != null ? app.thread : null)
3689                + " pid=" + (app != null ? app.pid : -1));
3690        if (app != null && app.pid > 0) {
3691            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3692                // We already have the app running, or are waiting for it to
3693                // come up (we have a pid but not yet its thread), so keep it.
3694                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3695                // If this is a new package in the process, add the package to the list
3696                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3697                checkTime(startTime, "startProcess: done, added package to proc");
3698                return app;
3699            }
3700
3701            // An application record is attached to a previous process,
3702            // clean it up now.
3703            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3704            checkTime(startTime, "startProcess: bad proc running, killing");
3705            killProcessGroup(app.uid, app.pid);
3706            handleAppDiedLocked(app, true, true);
3707            checkTime(startTime, "startProcess: done killing old proc");
3708        }
3709
3710        String hostingNameStr = hostingName != null
3711                ? hostingName.flattenToShortString() : null;
3712
3713        if (app == null) {
3714            checkTime(startTime, "startProcess: creating new process record");
3715            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3716            if (app == null) {
3717                Slog.w(TAG, "Failed making new process record for "
3718                        + processName + "/" + info.uid + " isolated=" + isolated);
3719                return null;
3720            }
3721            app.crashHandler = crashHandler;
3722            checkTime(startTime, "startProcess: done creating new process record");
3723        } else {
3724            // If this is a new package in the process, add the package to the list
3725            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3726            checkTime(startTime, "startProcess: added package to existing proc");
3727        }
3728
3729        // If the system is not ready yet, then hold off on starting this
3730        // process until it is.
3731        if (!mProcessesReady
3732                && !isAllowedWhileBooting(info)
3733                && !allowWhileBooting) {
3734            if (!mProcessesOnHold.contains(app)) {
3735                mProcessesOnHold.add(app);
3736            }
3737            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3738                    "System not ready, putting on hold: " + app);
3739            checkTime(startTime, "startProcess: returning with proc on hold");
3740            return app;
3741        }
3742
3743        checkTime(startTime, "startProcess: stepping in to startProcess");
3744        startProcessLocked(
3745                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3746        checkTime(startTime, "startProcess: done starting proc!");
3747        return (app.pid != 0) ? app : null;
3748    }
3749
3750    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3751        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3752    }
3753
3754    private final void startProcessLocked(ProcessRecord app,
3755            String hostingType, String hostingNameStr) {
3756        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3757                null /* entryPoint */, null /* entryPointArgs */);
3758    }
3759
3760    private final void startProcessLocked(ProcessRecord app, String hostingType,
3761            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3762        long startTime = SystemClock.elapsedRealtime();
3763        if (app.pid > 0 && app.pid != MY_PID) {
3764            checkTime(startTime, "startProcess: removing from pids map");
3765            synchronized (mPidsSelfLocked) {
3766                mPidsSelfLocked.remove(app.pid);
3767                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3768            }
3769            checkTime(startTime, "startProcess: done removing from pids map");
3770            app.setPid(0);
3771        }
3772
3773        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3774                "startProcessLocked removing on hold: " + app);
3775        mProcessesOnHold.remove(app);
3776
3777        checkTime(startTime, "startProcess: starting to update cpu stats");
3778        updateCpuStats();
3779        checkTime(startTime, "startProcess: done updating cpu stats");
3780
3781        try {
3782            try {
3783                final int userId = UserHandle.getUserId(app.uid);
3784                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3785            } catch (RemoteException e) {
3786                throw e.rethrowAsRuntimeException();
3787            }
3788
3789            int uid = app.uid;
3790            int[] gids = null;
3791            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3792            if (!app.isolated) {
3793                int[] permGids = null;
3794                try {
3795                    checkTime(startTime, "startProcess: getting gids from package manager");
3796                    final IPackageManager pm = AppGlobals.getPackageManager();
3797                    permGids = pm.getPackageGids(app.info.packageName,
3798                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3799                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3800                            StorageManagerInternal.class);
3801                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3802                            app.info.packageName);
3803                } catch (RemoteException e) {
3804                    throw e.rethrowAsRuntimeException();
3805                }
3806
3807                /*
3808                 * Add shared application and profile GIDs so applications can share some
3809                 * resources like shared libraries and access user-wide resources
3810                 */
3811                if (ArrayUtils.isEmpty(permGids)) {
3812                    gids = new int[3];
3813                } else {
3814                    gids = new int[permGids.length + 3];
3815                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3816                }
3817                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3818                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3819                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3820            }
3821            checkTime(startTime, "startProcess: building args");
3822            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3823                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3824                        && mTopComponent != null
3825                        && app.processName.equals(mTopComponent.getPackageName())) {
3826                    uid = 0;
3827                }
3828                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3829                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3830                    uid = 0;
3831                }
3832            }
3833            int runtimeFlags = 0;
3834            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3835                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
3836                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3837                // Also turn on CheckJNI for debuggable apps. It's quite
3838                // awkward to turn on otherwise.
3839                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3840            }
3841            // Run the app in safe mode if its manifest requests so or the
3842            // system is booted in safe mode.
3843            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3844                mSafeMode == true) {
3845                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3846            }
3847            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3848                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3849            }
3850            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3851            if ("true".equals(genDebugInfoProperty)) {
3852                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3853            }
3854            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3855                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3856            }
3857            if ("1".equals(SystemProperties.get("debug.assert"))) {
3858                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3859            }
3860            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3861                // Enable all debug flags required by the native debugger.
3862                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3863                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3864                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3865                mNativeDebuggingApp = null;
3866            }
3867
3868            if (app.info.isPrivilegedApp() &&
3869                    !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
3870                runtimeFlags |= Zygote.DISABLE_VERIFIER;
3871                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
3872            }
3873
3874            String invokeWith = null;
3875            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3876                // Debuggable apps may include a wrapper script with their library directory.
3877                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3878                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3879                try {
3880                    if (new File(wrapperFileName).exists()) {
3881                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3882                    }
3883                } finally {
3884                    StrictMode.setThreadPolicy(oldPolicy);
3885                }
3886            }
3887
3888            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3889            if (requiredAbi == null) {
3890                requiredAbi = Build.SUPPORTED_ABIS[0];
3891            }
3892
3893            String instructionSet = null;
3894            if (app.info.primaryCpuAbi != null) {
3895                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3896            }
3897
3898            app.gids = gids;
3899            app.requiredAbi = requiredAbi;
3900            app.instructionSet = instructionSet;
3901
3902            // the per-user SELinux context must be set
3903            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3904                Slog.wtf(TAG, "SELinux tag not defined",
3905                        new IllegalStateException("SELinux tag not defined for "
3906                        + app.info.packageName + " (uid " + app.uid + ")"));
3907            }
3908            final String seInfo = app.info.seInfo
3909                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3910            // Start the process.  It will either succeed and return a result containing
3911            // the PID of the new process, or else throw a RuntimeException.
3912            boolean isActivityProcess = (entryPoint == null);
3913            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3914            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3915                    app.processName);
3916            checkTime(startTime, "startProcess: asking zygote to start proc");
3917            ProcessStartResult startResult;
3918            if (hostingType.equals("webview_service")) {
3919                startResult = startWebView(entryPoint,
3920                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3921                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3922                        app.info.dataDir, null, entryPointArgs);
3923            } else {
3924                startResult = Process.start(entryPoint,
3925                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3926                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3927                        app.info.dataDir, invokeWith, entryPointArgs);
3928            }
3929            checkTime(startTime, "startProcess: returned from zygote!");
3930            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3931
3932            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3933            checkTime(startTime, "startProcess: done updating battery stats");
3934
3935            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3936                    UserHandle.getUserId(uid), startResult.pid, uid,
3937                    app.processName, hostingType,
3938                    hostingNameStr != null ? hostingNameStr : "");
3939
3940            try {
3941                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3942                        seInfo, app.info.sourceDir, startResult.pid);
3943            } catch (RemoteException ex) {
3944                // Ignore
3945            }
3946
3947            if (app.persistent) {
3948                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3949            }
3950
3951            checkTime(startTime, "startProcess: building log message");
3952            StringBuilder buf = mStringBuilder;
3953            buf.setLength(0);
3954            buf.append("Start proc ");
3955            buf.append(startResult.pid);
3956            buf.append(':');
3957            buf.append(app.processName);
3958            buf.append('/');
3959            UserHandle.formatUid(buf, uid);
3960            if (!isActivityProcess) {
3961                buf.append(" [");
3962                buf.append(entryPoint);
3963                buf.append("]");
3964            }
3965            buf.append(" for ");
3966            buf.append(hostingType);
3967            if (hostingNameStr != null) {
3968                buf.append(" ");
3969                buf.append(hostingNameStr);
3970            }
3971            Slog.i(TAG, buf.toString());
3972            app.setPid(startResult.pid);
3973            app.usingWrapper = startResult.usingWrapper;
3974            app.removed = false;
3975            app.killed = false;
3976            app.killedByAm = false;
3977            checkTime(startTime, "startProcess: starting to update pids map");
3978            ProcessRecord oldApp;
3979            synchronized (mPidsSelfLocked) {
3980                oldApp = mPidsSelfLocked.get(startResult.pid);
3981            }
3982            // If there is already an app occupying that pid that hasn't been cleaned up
3983            if (oldApp != null && !app.isolated) {
3984                // Clean up anything relating to this pid first
3985                Slog.w(TAG, "Reusing pid " + startResult.pid
3986                        + " while app is still mapped to it");
3987                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3988                        true /*replacingPid*/);
3989            }
3990            synchronized (mPidsSelfLocked) {
3991                this.mPidsSelfLocked.put(startResult.pid, app);
3992                if (isActivityProcess) {
3993                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3994                    msg.obj = app;
3995                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3996                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3997                }
3998            }
3999            checkTime(startTime, "startProcess: done updating pids map");
4000        } catch (RuntimeException e) {
4001            Slog.e(TAG, "Failure starting process " + app.processName, e);
4002
4003            // Something went very wrong while trying to start this process; one
4004            // common case is when the package is frozen due to an active
4005            // upgrade. To recover, clean up any active bookkeeping related to
4006            // starting this process. (We already invoked this method once when
4007            // the package was initially frozen through KILL_APPLICATION_MSG, so
4008            // it doesn't hurt to use it again.)
4009            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4010                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4011        }
4012    }
4013
4014    void updateUsageStats(ActivityRecord component, boolean resumed) {
4015        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4016                "updateUsageStats: comp=" + component + "res=" + resumed);
4017        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4018        if (resumed) {
4019            if (mUsageStatsService != null) {
4020                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4021                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4022            }
4023            synchronized (stats) {
4024                stats.noteActivityResumedLocked(component.app.uid);
4025            }
4026        } else {
4027            if (mUsageStatsService != null) {
4028                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4029                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4030            }
4031            synchronized (stats) {
4032                stats.noteActivityPausedLocked(component.app.uid);
4033            }
4034        }
4035    }
4036
4037    Intent getHomeIntent() {
4038        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4039        intent.setComponent(mTopComponent);
4040        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4041        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4042            intent.addCategory(Intent.CATEGORY_HOME);
4043        }
4044        return intent;
4045    }
4046
4047    boolean startHomeActivityLocked(int userId, String reason) {
4048        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4049                && mTopAction == null) {
4050            // We are running in factory test mode, but unable to find
4051            // the factory test app, so just sit around displaying the
4052            // error message and don't try to start anything.
4053            return false;
4054        }
4055        Intent intent = getHomeIntent();
4056        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4057        if (aInfo != null) {
4058            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4059            // Don't do this if the home app is currently being
4060            // instrumented.
4061            aInfo = new ActivityInfo(aInfo);
4062            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4063            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4064                    aInfo.applicationInfo.uid, true);
4065            if (app == null || app.instr == null) {
4066                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4067                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4068                // For ANR debugging to verify if the user activity is the one that actually
4069                // launched.
4070                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4071                mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4072            }
4073        } else {
4074            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4075        }
4076
4077        return true;
4078    }
4079
4080    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4081        ActivityInfo ai = null;
4082        ComponentName comp = intent.getComponent();
4083        try {
4084            if (comp != null) {
4085                // Factory test.
4086                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4087            } else {
4088                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4089                        intent,
4090                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4091                        flags, userId);
4092
4093                if (info != null) {
4094                    ai = info.activityInfo;
4095                }
4096            }
4097        } catch (RemoteException e) {
4098            // ignore
4099        }
4100
4101        return ai;
4102    }
4103
4104    /**
4105     * Starts the "new version setup screen" if appropriate.
4106     */
4107    void startSetupActivityLocked() {
4108        // Only do this once per boot.
4109        if (mCheckedForSetup) {
4110            return;
4111        }
4112
4113        // We will show this screen if the current one is a different
4114        // version than the last one shown, and we are not running in
4115        // low-level factory test mode.
4116        final ContentResolver resolver = mContext.getContentResolver();
4117        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4118                Settings.Global.getInt(resolver,
4119                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4120            mCheckedForSetup = true;
4121
4122            // See if we should be showing the platform update setup UI.
4123            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4124            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4125                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4126            if (!ris.isEmpty()) {
4127                final ResolveInfo ri = ris.get(0);
4128                String vers = ri.activityInfo.metaData != null
4129                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4130                        : null;
4131                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4132                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4133                            Intent.METADATA_SETUP_VERSION);
4134                }
4135                String lastVers = Settings.Secure.getString(
4136                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4137                if (vers != null && !vers.equals(lastVers)) {
4138                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4139                    intent.setComponent(new ComponentName(
4140                            ri.activityInfo.packageName, ri.activityInfo.name));
4141                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4142                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4143                            null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4144                }
4145            }
4146        }
4147    }
4148
4149    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4150        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4151    }
4152
4153    void enforceNotIsolatedCaller(String caller) {
4154        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4155            throw new SecurityException("Isolated process not allowed to call " + caller);
4156        }
4157    }
4158
4159    void enforceShellRestriction(String restriction, int userHandle) {
4160        if (Binder.getCallingUid() == SHELL_UID) {
4161            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4162                throw new SecurityException("Shell does not have permission to access user "
4163                        + userHandle);
4164            }
4165        }
4166    }
4167
4168    @Override
4169    public int getFrontActivityScreenCompatMode() {
4170        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4171        synchronized (this) {
4172            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4173        }
4174    }
4175
4176    @Override
4177    public void setFrontActivityScreenCompatMode(int mode) {
4178        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4179                "setFrontActivityScreenCompatMode");
4180        synchronized (this) {
4181            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4182        }
4183    }
4184
4185    @Override
4186    public int getPackageScreenCompatMode(String packageName) {
4187        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4188        synchronized (this) {
4189            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4190        }
4191    }
4192
4193    @Override
4194    public void setPackageScreenCompatMode(String packageName, int mode) {
4195        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4196                "setPackageScreenCompatMode");
4197        synchronized (this) {
4198            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4199        }
4200    }
4201
4202    @Override
4203    public boolean getPackageAskScreenCompat(String packageName) {
4204        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4205        synchronized (this) {
4206            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4207        }
4208    }
4209
4210    @Override
4211    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4212        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4213                "setPackageAskScreenCompat");
4214        synchronized (this) {
4215            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4216        }
4217    }
4218
4219    private boolean hasUsageStatsPermission(String callingPackage) {
4220        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4221                Binder.getCallingUid(), callingPackage);
4222        if (mode == AppOpsManager.MODE_DEFAULT) {
4223            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4224                    == PackageManager.PERMISSION_GRANTED;
4225        }
4226        return mode == AppOpsManager.MODE_ALLOWED;
4227    }
4228
4229    @Override
4230    public int getPackageProcessState(String packageName, String callingPackage) {
4231        if (!hasUsageStatsPermission(callingPackage)) {
4232            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4233                    "getPackageProcessState");
4234        }
4235
4236        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4237        synchronized (this) {
4238            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4239                final ProcessRecord proc = mLruProcesses.get(i);
4240                if (procState > proc.setProcState) {
4241                    if (proc.pkgList.containsKey(packageName) ||
4242                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4243                        procState = proc.setProcState;
4244                    }
4245                }
4246            }
4247        }
4248        return procState;
4249    }
4250
4251    @Override
4252    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4253            throws RemoteException {
4254        synchronized (this) {
4255            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4256            if (app == null) {
4257                throw new IllegalArgumentException("Unknown process: " + process);
4258            }
4259            if (app.thread == null) {
4260                throw new IllegalArgumentException("Process has no app thread");
4261            }
4262            if (app.trimMemoryLevel >= level) {
4263                throw new IllegalArgumentException(
4264                        "Unable to set a higher trim level than current level");
4265            }
4266            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4267                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4268                throw new IllegalArgumentException("Unable to set a background trim level "
4269                    + "on a foreground process");
4270            }
4271            app.thread.scheduleTrimMemory(level);
4272            app.trimMemoryLevel = level;
4273            return true;
4274        }
4275    }
4276
4277    private void dispatchProcessesChanged() {
4278        int N;
4279        synchronized (this) {
4280            N = mPendingProcessChanges.size();
4281            if (mActiveProcessChanges.length < N) {
4282                mActiveProcessChanges = new ProcessChangeItem[N];
4283            }
4284            mPendingProcessChanges.toArray(mActiveProcessChanges);
4285            mPendingProcessChanges.clear();
4286            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4287                    "*** Delivering " + N + " process changes");
4288        }
4289
4290        int i = mProcessObservers.beginBroadcast();
4291        while (i > 0) {
4292            i--;
4293            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4294            if (observer != null) {
4295                try {
4296                    for (int j=0; j<N; j++) {
4297                        ProcessChangeItem item = mActiveProcessChanges[j];
4298                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4299                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4300                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4301                                    + item.uid + ": " + item.foregroundActivities);
4302                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4303                                    item.foregroundActivities);
4304                        }
4305                    }
4306                } catch (RemoteException e) {
4307                }
4308            }
4309        }
4310        mProcessObservers.finishBroadcast();
4311
4312        synchronized (this) {
4313            for (int j=0; j<N; j++) {
4314                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4315            }
4316        }
4317    }
4318
4319    private void dispatchProcessDied(int pid, int uid) {
4320        int i = mProcessObservers.beginBroadcast();
4321        while (i > 0) {
4322            i--;
4323            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4324            if (observer != null) {
4325                try {
4326                    observer.onProcessDied(pid, uid);
4327                } catch (RemoteException e) {
4328                }
4329            }
4330        }
4331        mProcessObservers.finishBroadcast();
4332    }
4333
4334    @VisibleForTesting
4335    void dispatchUidsChanged() {
4336        int N;
4337        synchronized (this) {
4338            N = mPendingUidChanges.size();
4339            if (mActiveUidChanges.length < N) {
4340                mActiveUidChanges = new UidRecord.ChangeItem[N];
4341            }
4342            for (int i=0; i<N; i++) {
4343                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4344                mActiveUidChanges[i] = change;
4345                if (change.uidRecord != null) {
4346                    change.uidRecord.pendingChange = null;
4347                    change.uidRecord = null;
4348                }
4349            }
4350            mPendingUidChanges.clear();
4351            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4352                    "*** Delivering " + N + " uid changes");
4353        }
4354
4355        int i = mUidObservers.beginBroadcast();
4356        while (i > 0) {
4357            i--;
4358            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4359                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4360        }
4361        mUidObservers.finishBroadcast();
4362
4363        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4364            for (int j = 0; j < N; ++j) {
4365                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4366                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4367                    mValidateUids.remove(item.uid);
4368                } else {
4369                    UidRecord validateUid = mValidateUids.get(item.uid);
4370                    if (validateUid == null) {
4371                        validateUid = new UidRecord(item.uid);
4372                        mValidateUids.put(item.uid, validateUid);
4373                    }
4374                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4375                        validateUid.idle = true;
4376                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4377                        validateUid.idle = false;
4378                    }
4379                    validateUid.curProcState = validateUid.setProcState = item.processState;
4380                    validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4381                }
4382            }
4383        }
4384
4385        synchronized (this) {
4386            for (int j = 0; j < N; j++) {
4387                mAvailUidChanges.add(mActiveUidChanges[j]);
4388            }
4389        }
4390    }
4391
4392    private void dispatchUidsChangedForObserver(IUidObserver observer,
4393            UidObserverRegistration reg, int changesSize) {
4394        if (observer == null) {
4395            return;
4396        }
4397        try {
4398            for (int j = 0; j < changesSize; j++) {
4399                UidRecord.ChangeItem item = mActiveUidChanges[j];
4400                final int change = item.change;
4401                if (change == UidRecord.CHANGE_PROCSTATE &&
4402                        (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4403                    // No-op common case: no significant change, the observer is not
4404                    // interested in all proc state changes.
4405                    continue;
4406                }
4407                if ((change & UidRecord.CHANGE_IDLE) != 0) {
4408                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4409                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4410                                "UID idle uid=" + item.uid);
4411                        observer.onUidIdle(item.uid, item.ephemeral);
4412                    }
4413                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4414                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4415                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4416                                "UID active uid=" + item.uid);
4417                        observer.onUidActive(item.uid);
4418                    }
4419                }
4420                if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4421                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
4422                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4423                                "UID cached uid=" + item.uid);
4424                        observer.onUidCachedChanged(item.uid, true);
4425                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4426                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4427                                "UID active uid=" + item.uid);
4428                        observer.onUidCachedChanged(item.uid, false);
4429                    }
4430                }
4431                if ((change & UidRecord.CHANGE_GONE) != 0) {
4432                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4433                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4434                                "UID gone uid=" + item.uid);
4435                        observer.onUidGone(item.uid, item.ephemeral);
4436                    }
4437                    if (reg.lastProcStates != null) {
4438                        reg.lastProcStates.delete(item.uid);
4439                    }
4440                } else {
4441                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4442                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4443                                "UID CHANGED uid=" + item.uid
4444                                        + ": " + item.processState);
4445                        boolean doReport = true;
4446                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4447                            final int lastState = reg.lastProcStates.get(item.uid,
4448                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4449                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4450                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4451                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4452                                doReport = lastAboveCut != newAboveCut;
4453                            } else {
4454                                doReport = item.processState
4455                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4456                            }
4457                        }
4458                        if (doReport) {
4459                            if (reg.lastProcStates != null) {
4460                                reg.lastProcStates.put(item.uid, item.processState);
4461                            }
4462                            observer.onUidStateChanged(item.uid, item.processState,
4463                                    item.procStateSeq);
4464                        }
4465                    }
4466                }
4467            }
4468        } catch (RemoteException e) {
4469        }
4470    }
4471
4472    void dispatchOomAdjObserver(String msg) {
4473        OomAdjObserver observer;
4474        synchronized (this) {
4475            observer = mCurOomAdjObserver;
4476        }
4477
4478        if (observer != null) {
4479            observer.onOomAdjMessage(msg);
4480        }
4481    }
4482
4483    void setOomAdjObserver(int uid, OomAdjObserver observer) {
4484        synchronized (this) {
4485            mCurOomAdjUid = uid;
4486            mCurOomAdjObserver = observer;
4487        }
4488    }
4489
4490    void clearOomAdjObserver() {
4491        synchronized (this) {
4492            mCurOomAdjUid = -1;
4493            mCurOomAdjObserver = null;
4494        }
4495    }
4496
4497    void reportOomAdjMessageLocked(String tag, String msg) {
4498        Slog.d(tag, msg);
4499        if (mCurOomAdjObserver != null) {
4500            mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4501        }
4502    }
4503
4504    @Override
4505    public final int startActivity(IApplicationThread caller, String callingPackage,
4506            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4507            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4508        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4509                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4510                UserHandle.getCallingUserId());
4511    }
4512
4513    @Override
4514    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4515            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4516            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4517        enforceNotIsolatedCaller("startActivity");
4518        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4519                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4520        // TODO: Switch to user app stacks here.
4521        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4522                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4523                profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4524    }
4525
4526    @Override
4527    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4528            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4529            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4530            int userId) {
4531
4532        // This is very dangerous -- it allows you to perform a start activity (including
4533        // permission grants) as any app that may launch one of your own activities.  So
4534        // we will only allow this to be done from activities that are part of the core framework,
4535        // and then only when they are running as the system.
4536        final ActivityRecord sourceRecord;
4537        final int targetUid;
4538        final String targetPackage;
4539        synchronized (this) {
4540            if (resultTo == null) {
4541                throw new SecurityException("Must be called from an activity");
4542            }
4543            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4544            if (sourceRecord == null) {
4545                throw new SecurityException("Called with bad activity token: " + resultTo);
4546            }
4547            if (!sourceRecord.info.packageName.equals("android")) {
4548                throw new SecurityException(
4549                        "Must be called from an activity that is declared in the android package");
4550            }
4551            if (sourceRecord.app == null) {
4552                throw new SecurityException("Called without a process attached to activity");
4553            }
4554            if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4555                // This is still okay, as long as this activity is running under the
4556                // uid of the original calling activity.
4557                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4558                    throw new SecurityException(
4559                            "Calling activity in uid " + sourceRecord.app.uid
4560                                    + " must be system uid or original calling uid "
4561                                    + sourceRecord.launchedFromUid);
4562                }
4563            }
4564            if (ignoreTargetSecurity) {
4565                if (intent.getComponent() == null) {
4566                    throw new SecurityException(
4567                            "Component must be specified with ignoreTargetSecurity");
4568                }
4569                if (intent.getSelector() != null) {
4570                    throw new SecurityException(
4571                            "Selector not allowed with ignoreTargetSecurity");
4572                }
4573            }
4574            targetUid = sourceRecord.launchedFromUid;
4575            targetPackage = sourceRecord.launchedFromPackage;
4576        }
4577
4578        if (userId == UserHandle.USER_NULL) {
4579            userId = UserHandle.getUserId(sourceRecord.app.uid);
4580        }
4581
4582        // TODO: Switch to user app stacks here.
4583        try {
4584            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4585                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4586                    null, null, bOptions, ignoreTargetSecurity, userId, null,
4587                    "startActivityAsCaller");
4588            return ret;
4589        } catch (SecurityException e) {
4590            // XXX need to figure out how to propagate to original app.
4591            // A SecurityException here is generally actually a fault of the original
4592            // calling activity (such as a fairly granting permissions), so propagate it
4593            // back to them.
4594            /*
4595            StringBuilder msg = new StringBuilder();
4596            msg.append("While launching");
4597            msg.append(intent.toString());
4598            msg.append(": ");
4599            msg.append(e.getMessage());
4600            */
4601            throw e;
4602        }
4603    }
4604
4605    @Override
4606    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4607            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4608            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4609        enforceNotIsolatedCaller("startActivityAndWait");
4610        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4611                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4612        WaitResult res = new WaitResult();
4613        // TODO: Switch to user app stacks here.
4614        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4615                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4616                bOptions, false, userId, null, "startActivityAndWait");
4617        return res;
4618    }
4619
4620    @Override
4621    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4622            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4623            int startFlags, Configuration config, Bundle bOptions, int userId) {
4624        enforceNotIsolatedCaller("startActivityWithConfig");
4625        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4626                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4627        // TODO: Switch to user app stacks here.
4628        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4629                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4630                null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4631        return ret;
4632    }
4633
4634    @Override
4635    public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4636            IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4637            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4638            throws TransactionTooLargeException {
4639        enforceNotIsolatedCaller("startActivityIntentSender");
4640        // Refuse possible leaked file descriptors
4641        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4642            throw new IllegalArgumentException("File descriptors passed in Intent");
4643        }
4644
4645        if (!(target instanceof PendingIntentRecord)) {
4646            throw new IllegalArgumentException("Bad PendingIntent object");
4647        }
4648
4649        PendingIntentRecord pir = (PendingIntentRecord)target;
4650
4651        synchronized (this) {
4652            // If this is coming from the currently resumed activity, it is
4653            // effectively saying that app switches are allowed at this point.
4654            final ActivityStack stack = getFocusedStack();
4655            if (stack.mResumedActivity != null &&
4656                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4657                mAppSwitchesAllowedTime = 0;
4658            }
4659        }
4660        int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4661                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4662        return ret;
4663    }
4664
4665    @Override
4666    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4667            Intent intent, String resolvedType, IVoiceInteractionSession session,
4668            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4669            Bundle bOptions, int userId) {
4670        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4671                != PackageManager.PERMISSION_GRANTED) {
4672            String msg = "Permission Denial: startVoiceActivity() from pid="
4673                    + Binder.getCallingPid()
4674                    + ", uid=" + Binder.getCallingUid()
4675                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4676            Slog.w(TAG, msg);
4677            throw new SecurityException(msg);
4678        }
4679        if (session == null || interactor == null) {
4680            throw new NullPointerException("null session or interactor");
4681        }
4682        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4683                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4684        // TODO: Switch to user app stacks here.
4685        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4686                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4687                null, bOptions, false, userId, null, "startVoiceActivity");
4688    }
4689
4690    @Override
4691    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4692            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4693        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4694                != PackageManager.PERMISSION_GRANTED) {
4695            final String msg = "Permission Denial: startAssistantActivity() from pid="
4696                    + Binder.getCallingPid()
4697                    + ", uid=" + Binder.getCallingUid()
4698                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4699            Slog.w(TAG, msg);
4700            throw new SecurityException(msg);
4701        }
4702        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4703                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4704        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4705                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4706                userId, null, "startAssistantActivity");
4707    }
4708
4709    @Override
4710    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4711            throws RemoteException {
4712        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4713        synchronized (this) {
4714            ActivityRecord activity = getFocusedStack().topActivity();
4715            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4716                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4717            }
4718            if (mRunningVoice != null || activity.getTask().voiceSession != null
4719                    || activity.voiceSession != null) {
4720                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4721                return;
4722            }
4723            if (activity.pendingVoiceInteractionStart) {
4724                Slog.w(TAG, "Pending start of voice interaction already.");
4725                return;
4726            }
4727            activity.pendingVoiceInteractionStart = true;
4728        }
4729        LocalServices.getService(VoiceInteractionManagerInternal.class)
4730                .startLocalVoiceInteraction(callingActivity, options);
4731    }
4732
4733    @Override
4734    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4735        LocalServices.getService(VoiceInteractionManagerInternal.class)
4736                .stopLocalVoiceInteraction(callingActivity);
4737    }
4738
4739    @Override
4740    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4741        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4742                .supportsLocalVoiceInteraction();
4743    }
4744
4745    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4746            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4747        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4748        if (activityToCallback == null) return;
4749        activityToCallback.setVoiceSessionLocked(voiceSession);
4750
4751        // Inform the activity
4752        try {
4753            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4754                    voiceInteractor);
4755            long token = Binder.clearCallingIdentity();
4756            try {
4757                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4758            } finally {
4759                Binder.restoreCallingIdentity(token);
4760            }
4761            // TODO: VI Should we cache the activity so that it's easier to find later
4762            // rather than scan through all the stacks and activities?
4763        } catch (RemoteException re) {
4764            activityToCallback.clearVoiceSessionLocked();
4765            // TODO: VI Should this terminate the voice session?
4766        }
4767    }
4768
4769    @Override
4770    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4771        synchronized (this) {
4772            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4773                if (keepAwake) {
4774                    mVoiceWakeLock.acquire();
4775                } else {
4776                    mVoiceWakeLock.release();
4777                }
4778            }
4779        }
4780    }
4781
4782    @Override
4783    public boolean startNextMatchingActivity(IBinder callingActivity,
4784            Intent intent, Bundle bOptions) {
4785        // Refuse possible leaked file descriptors
4786        if (intent != null && intent.hasFileDescriptors() == true) {
4787            throw new IllegalArgumentException("File descriptors passed in Intent");
4788        }
4789        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4790
4791        synchronized (this) {
4792            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4793            if (r == null) {
4794                ActivityOptions.abort(options);
4795                return false;
4796            }
4797            if (r.app == null || r.app.thread == null) {
4798                // The caller is not running...  d'oh!
4799                ActivityOptions.abort(options);
4800                return false;
4801            }
4802            intent = new Intent(intent);
4803            // The caller is not allowed to change the data.
4804            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4805            // And we are resetting to find the next component...
4806            intent.setComponent(null);
4807
4808            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4809
4810            ActivityInfo aInfo = null;
4811            try {
4812                List<ResolveInfo> resolves =
4813                    AppGlobals.getPackageManager().queryIntentActivities(
4814                            intent, r.resolvedType,
4815                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4816                            UserHandle.getCallingUserId()).getList();
4817
4818                // Look for the original activity in the list...
4819                final int N = resolves != null ? resolves.size() : 0;
4820                for (int i=0; i<N; i++) {
4821                    ResolveInfo rInfo = resolves.get(i);
4822                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4823                            && rInfo.activityInfo.name.equals(r.info.name)) {
4824                        // We found the current one...  the next matching is
4825                        // after it.
4826                        i++;
4827                        if (i<N) {
4828                            aInfo = resolves.get(i).activityInfo;
4829                        }
4830                        if (debug) {
4831                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4832                                    + "/" + r.info.name);
4833                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4834                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4835                        }
4836                        break;
4837                    }
4838                }
4839            } catch (RemoteException e) {
4840            }
4841
4842            if (aInfo == null) {
4843                // Nobody who is next!
4844                ActivityOptions.abort(options);
4845                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4846                return false;
4847            }
4848
4849            intent.setComponent(new ComponentName(
4850                    aInfo.applicationInfo.packageName, aInfo.name));
4851            intent.setFlags(intent.getFlags()&~(
4852                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4853                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4854                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4855                    Intent.FLAG_ACTIVITY_NEW_TASK));
4856
4857            // Okay now we need to start the new activity, replacing the
4858            // currently running activity.  This is a little tricky because
4859            // we want to start the new one as if the current one is finished,
4860            // but not finish the current one first so that there is no flicker.
4861            // And thus...
4862            final boolean wasFinishing = r.finishing;
4863            r.finishing = true;
4864
4865            // Propagate reply information over to the new activity.
4866            final ActivityRecord resultTo = r.resultTo;
4867            final String resultWho = r.resultWho;
4868            final int requestCode = r.requestCode;
4869            r.resultTo = null;
4870            if (resultTo != null) {
4871                resultTo.removeResultsLocked(r, resultWho, requestCode);
4872            }
4873
4874            final long origId = Binder.clearCallingIdentity();
4875            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4876                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4877                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4878                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4879                    false, false, null, null, "startNextMatchingActivity");
4880            Binder.restoreCallingIdentity(origId);
4881
4882            r.finishing = wasFinishing;
4883            if (res != ActivityManager.START_SUCCESS) {
4884                return false;
4885            }
4886            return true;
4887        }
4888    }
4889
4890    @Override
4891    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4892        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4893            String msg = "Permission Denial: startActivityFromRecents called without " +
4894                    START_TASKS_FROM_RECENTS;
4895            Slog.w(TAG, msg);
4896            throw new SecurityException(msg);
4897        }
4898        final long origId = Binder.clearCallingIdentity();
4899        try {
4900            synchronized (this) {
4901                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4902            }
4903        } finally {
4904            Binder.restoreCallingIdentity(origId);
4905        }
4906    }
4907
4908    final int startActivityInPackage(int uid, String callingPackage,
4909            Intent intent, String resolvedType, IBinder resultTo,
4910            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4911            TaskRecord inTask, String reason) {
4912
4913        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4914                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4915
4916        // TODO: Switch to user app stacks here.
4917        return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4918                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4919                null, null, null, bOptions, false, userId, inTask, reason);
4920    }
4921
4922    @Override
4923    public final int startActivities(IApplicationThread caller, String callingPackage,
4924            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4925            int userId) {
4926        final String reason = "startActivities";
4927        enforceNotIsolatedCaller(reason);
4928        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4929                userId, false, ALLOW_FULL_ONLY, reason, null);
4930        // TODO: Switch to user app stacks here.
4931        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4932                resolvedTypes, resultTo, bOptions, userId, reason);
4933        return ret;
4934    }
4935
4936    final int startActivitiesInPackage(int uid, String callingPackage,
4937            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4938            Bundle bOptions, int userId) {
4939
4940        final String reason = "startActivityInPackage";
4941        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4942                userId, false, ALLOW_FULL_ONLY, reason, null);
4943        // TODO: Switch to user app stacks here.
4944        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4945                resultTo, bOptions, userId, reason);
4946        return ret;
4947    }
4948
4949    @Override
4950    public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4951        synchronized (this) {
4952            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4953            if (r == null) {
4954                return;
4955            }
4956            r.reportFullyDrawnLocked(restoredFromBundle);
4957        }
4958    }
4959
4960    @Override
4961    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4962        synchronized (this) {
4963            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4964            if (r == null) {
4965                return;
4966            }
4967            final long origId = Binder.clearCallingIdentity();
4968            try {
4969                r.setRequestedOrientation(requestedOrientation);
4970            } finally {
4971                Binder.restoreCallingIdentity(origId);
4972            }
4973        }
4974    }
4975
4976    @Override
4977    public int getRequestedOrientation(IBinder token) {
4978        synchronized (this) {
4979            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4980            if (r == null) {
4981                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4982            }
4983            return r.getRequestedOrientation();
4984        }
4985    }
4986
4987    @Override
4988    public final void requestActivityRelaunch(IBinder token) {
4989        synchronized(this) {
4990            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4991            if (r == null) {
4992                return;
4993            }
4994            final long origId = Binder.clearCallingIdentity();
4995            try {
4996                r.forceNewConfig = true;
4997                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4998                        true /* preserveWindow */);
4999            } finally {
5000                Binder.restoreCallingIdentity(origId);
5001            }
5002        }
5003    }
5004
5005    /**
5006     * This is the internal entry point for handling Activity.finish().
5007     *
5008     * @param token The Binder token referencing the Activity we want to finish.
5009     * @param resultCode Result code, if any, from this Activity.
5010     * @param resultData Result data (Intent), if any, from this Activity.
5011     * @param finishTask Whether to finish the task associated with this Activity.
5012     *
5013     * @return Returns true if the activity successfully finished, or false if it is still running.
5014     */
5015    @Override
5016    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5017            int finishTask) {
5018        // Refuse possible leaked file descriptors
5019        if (resultData != null && resultData.hasFileDescriptors() == true) {
5020            throw new IllegalArgumentException("File descriptors passed in Intent");
5021        }
5022
5023        synchronized(this) {
5024            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5025            if (r == null) {
5026                return true;
5027            }
5028            // Keep track of the root activity of the task before we finish it
5029            TaskRecord tr = r.getTask();
5030            ActivityRecord rootR = tr.getRootActivity();
5031            if (rootR == null) {
5032                Slog.w(TAG, "Finishing task with all activities already finished");
5033            }
5034            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5035            // finish.
5036            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5037                    mStackSupervisor.isLastLockedTask(tr)) {
5038                Slog.i(TAG, "Not finishing task in lock task mode");
5039                mStackSupervisor.showLockTaskToast();
5040                return false;
5041            }
5042            if (mController != null) {
5043                // Find the first activity that is not finishing.
5044                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5045                if (next != null) {
5046                    // ask watcher if this is allowed
5047                    boolean resumeOK = true;
5048                    try {
5049                        resumeOK = mController.activityResuming(next.packageName);
5050                    } catch (RemoteException e) {
5051                        mController = null;
5052                        Watchdog.getInstance().setActivityController(null);
5053                    }
5054
5055                    if (!resumeOK) {
5056                        Slog.i(TAG, "Not finishing activity because controller resumed");
5057                        return false;
5058                    }
5059                }
5060            }
5061            final long origId = Binder.clearCallingIdentity();
5062            try {
5063                boolean res;
5064                final boolean finishWithRootActivity =
5065                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5066                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5067                        || (finishWithRootActivity && r == rootR)) {
5068                    // If requested, remove the task that is associated to this activity only if it
5069                    // was the root activity in the task. The result code and data is ignored
5070                    // because we don't support returning them across task boundaries. Also, to
5071                    // keep backwards compatibility we remove the task from recents when finishing
5072                    // task with root activity.
5073                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5074                    if (!res) {
5075                        Slog.i(TAG, "Removing task failed to finish activity");
5076                    }
5077                } else {
5078                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5079                            resultData, "app-request", true);
5080                    if (!res) {
5081                        Slog.i(TAG, "Failed to finish by app-request");
5082                    }
5083                }
5084                return res;
5085            } finally {
5086                Binder.restoreCallingIdentity(origId);
5087            }
5088        }
5089    }
5090
5091    @Override
5092    public final void finishHeavyWeightApp() {
5093        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5094                != PackageManager.PERMISSION_GRANTED) {
5095            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5096                    + Binder.getCallingPid()
5097                    + ", uid=" + Binder.getCallingUid()
5098                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5099            Slog.w(TAG, msg);
5100            throw new SecurityException(msg);
5101        }
5102
5103        synchronized(this) {
5104            if (mHeavyWeightProcess == null) {
5105                return;
5106            }
5107
5108            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5109            for (int i = 0; i < activities.size(); i++) {
5110                ActivityRecord r = activities.get(i);
5111                if (!r.finishing && r.isInStackLocked()) {
5112                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5113                            null, "finish-heavy", true);
5114                }
5115            }
5116
5117            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5118                    mHeavyWeightProcess.userId, 0));
5119            mHeavyWeightProcess = null;
5120        }
5121    }
5122
5123    @Override
5124    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5125            String message) {
5126        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5127                != PackageManager.PERMISSION_GRANTED) {
5128            String msg = "Permission Denial: crashApplication() from pid="
5129                    + Binder.getCallingPid()
5130                    + ", uid=" + Binder.getCallingUid()
5131                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5132            Slog.w(TAG, msg);
5133            throw new SecurityException(msg);
5134        }
5135
5136        synchronized(this) {
5137            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5138        }
5139    }
5140
5141    @Override
5142    public final void finishSubActivity(IBinder token, String resultWho,
5143            int requestCode) {
5144        synchronized(this) {
5145            final long origId = Binder.clearCallingIdentity();
5146            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5147            if (r != null) {
5148                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5149            }
5150            Binder.restoreCallingIdentity(origId);
5151        }
5152    }
5153
5154    @Override
5155    public boolean finishActivityAffinity(IBinder token) {
5156        synchronized(this) {
5157            final long origId = Binder.clearCallingIdentity();
5158            try {
5159                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5160                if (r == null) {
5161                    return false;
5162                }
5163
5164                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5165                // can finish.
5166                final TaskRecord task = r.getTask();
5167                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5168                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5169                    mStackSupervisor.showLockTaskToast();
5170                    return false;
5171                }
5172                return task.getStack().finishActivityAffinityLocked(r);
5173            } finally {
5174                Binder.restoreCallingIdentity(origId);
5175            }
5176        }
5177    }
5178
5179    @Override
5180    public void finishVoiceTask(IVoiceInteractionSession session) {
5181        synchronized (this) {
5182            final long origId = Binder.clearCallingIdentity();
5183            try {
5184                // TODO: VI Consider treating local voice interactions and voice tasks
5185                // differently here
5186                mStackSupervisor.finishVoiceTask(session);
5187            } finally {
5188                Binder.restoreCallingIdentity(origId);
5189            }
5190        }
5191
5192    }
5193
5194    @Override
5195    public boolean releaseActivityInstance(IBinder token) {
5196        synchronized(this) {
5197            final long origId = Binder.clearCallingIdentity();
5198            try {
5199                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5200                if (r == null) {
5201                    return false;
5202                }
5203                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5204            } finally {
5205                Binder.restoreCallingIdentity(origId);
5206            }
5207        }
5208    }
5209
5210    @Override
5211    public void releaseSomeActivities(IApplicationThread appInt) {
5212        synchronized(this) {
5213            final long origId = Binder.clearCallingIdentity();
5214            try {
5215                ProcessRecord app = getRecordForAppLocked(appInt);
5216                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5217            } finally {
5218                Binder.restoreCallingIdentity(origId);
5219            }
5220        }
5221    }
5222
5223    @Override
5224    public boolean willActivityBeVisible(IBinder token) {
5225        synchronized(this) {
5226            ActivityStack stack = ActivityRecord.getStackLocked(token);
5227            if (stack != null) {
5228                return stack.willActivityBeVisibleLocked(token);
5229            }
5230            return false;
5231        }
5232    }
5233
5234    @Override
5235    public void overridePendingTransition(IBinder token, String packageName,
5236            int enterAnim, int exitAnim) {
5237        synchronized(this) {
5238            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5239            if (self == null) {
5240                return;
5241            }
5242
5243            final long origId = Binder.clearCallingIdentity();
5244
5245            if (self.state == ActivityState.RESUMED
5246                    || self.state == ActivityState.PAUSING) {
5247                mWindowManager.overridePendingAppTransition(packageName,
5248                        enterAnim, exitAnim, null);
5249            }
5250
5251            Binder.restoreCallingIdentity(origId);
5252        }
5253    }
5254
5255    /**
5256     * Main function for removing an existing process from the activity manager
5257     * as a result of that process going away.  Clears out all connections
5258     * to the process.
5259     */
5260    private final void handleAppDiedLocked(ProcessRecord app,
5261            boolean restarting, boolean allowRestart) {
5262        int pid = app.pid;
5263        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5264                false /*replacingPid*/);
5265        if (!kept && !restarting) {
5266            removeLruProcessLocked(app);
5267            if (pid > 0) {
5268                ProcessList.remove(pid);
5269            }
5270        }
5271
5272        if (mProfileProc == app) {
5273            clearProfilerLocked();
5274        }
5275
5276        // Remove this application's activities from active lists.
5277        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5278
5279        app.activities.clear();
5280
5281        if (app.instr != null) {
5282            Slog.w(TAG, "Crash of app " + app.processName
5283                  + " running instrumentation " + app.instr.mClass);
5284            Bundle info = new Bundle();
5285            info.putString("shortMsg", "Process crashed.");
5286            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5287        }
5288
5289        mWindowManager.deferSurfaceLayout();
5290        try {
5291            if (!restarting && hasVisibleActivities
5292                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5293                // If there was nothing to resume, and we are not already restarting this process, but
5294                // there is a visible activity that is hosted by the process...  then make sure all
5295                // visible activities are running, taking care of restarting this process.
5296                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5297            }
5298        } finally {
5299            mWindowManager.continueSurfaceLayout();
5300        }
5301    }
5302
5303    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5304        final IBinder threadBinder = thread.asBinder();
5305        // Find the application record.
5306        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5307            final ProcessRecord rec = mLruProcesses.get(i);
5308            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5309                return i;
5310            }
5311        }
5312        return -1;
5313    }
5314
5315    final ProcessRecord getRecordForAppLocked(
5316            IApplicationThread thread) {
5317        if (thread == null) {
5318            return null;
5319        }
5320
5321        int appIndex = getLRURecordIndexForAppLocked(thread);
5322        if (appIndex >= 0) {
5323            return mLruProcesses.get(appIndex);
5324        }
5325
5326        // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5327        // double-check that.
5328        final IBinder threadBinder = thread.asBinder();
5329        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5330        for (int i = pmap.size()-1; i >= 0; i--) {
5331            final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5332            for (int j = procs.size()-1; j >= 0; j--) {
5333                final ProcessRecord proc = procs.valueAt(j);
5334                if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5335                    Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5336                            + proc);
5337                    return proc;
5338                }
5339            }
5340        }
5341
5342        return null;
5343    }
5344
5345    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5346        // If there are no longer any background processes running,
5347        // and the app that died was not running instrumentation,
5348        // then tell everyone we are now low on memory.
5349        boolean haveBg = false;
5350        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5351            ProcessRecord rec = mLruProcesses.get(i);
5352            if (rec.thread != null
5353                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5354                haveBg = true;
5355                break;
5356            }
5357        }
5358
5359        if (!haveBg) {
5360            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5361            if (doReport) {
5362                long now = SystemClock.uptimeMillis();
5363                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5364                    doReport = false;
5365                } else {
5366                    mLastMemUsageReportTime = now;
5367                }
5368            }
5369            final ArrayList<ProcessMemInfo> memInfos
5370                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5371            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5372            long now = SystemClock.uptimeMillis();
5373            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5374                ProcessRecord rec = mLruProcesses.get(i);
5375                if (rec == dyingProc || rec.thread == null) {
5376                    continue;
5377                }
5378                if (doReport) {
5379                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5380                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5381                }
5382                if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5383                    // The low memory report is overriding any current
5384                    // state for a GC request.  Make sure to do
5385                    // heavy/important/visible/foreground processes first.
5386                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5387                        rec.lastRequestedGc = 0;
5388                    } else {
5389                        rec.lastRequestedGc = rec.lastLowMemory;
5390                    }
5391                    rec.reportLowMemory = true;
5392                    rec.lastLowMemory = now;
5393                    mProcessesToGc.remove(rec);
5394                    addProcessToGcListLocked(rec);
5395                }
5396            }
5397            if (doReport) {
5398                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5399                mHandler.sendMessage(msg);
5400            }
5401            scheduleAppGcsLocked();
5402        }
5403    }
5404
5405    final void appDiedLocked(ProcessRecord app) {
5406       appDiedLocked(app, app.pid, app.thread, false);
5407    }
5408
5409    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5410            boolean fromBinderDied) {
5411        // First check if this ProcessRecord is actually active for the pid.
5412        synchronized (mPidsSelfLocked) {
5413            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5414            if (curProc != app) {
5415                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5416                return;
5417            }
5418        }
5419
5420        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5421        synchronized (stats) {
5422            stats.noteProcessDiedLocked(app.info.uid, pid);
5423        }
5424
5425        if (!app.killed) {
5426            if (!fromBinderDied) {
5427                killProcessQuiet(pid);
5428            }
5429            killProcessGroup(app.uid, pid);
5430            app.killed = true;
5431        }
5432
5433        // Clean up already done if the process has been re-started.
5434        if (app.pid == pid && app.thread != null &&
5435                app.thread.asBinder() == thread.asBinder()) {
5436            boolean doLowMem = app.instr == null;
5437            boolean doOomAdj = doLowMem;
5438            if (!app.killedByAm) {
5439                Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5440                        + ProcessList.makeOomAdjString(app.setAdj)
5441                        + ProcessList.makeProcStateString(app.setProcState));
5442                mAllowLowerMemLevel = true;
5443            } else {
5444                // Note that we always want to do oom adj to update our state with the
5445                // new number of procs.
5446                mAllowLowerMemLevel = false;
5447                doLowMem = false;
5448            }
5449            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5450                    app.setAdj, app.setProcState);
5451            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5452                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5453            handleAppDiedLocked(app, false, true);
5454
5455            if (doOomAdj) {
5456                updateOomAdjLocked();
5457            }
5458            if (doLowMem) {
5459                doLowMemReportIfNeededLocked(app);
5460            }
5461        } else if (app.pid != pid) {
5462            // A new process has already been started.
5463            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5464                    + ") has died and restarted (pid " + app.pid + ").");
5465            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5466        } else if (DEBUG_PROCESSES) {
5467            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5468                    + thread.asBinder());
5469        }
5470    }
5471
5472    /**
5473     * If a stack trace dump file is configured, dump process stack traces.
5474     * @param clearTraces causes the dump file to be erased prior to the new
5475     *    traces being written, if true; when false, the new traces will be
5476     *    appended to any existing file content.
5477     * @param firstPids of dalvik VM processes to dump stack traces for first
5478     * @param lastPids of dalvik VM processes to dump stack traces for last
5479     * @param nativePids optional list of native pids to dump stack crawls
5480     */
5481    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5482            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5483            ArrayList<Integer> nativePids) {
5484        ArrayList<Integer> extraPids = null;
5485
5486        // Measure CPU usage as soon as we're called in order to get a realistic sampling
5487        // of the top users at the time of the request.
5488        if (processCpuTracker != null) {
5489            processCpuTracker.init();
5490            try {
5491                Thread.sleep(200);
5492            } catch (InterruptedException ignored) {
5493            }
5494
5495            processCpuTracker.update();
5496
5497            // We'll take the stack crawls of just the top apps using CPU.
5498            final int N = processCpuTracker.countWorkingStats();
5499            extraPids = new ArrayList<>();
5500            for (int i = 0; i < N && extraPids.size() < 5; i++) {
5501                ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5502                if (lastPids.indexOfKey(stats.pid) >= 0) {
5503                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5504
5505                    extraPids.add(stats.pid);
5506                } else if (DEBUG_ANR) {
5507                    Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5508                            + stats.pid);
5509                }
5510            }
5511        }
5512
5513        boolean useTombstonedForJavaTraces = false;
5514        File tracesFile;
5515
5516        final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5517        if (tracesDirProp.isEmpty()) {
5518            // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5519            // dumping scheme. All traces are written to a global trace file (usually
5520            // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5521            // the file if requested.
5522            //
5523            // This mode of operation will be removed in the near future.
5524
5525
5526            String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5527            if (globalTracesPath.isEmpty()) {
5528                Slog.w(TAG, "dumpStackTraces: no trace path configured");
5529                return null;
5530            }
5531
5532            tracesFile = new File(globalTracesPath);
5533            try {
5534                if (clearTraces && tracesFile.exists()) {
5535                    tracesFile.delete();
5536                }
5537
5538                tracesFile.createNewFile();
5539                FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5540            } catch (IOException e) {
5541                Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5542                return null;
5543            }
5544        } else {
5545            File tracesDir = new File(tracesDirProp);
5546            // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5547            // Each set of ANR traces is written to a separate file and dumpstate will process
5548            // all such files and add them to a captured bug report if they're recent enough.
5549            maybePruneOldTraces(tracesDir);
5550
5551            // NOTE: We should consider creating the file in native code atomically once we've
5552            // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5553            // can be removed.
5554            tracesFile = createAnrDumpFile(tracesDir);
5555            if (tracesFile == null) {
5556                return null;
5557            }
5558
5559            useTombstonedForJavaTraces = true;
5560        }
5561
5562        dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5563                useTombstonedForJavaTraces);
5564        return tracesFile;
5565    }
5566
5567    @GuardedBy("ActivityManagerService.class")
5568    private static SimpleDateFormat sAnrFileDateFormat;
5569
5570    private static synchronized File createAnrDumpFile(File tracesDir) {
5571        if (sAnrFileDateFormat == null) {
5572            sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5573        }
5574
5575        final String formattedDate = sAnrFileDateFormat.format(new Date());
5576        final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5577
5578        try {
5579            if (anrFile.createNewFile()) {
5580                FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5581                return anrFile;
5582            } else {
5583                Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5584            }
5585        } catch (IOException ioe) {
5586            Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5587        }
5588
5589        return null;
5590    }
5591
5592    /**
5593     * Prune all trace files that are more than a day old.
5594     *
5595     * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5596     * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5597     * since it's the system_server that creates trace files for most ANRs.
5598     */
5599    private static void maybePruneOldTraces(File tracesDir) {
5600        final long now = System.currentTimeMillis();
5601        final File[] traceFiles = tracesDir.listFiles();
5602
5603        if (traceFiles != null) {
5604            for (File file : traceFiles) {
5605                if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5606                    if (!file.delete()) {
5607                        Slog.w(TAG, "Unable to prune stale trace file: " + file);
5608                    }
5609                }
5610            }
5611        }
5612    }
5613
5614    /**
5615     * Legacy code, do not use. Existing users will be deleted.
5616     *
5617     * @deprecated
5618     */
5619    @Deprecated
5620    public static class DumpStackFileObserver extends FileObserver {
5621        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5622        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5623
5624        private final String mTracesPath;
5625        private boolean mClosed;
5626
5627        public DumpStackFileObserver(String tracesPath) {
5628            super(tracesPath, FileObserver.CLOSE_WRITE);
5629            mTracesPath = tracesPath;
5630        }
5631
5632        @Override
5633        public synchronized void onEvent(int event, String path) {
5634            mClosed = true;
5635            notify();
5636        }
5637
5638        public long dumpWithTimeout(int pid, long timeout) {
5639            sendSignal(pid, SIGNAL_QUIT);
5640            final long start = SystemClock.elapsedRealtime();
5641
5642            final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5643            synchronized (this) {
5644                try {
5645                    wait(waitTime); // Wait for traces file to be closed.
5646                } catch (InterruptedException e) {
5647                    Slog.wtf(TAG, e);
5648                }
5649            }
5650
5651            // This avoids a corner case of passing a negative time to the native
5652            // trace in case we've already hit the overall timeout.
5653            final long timeWaited = SystemClock.elapsedRealtime() - start;
5654            if (timeWaited >= timeout) {
5655                return timeWaited;
5656            }
5657
5658            if (!mClosed) {
5659                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5660                       ". Attempting native stack collection.");
5661
5662                final long nativeDumpTimeoutMs = Math.min(
5663                        NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5664
5665                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5666                        (int) (nativeDumpTimeoutMs / 1000));
5667            }
5668
5669            final long end = SystemClock.elapsedRealtime();
5670            mClosed = false;
5671
5672            return (end - start);
5673        }
5674    }
5675
5676    /**
5677     * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5678     * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5679     * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5680     * attempting to obtain native traces in the case of a failure. Returns the total time spent
5681     * capturing traces.
5682     */
5683    private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5684        final long timeStart = SystemClock.elapsedRealtime();
5685        if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5686            Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5687                    (NATIVE_DUMP_TIMEOUT_MS / 1000));
5688        }
5689
5690        return SystemClock.elapsedRealtime() - timeStart;
5691    }
5692
5693    private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5694            ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5695            boolean useTombstonedForJavaTraces) {
5696
5697        // We don't need any sort of inotify based monitoring when we're dumping traces via
5698        // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5699        // control of all writes to the file in question.
5700        final DumpStackFileObserver observer;
5701        if (useTombstonedForJavaTraces) {
5702            observer = null;
5703        } else {
5704            // Use a FileObserver to detect when traces finish writing.
5705            // The order of traces is considered important to maintain for legibility.
5706            observer = new DumpStackFileObserver(tracesFile);
5707        }
5708
5709        // We must complete all stack dumps within 20 seconds.
5710        long remainingTime = 20 * 1000;
5711        try {
5712            if (observer != null) {
5713                observer.startWatching();
5714            }
5715
5716            // First collect all of the stacks of the most important pids.
5717            if (firstPids != null) {
5718                int num = firstPids.size();
5719                for (int i = 0; i < num; i++) {
5720                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5721                            + firstPids.get(i));
5722                    final long timeTaken;
5723                    if (useTombstonedForJavaTraces) {
5724                        timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5725                    } else {
5726                        timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5727                    }
5728
5729                    remainingTime -= timeTaken;
5730                    if (remainingTime <= 0) {
5731                        Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5732                            "); deadline exceeded.");
5733                        return;
5734                    }
5735
5736                    if (DEBUG_ANR) {
5737                        Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5738                    }
5739                }
5740            }
5741
5742            // Next collect the stacks of the native pids
5743            if (nativePids != null) {
5744                for (int pid : nativePids) {
5745                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5746                    final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5747
5748                    final long start = SystemClock.elapsedRealtime();
5749                    Debug.dumpNativeBacktraceToFileTimeout(
5750                            pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5751                    final long timeTaken = SystemClock.elapsedRealtime() - start;
5752
5753                    remainingTime -= timeTaken;
5754                    if (remainingTime <= 0) {
5755                        Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5756                            "); deadline exceeded.");
5757                        return;
5758                    }
5759
5760                    if (DEBUG_ANR) {
5761                        Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5762                    }
5763                }
5764            }
5765
5766            // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5767            if (extraPids != null) {
5768                for (int pid : extraPids) {
5769                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5770
5771                    final long timeTaken;
5772                    if (useTombstonedForJavaTraces) {
5773                        timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5774                    } else {
5775                        timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5776                    }
5777
5778                    remainingTime -= timeTaken;
5779                    if (remainingTime <= 0) {
5780                        Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5781                                "); deadline exceeded.");
5782                        return;
5783                    }
5784
5785                    if (DEBUG_ANR) {
5786                        Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5787                    }
5788                }
5789            }
5790        } finally {
5791            if (observer != null) {
5792                observer.stopWatching();
5793            }
5794        }
5795    }
5796
5797    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5798        if (true || Build.IS_USER) {
5799            return;
5800        }
5801        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5802        if (tracesPath == null || tracesPath.length() == 0) {
5803            return;
5804        }
5805
5806        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5807        StrictMode.allowThreadDiskWrites();
5808        try {
5809            final File tracesFile = new File(tracesPath);
5810            final File tracesDir = tracesFile.getParentFile();
5811            final File tracesTmp = new File(tracesDir, "__tmp__");
5812            try {
5813                if (tracesFile.exists()) {
5814                    tracesTmp.delete();
5815                    tracesFile.renameTo(tracesTmp);
5816                }
5817                StringBuilder sb = new StringBuilder();
5818                Time tobj = new Time();
5819                tobj.set(System.currentTimeMillis());
5820                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5821                sb.append(": ");
5822                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5823                sb.append(" since ");
5824                sb.append(msg);
5825                FileOutputStream fos = new FileOutputStream(tracesFile);
5826                fos.write(sb.toString().getBytes());
5827                if (app == null) {
5828                    fos.write("\n*** No application process!".getBytes());
5829                }
5830                fos.close();
5831                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5832            } catch (IOException e) {
5833                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5834                return;
5835            }
5836
5837            if (app != null) {
5838                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5839                firstPids.add(app.pid);
5840                dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5841            }
5842
5843            File lastTracesFile = null;
5844            File curTracesFile = null;
5845            for (int i=9; i>=0; i--) {
5846                String name = String.format(Locale.US, "slow%02d.txt", i);
5847                curTracesFile = new File(tracesDir, name);
5848                if (curTracesFile.exists()) {
5849                    if (lastTracesFile != null) {
5850                        curTracesFile.renameTo(lastTracesFile);
5851                    } else {
5852                        curTracesFile.delete();
5853                    }
5854                }
5855                lastTracesFile = curTracesFile;
5856            }
5857            tracesFile.renameTo(curTracesFile);
5858            if (tracesTmp.exists()) {
5859                tracesTmp.renameTo(tracesFile);
5860            }
5861        } finally {
5862            StrictMode.setThreadPolicy(oldPolicy);
5863        }
5864    }
5865
5866    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5867        if (!mLaunchWarningShown) {
5868            mLaunchWarningShown = true;
5869            mUiHandler.post(new Runnable() {
5870                @Override
5871                public void run() {
5872                    synchronized (ActivityManagerService.this) {
5873                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5874                        d.show();
5875                        mUiHandler.postDelayed(new Runnable() {
5876                            @Override
5877                            public void run() {
5878                                synchronized (ActivityManagerService.this) {
5879                                    d.dismiss();
5880                                    mLaunchWarningShown = false;
5881                                }
5882                            }
5883                        }, 4000);
5884                    }
5885                }
5886            });
5887        }
5888    }
5889
5890    @Override
5891    public boolean clearApplicationUserData(final String packageName,
5892            final IPackageDataObserver observer, int userId) {
5893        enforceNotIsolatedCaller("clearApplicationUserData");
5894        int uid = Binder.getCallingUid();
5895        int pid = Binder.getCallingPid();
5896        final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5897                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5898
5899        final ApplicationInfo appInfo;
5900        final boolean isInstantApp;
5901
5902        long callingId = Binder.clearCallingIdentity();
5903        try {
5904            IPackageManager pm = AppGlobals.getPackageManager();
5905            synchronized(this) {
5906                // Instant packages are not protected
5907                if (getPackageManagerInternalLocked().isPackageDataProtected(
5908                        resolvedUserId, packageName)) {
5909                    throw new SecurityException(
5910                            "Cannot clear data for a protected package: " + packageName);
5911                }
5912
5913                ApplicationInfo applicationInfo = null;
5914                try {
5915                    applicationInfo = pm.getApplicationInfo(packageName,
5916                            MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5917                } catch (RemoteException e) {
5918                    /* ignore */
5919                }
5920                appInfo = applicationInfo;
5921
5922                final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5923
5924                if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5925                        pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5926                    throw new SecurityException("PID " + pid + " does not have permission "
5927                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5928                            + " of package " + packageName);
5929                }
5930
5931                final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5932                        .hasInstantApplicationMetadata(packageName, resolvedUserId);
5933                final boolean isUninstalledAppWithoutInstantMetadata =
5934                        (appInfo == null && !hasInstantMetadata);
5935                isInstantApp = (appInfo != null && appInfo.isInstantApp())
5936                        || hasInstantMetadata;
5937                final boolean canAccessInstantApps = checkComponentPermission(
5938                        permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5939                        == PackageManager.PERMISSION_GRANTED;
5940
5941                if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5942                        && !canAccessInstantApps)) {
5943                    Slog.w(TAG, "Invalid packageName: " + packageName);
5944                    if (observer != null) {
5945                        try {
5946                            observer.onRemoveCompleted(packageName, false);
5947                        } catch (RemoteException e) {
5948                            Slog.i(TAG, "Observer no longer exists.");
5949                        }
5950                    }
5951                    return false;
5952                }
5953
5954                if (appInfo != null) {
5955                    forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5956                    // Remove all tasks match the cleared application package and user
5957                    for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5958                        final TaskRecord tr = mRecentTasks.get(i);
5959                        final String taskPackageName =
5960                                tr.getBaseIntent().getComponent().getPackageName();
5961                        if (tr.userId != resolvedUserId) continue;
5962                        if (!taskPackageName.equals(packageName)) continue;
5963                        mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5964                                REMOVE_FROM_RECENTS);
5965                    }
5966                }
5967            }
5968
5969            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5970                @Override
5971                public void onRemoveCompleted(String packageName, boolean succeeded)
5972                        throws RemoteException {
5973                    if (appInfo != null) {
5974                        synchronized (ActivityManagerService.this) {
5975                            finishForceStopPackageLocked(packageName, appInfo.uid);
5976                        }
5977                    }
5978                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5979                            Uri.fromParts("package", packageName, null));
5980                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5981                    intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
5982                    intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
5983                    if (isInstantApp) {
5984                        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
5985                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5986                                null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
5987                                resolvedUserId);
5988                    } else {
5989                        broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5990                                null, null, null, null, false, false, resolvedUserId);
5991                    }
5992
5993                    if (observer != null) {
5994                        observer.onRemoveCompleted(packageName, succeeded);
5995                    }
5996                }
5997            };
5998
5999            try {
6000                // Clear application user data
6001                pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6002
6003                if (appInfo != null) {
6004                    synchronized (this) {
6005                        // Remove all permissions granted from/to this package
6006                        removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6007                    }
6008
6009                    // Reset notification settings.
6010                    INotificationManager inm = NotificationManager.getService();
6011                    inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6012                }
6013            } catch (RemoteException e) {
6014            }
6015        } finally {
6016            Binder.restoreCallingIdentity(callingId);
6017        }
6018        return true;
6019    }
6020
6021    @Override
6022    public void killBackgroundProcesses(final String packageName, int userId) {
6023        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6024                != PackageManager.PERMISSION_GRANTED &&
6025                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6026                        != PackageManager.PERMISSION_GRANTED) {
6027            String msg = "Permission Denial: killBackgroundProcesses() from pid="
6028                    + Binder.getCallingPid()
6029                    + ", uid=" + Binder.getCallingUid()
6030                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6031            Slog.w(TAG, msg);
6032            throw new SecurityException(msg);
6033        }
6034
6035        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6036                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6037        long callingId = Binder.clearCallingIdentity();
6038        try {
6039            IPackageManager pm = AppGlobals.getPackageManager();
6040            synchronized(this) {
6041                int appId = -1;
6042                try {
6043                    appId = UserHandle.getAppId(
6044                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6045                } catch (RemoteException e) {
6046                }
6047                if (appId == -1) {
6048                    Slog.w(TAG, "Invalid packageName: " + packageName);
6049                    return;
6050                }
6051                killPackageProcessesLocked(packageName, appId, userId,
6052                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6053            }
6054        } finally {
6055            Binder.restoreCallingIdentity(callingId);
6056        }
6057    }
6058
6059    @Override
6060    public void killAllBackgroundProcesses() {
6061        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6062                != PackageManager.PERMISSION_GRANTED) {
6063            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6064                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6065                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6066            Slog.w(TAG, msg);
6067            throw new SecurityException(msg);
6068        }
6069
6070        final long callingId = Binder.clearCallingIdentity();
6071        try {
6072            synchronized (this) {
6073                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6074                final int NP = mProcessNames.getMap().size();
6075                for (int ip = 0; ip < NP; ip++) {
6076                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6077                    final int NA = apps.size();
6078                    for (int ia = 0; ia < NA; ia++) {
6079                        final ProcessRecord app = apps.valueAt(ia);
6080                        if (app.persistent) {
6081                            // We don't kill persistent processes.
6082                            continue;
6083                        }
6084                        if (app.removed) {
6085                            procs.add(app);
6086                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6087                            app.removed = true;
6088                            procs.add(app);
6089                        }
6090                    }
6091                }
6092
6093                final int N = procs.size();
6094                for (int i = 0; i < N; i++) {
6095                    removeProcessLocked(procs.get(i), false, true, "kill all background");
6096                }
6097
6098                mAllowLowerMemLevel = true;
6099
6100                updateOomAdjLocked();
6101                doLowMemReportIfNeededLocked(null);
6102            }
6103        } finally {
6104            Binder.restoreCallingIdentity(callingId);
6105        }
6106    }
6107
6108    /**
6109     * Kills all background processes, except those matching any of the
6110     * specified properties.
6111     *
6112     * @param minTargetSdk the target SDK version at or above which to preserve
6113     *                     processes, or {@code -1} to ignore the target SDK
6114     * @param maxProcState the process state at or below which to preserve
6115     *                     processes, or {@code -1} to ignore the process state
6116     */
6117    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6118        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6119                != PackageManager.PERMISSION_GRANTED) {
6120            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6121                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6122                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6123            Slog.w(TAG, msg);
6124            throw new SecurityException(msg);
6125        }
6126
6127        final long callingId = Binder.clearCallingIdentity();
6128        try {
6129            synchronized (this) {
6130                final ArrayList<ProcessRecord> procs = new ArrayList<>();
6131                final int NP = mProcessNames.getMap().size();
6132                for (int ip = 0; ip < NP; ip++) {
6133                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6134                    final int NA = apps.size();
6135                    for (int ia = 0; ia < NA; ia++) {
6136                        final ProcessRecord app = apps.valueAt(ia);
6137                        if (app.removed) {
6138                            procs.add(app);
6139                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6140                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
6141                            app.removed = true;
6142                            procs.add(app);
6143                        }
6144                    }
6145                }
6146
6147                final int N = procs.size();
6148                for (int i = 0; i < N; i++) {
6149                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
6150                }
6151            }
6152        } finally {
6153            Binder.restoreCallingIdentity(callingId);
6154        }
6155    }
6156
6157    @Override
6158    public void forceStopPackage(final String packageName, int userId) {
6159        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6160                != PackageManager.PERMISSION_GRANTED) {
6161            String msg = "Permission Denial: forceStopPackage() from pid="
6162                    + Binder.getCallingPid()
6163                    + ", uid=" + Binder.getCallingUid()
6164                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6165            Slog.w(TAG, msg);
6166            throw new SecurityException(msg);
6167        }
6168        final int callingPid = Binder.getCallingPid();
6169        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6170                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6171        long callingId = Binder.clearCallingIdentity();
6172        try {
6173            IPackageManager pm = AppGlobals.getPackageManager();
6174            synchronized(this) {
6175                int[] users = userId == UserHandle.USER_ALL
6176                        ? mUserController.getUsers() : new int[] { userId };
6177                for (int user : users) {
6178                    int pkgUid = -1;
6179                    try {
6180                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6181                                user);
6182                    } catch (RemoteException e) {
6183                    }
6184                    if (pkgUid == -1) {
6185                        Slog.w(TAG, "Invalid packageName: " + packageName);
6186                        continue;
6187                    }
6188                    try {
6189                        pm.setPackageStoppedState(packageName, true, user);
6190                    } catch (RemoteException e) {
6191                    } catch (IllegalArgumentException e) {
6192                        Slog.w(TAG, "Failed trying to unstop package "
6193                                + packageName + ": " + e);
6194                    }
6195                    if (mUserController.isUserRunningLocked(user, 0)) {
6196                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6197                        finishForceStopPackageLocked(packageName, pkgUid);
6198                    }
6199                }
6200            }
6201        } finally {
6202            Binder.restoreCallingIdentity(callingId);
6203        }
6204    }
6205
6206    @Override
6207    public void addPackageDependency(String packageName) {
6208        synchronized (this) {
6209            int callingPid = Binder.getCallingPid();
6210            if (callingPid == myPid()) {
6211                //  Yeah, um, no.
6212                return;
6213            }
6214            ProcessRecord proc;
6215            synchronized (mPidsSelfLocked) {
6216                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6217            }
6218            if (proc != null) {
6219                if (proc.pkgDeps == null) {
6220                    proc.pkgDeps = new ArraySet<String>(1);
6221                }
6222                proc.pkgDeps.add(packageName);
6223            }
6224        }
6225    }
6226
6227    /*
6228     * The pkg name and app id have to be specified.
6229     */
6230    @Override
6231    public void killApplication(String pkg, int appId, int userId, String reason) {
6232        if (pkg == null) {
6233            return;
6234        }
6235        // Make sure the uid is valid.
6236        if (appId < 0) {
6237            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6238            return;
6239        }
6240        int callerUid = Binder.getCallingUid();
6241        // Only the system server can kill an application
6242        if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6243            // Post an aysnc message to kill the application
6244            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6245            msg.arg1 = appId;
6246            msg.arg2 = userId;
6247            Bundle bundle = new Bundle();
6248            bundle.putString("pkg", pkg);
6249            bundle.putString("reason", reason);
6250            msg.obj = bundle;
6251            mHandler.sendMessage(msg);
6252        } else {
6253            throw new SecurityException(callerUid + " cannot kill pkg: " +
6254                    pkg);
6255        }
6256    }
6257
6258    @Override
6259    public void closeSystemDialogs(String reason) {
6260        enforceNotIsolatedCaller("closeSystemDialogs");
6261
6262        final int pid = Binder.getCallingPid();
6263        final int uid = Binder.getCallingUid();
6264        final long origId = Binder.clearCallingIdentity();
6265        try {
6266            synchronized (this) {
6267                // Only allow this from foreground processes, so that background
6268                // applications can't abuse it to prevent system UI from being shown.
6269                if (uid >= FIRST_APPLICATION_UID) {
6270                    ProcessRecord proc;
6271                    synchronized (mPidsSelfLocked) {
6272                        proc = mPidsSelfLocked.get(pid);
6273                    }
6274                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6275                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6276                                + " from background process " + proc);
6277                        return;
6278                    }
6279                }
6280                closeSystemDialogsLocked(reason);
6281            }
6282        } finally {
6283            Binder.restoreCallingIdentity(origId);
6284        }
6285    }
6286
6287    void closeSystemDialogsLocked(String reason) {
6288        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6289        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6290                | Intent.FLAG_RECEIVER_FOREGROUND);
6291        if (reason != null) {
6292            intent.putExtra("reason", reason);
6293        }
6294        mWindowManager.closeSystemDialogs(reason);
6295
6296        mStackSupervisor.closeSystemDialogsLocked();
6297
6298        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6299                AppOpsManager.OP_NONE, null, false, false,
6300                -1, SYSTEM_UID, UserHandle.USER_ALL);
6301    }
6302
6303    @Override
6304    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6305        enforceNotIsolatedCaller("getProcessMemoryInfo");
6306        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6307        for (int i=pids.length-1; i>=0; i--) {
6308            ProcessRecord proc;
6309            int oomAdj;
6310            synchronized (this) {
6311                synchronized (mPidsSelfLocked) {
6312                    proc = mPidsSelfLocked.get(pids[i]);
6313                    oomAdj = proc != null ? proc.setAdj : 0;
6314                }
6315            }
6316            infos[i] = new Debug.MemoryInfo();
6317            Debug.getMemoryInfo(pids[i], infos[i]);
6318            if (proc != null) {
6319                synchronized (this) {
6320                    if (proc.thread != null && proc.setAdj == oomAdj) {
6321                        // Record this for posterity if the process has been stable.
6322                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6323                                infos[i].getTotalUss(), false, proc.pkgList);
6324                    }
6325                }
6326            }
6327        }
6328        return infos;
6329    }
6330
6331    @Override
6332    public long[] getProcessPss(int[] pids) {
6333        enforceNotIsolatedCaller("getProcessPss");
6334        long[] pss = new long[pids.length];
6335        for (int i=pids.length-1; i>=0; i--) {
6336            ProcessRecord proc;
6337            int oomAdj;
6338            synchronized (this) {
6339                synchronized (mPidsSelfLocked) {
6340                    proc = mPidsSelfLocked.get(pids[i]);
6341                    oomAdj = proc != null ? proc.setAdj : 0;
6342                }
6343            }
6344            long[] tmpUss = new long[1];
6345            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6346            if (proc != null) {
6347                synchronized (this) {
6348                    if (proc.thread != null && proc.setAdj == oomAdj) {
6349                        // Record this for posterity if the process has been stable.
6350                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6351                    }
6352                }
6353            }
6354        }
6355        return pss;
6356    }
6357
6358    @Override
6359    public void killApplicationProcess(String processName, int uid) {
6360        if (processName == null) {
6361            return;
6362        }
6363
6364        int callerUid = Binder.getCallingUid();
6365        // Only the system server can kill an application
6366        if (callerUid == SYSTEM_UID) {
6367            synchronized (this) {
6368                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6369                if (app != null && app.thread != null) {
6370                    try {
6371                        app.thread.scheduleSuicide();
6372                    } catch (RemoteException e) {
6373                        // If the other end already died, then our work here is done.
6374                    }
6375                } else {
6376                    Slog.w(TAG, "Process/uid not found attempting kill of "
6377                            + processName + " / " + uid);
6378                }
6379            }
6380        } else {
6381            throw new SecurityException(callerUid + " cannot kill app process: " +
6382                    processName);
6383        }
6384    }
6385
6386    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6387        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6388                false, true, false, false, UserHandle.getUserId(uid), reason);
6389    }
6390
6391    private void finishForceStopPackageLocked(final String packageName, int uid) {
6392        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6393                Uri.fromParts("package", packageName, null));
6394        if (!mProcessesReady) {
6395            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6396                    | Intent.FLAG_RECEIVER_FOREGROUND);
6397        }
6398        intent.putExtra(Intent.EXTRA_UID, uid);
6399        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6400        broadcastIntentLocked(null, null, intent,
6401                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6402                null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6403    }
6404
6405
6406    private final boolean killPackageProcessesLocked(String packageName, int appId,
6407            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6408            boolean doit, boolean evenPersistent, String reason) {
6409        ArrayList<ProcessRecord> procs = new ArrayList<>();
6410
6411        // Remove all processes this package may have touched: all with the
6412        // same UID (except for the system or root user), and all whose name
6413        // matches the package name.
6414        final int NP = mProcessNames.getMap().size();
6415        for (int ip=0; ip<NP; ip++) {
6416            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6417            final int NA = apps.size();
6418            for (int ia=0; ia<NA; ia++) {
6419                ProcessRecord app = apps.valueAt(ia);
6420                if (app.persistent && !evenPersistent) {
6421                    // we don't kill persistent processes
6422                    continue;
6423                }
6424                if (app.removed) {
6425                    if (doit) {
6426                        procs.add(app);
6427                    }
6428                    continue;
6429                }
6430
6431                // Skip process if it doesn't meet our oom adj requirement.
6432                if (app.setAdj < minOomAdj) {
6433                    continue;
6434                }
6435
6436                // If no package is specified, we call all processes under the
6437                // give user id.
6438                if (packageName == null) {
6439                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6440                        continue;
6441                    }
6442                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6443                        continue;
6444                    }
6445                // Package has been specified, we want to hit all processes
6446                // that match it.  We need to qualify this by the processes
6447                // that are running under the specified app and user ID.
6448                } else {
6449                    final boolean isDep = app.pkgDeps != null
6450                            && app.pkgDeps.contains(packageName);
6451                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6452                        continue;
6453                    }
6454                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6455                        continue;
6456                    }
6457                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6458                        continue;
6459                    }
6460                }
6461
6462                // Process has passed all conditions, kill it!
6463                if (!doit) {
6464                    return true;
6465                }
6466                app.removed = true;
6467                procs.add(app);
6468            }
6469        }
6470
6471        int N = procs.size();
6472        for (int i=0; i<N; i++) {
6473            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6474        }
6475        updateOomAdjLocked();
6476        return N > 0;
6477    }
6478
6479    private void cleanupDisabledPackageComponentsLocked(
6480            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6481
6482        Set<String> disabledClasses = null;
6483        boolean packageDisabled = false;
6484        IPackageManager pm = AppGlobals.getPackageManager();
6485
6486        if (changedClasses == null) {
6487            // Nothing changed...
6488            return;
6489        }
6490
6491        // Determine enable/disable state of the package and its components.
6492        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6493        for (int i = changedClasses.length - 1; i >= 0; i--) {
6494            final String changedClass = changedClasses[i];
6495
6496            if (changedClass.equals(packageName)) {
6497                try {
6498                    // Entire package setting changed
6499                    enabled = pm.getApplicationEnabledSetting(packageName,
6500                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6501                } catch (Exception e) {
6502                    // No such package/component; probably racing with uninstall.  In any
6503                    // event it means we have nothing further to do here.
6504                    return;
6505                }
6506                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6507                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6508                if (packageDisabled) {
6509                    // Entire package is disabled.
6510                    // No need to continue to check component states.
6511                    disabledClasses = null;
6512                    break;
6513                }
6514            } else {
6515                try {
6516                    enabled = pm.getComponentEnabledSetting(
6517                            new ComponentName(packageName, changedClass),
6518                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6519                } catch (Exception e) {
6520                    // As above, probably racing with uninstall.
6521                    return;
6522                }
6523                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6524                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6525                    if (disabledClasses == null) {
6526                        disabledClasses = new ArraySet<>(changedClasses.length);
6527                    }
6528                    disabledClasses.add(changedClass);
6529                }
6530            }
6531        }
6532
6533        if (!packageDisabled && disabledClasses == null) {
6534            // Nothing to do here...
6535            return;
6536        }
6537
6538        // Clean-up disabled activities.
6539        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6540                packageName, disabledClasses, true, false, userId) && mBooted) {
6541            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6542            mStackSupervisor.scheduleIdleLocked();
6543        }
6544
6545        // Clean-up disabled tasks
6546        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6547
6548        // Clean-up disabled services.
6549        mServices.bringDownDisabledPackageServicesLocked(
6550                packageName, disabledClasses, userId, false, killProcess, true);
6551
6552        // Clean-up disabled providers.
6553        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6554        mProviderMap.collectPackageProvidersLocked(
6555                packageName, disabledClasses, true, false, userId, providers);
6556        for (int i = providers.size() - 1; i >= 0; i--) {
6557            removeDyingProviderLocked(null, providers.get(i), true);
6558        }
6559
6560        // Clean-up disabled broadcast receivers.
6561        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6562            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6563                    packageName, disabledClasses, userId, true);
6564        }
6565
6566    }
6567
6568    final boolean clearBroadcastQueueForUserLocked(int userId) {
6569        boolean didSomething = false;
6570        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6571            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6572                    null, null, userId, true);
6573        }
6574        return didSomething;
6575    }
6576
6577    final boolean forceStopPackageLocked(String packageName, int appId,
6578            boolean callerWillRestart, boolean purgeCache, boolean doit,
6579            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6580        int i;
6581
6582        if (userId == UserHandle.USER_ALL && packageName == null) {
6583            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6584        }
6585
6586        if (appId < 0 && packageName != null) {
6587            try {
6588                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6589                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6590            } catch (RemoteException e) {
6591            }
6592        }
6593
6594        if (doit) {
6595            if (packageName != null) {
6596                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6597                        + " user=" + userId + ": " + reason);
6598            } else {
6599                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6600            }
6601
6602            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6603        }
6604
6605        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6606                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6607                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6608
6609        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6610
6611        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6612                packageName, null, doit, evenPersistent, userId)) {
6613            if (!doit) {
6614                return true;
6615            }
6616            didSomething = true;
6617        }
6618
6619        if (mServices.bringDownDisabledPackageServicesLocked(
6620                packageName, null, userId, evenPersistent, true, doit)) {
6621            if (!doit) {
6622                return true;
6623            }
6624            didSomething = true;
6625        }
6626
6627        if (packageName == null) {
6628            // Remove all sticky broadcasts from this user.
6629            mStickyBroadcasts.remove(userId);
6630        }
6631
6632        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6633        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6634                userId, providers)) {
6635            if (!doit) {
6636                return true;
6637            }
6638            didSomething = true;
6639        }
6640        for (i = providers.size() - 1; i >= 0; i--) {
6641            removeDyingProviderLocked(null, providers.get(i), true);
6642        }
6643
6644        // Remove transient permissions granted from/to this package/user
6645        removeUriPermissionsForPackageLocked(packageName, userId, false);
6646
6647        if (doit) {
6648            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6649                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6650                        packageName, null, userId, doit);
6651            }
6652        }
6653
6654        if (packageName == null || uninstalling) {
6655            // Remove pending intents.  For now we only do this when force
6656            // stopping users, because we have some problems when doing this
6657            // for packages -- app widgets are not currently cleaned up for
6658            // such packages, so they can be left with bad pending intents.
6659            if (mIntentSenderRecords.size() > 0) {
6660                Iterator<WeakReference<PendingIntentRecord>> it
6661                        = mIntentSenderRecords.values().iterator();
6662                while (it.hasNext()) {
6663                    WeakReference<PendingIntentRecord> wpir = it.next();
6664                    if (wpir == null) {
6665                        it.remove();
6666                        continue;
6667                    }
6668                    PendingIntentRecord pir = wpir.get();
6669                    if (pir == null) {
6670                        it.remove();
6671                        continue;
6672                    }
6673                    if (packageName == null) {
6674                        // Stopping user, remove all objects for the user.
6675                        if (pir.key.userId != userId) {
6676                            // Not the same user, skip it.
6677                            continue;
6678                        }
6679                    } else {
6680                        if (UserHandle.getAppId(pir.uid) != appId) {
6681                            // Different app id, skip it.
6682                            continue;
6683                        }
6684                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6685                            // Different user, skip it.
6686                            continue;
6687                        }
6688                        if (!pir.key.packageName.equals(packageName)) {
6689                            // Different package, skip it.
6690                            continue;
6691                        }
6692                    }
6693                    if (!doit) {
6694                        return true;
6695                    }
6696                    didSomething = true;
6697                    it.remove();
6698                    makeIntentSenderCanceledLocked(pir);
6699                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6700                        pir.key.activity.pendingResults.remove(pir.ref);
6701                    }
6702                }
6703            }
6704        }
6705
6706        if (doit) {
6707            if (purgeCache && packageName != null) {
6708                AttributeCache ac = AttributeCache.instance();
6709                if (ac != null) {
6710                    ac.removePackage(packageName);
6711                }
6712            }
6713            if (mBooted) {
6714                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6715                mStackSupervisor.scheduleIdleLocked();
6716            }
6717        }
6718
6719        return didSomething;
6720    }
6721
6722    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6723        return removeProcessNameLocked(name, uid, null);
6724    }
6725
6726    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6727            final ProcessRecord expecting) {
6728        ProcessRecord old = mProcessNames.get(name, uid);
6729        // Only actually remove when the currently recorded value matches the
6730        // record that we expected; if it doesn't match then we raced with a
6731        // newly created process and we don't want to destroy the new one.
6732        if ((expecting == null) || (old == expecting)) {
6733            mProcessNames.remove(name, uid);
6734        }
6735        if (old != null && old.uidRecord != null) {
6736            old.uidRecord.numProcs--;
6737            if (old.uidRecord.numProcs == 0) {
6738                // No more processes using this uid, tell clients it is gone.
6739                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6740                        "No more processes in " + old.uidRecord);
6741                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6742                EventLogTags.writeAmUidStopped(uid);
6743                mActiveUids.remove(uid);
6744                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6745            }
6746            old.uidRecord = null;
6747        }
6748        mIsolatedProcesses.remove(uid);
6749        return old;
6750    }
6751
6752    private final void addProcessNameLocked(ProcessRecord proc) {
6753        // We shouldn't already have a process under this name, but just in case we
6754        // need to clean up whatever may be there now.
6755        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6756        if (old == proc && proc.persistent) {
6757            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6758            Slog.w(TAG, "Re-adding persistent process " + proc);
6759        } else if (old != null) {
6760            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6761        }
6762        UidRecord uidRec = mActiveUids.get(proc.uid);
6763        if (uidRec == null) {
6764            uidRec = new UidRecord(proc.uid);
6765            // This is the first appearance of the uid, report it now!
6766            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6767                    "Creating new process uid: " + uidRec);
6768            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6769                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6770                uidRec.setWhitelist = uidRec.curWhitelist = true;
6771            }
6772            uidRec.updateHasInternetPermission();
6773            mActiveUids.put(proc.uid, uidRec);
6774            EventLogTags.writeAmUidRunning(uidRec.uid);
6775            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6776        }
6777        proc.uidRecord = uidRec;
6778
6779        // Reset render thread tid if it was already set, so new process can set it again.
6780        proc.renderThreadTid = 0;
6781        uidRec.numProcs++;
6782        mProcessNames.put(proc.processName, proc.uid, proc);
6783        if (proc.isolated) {
6784            mIsolatedProcesses.put(proc.uid, proc);
6785        }
6786    }
6787
6788    boolean removeProcessLocked(ProcessRecord app,
6789            boolean callerWillRestart, boolean allowRestart, String reason) {
6790        final String name = app.processName;
6791        final int uid = app.uid;
6792        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6793            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6794
6795        ProcessRecord old = mProcessNames.get(name, uid);
6796        if (old != app) {
6797            // This process is no longer active, so nothing to do.
6798            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6799            return false;
6800        }
6801        removeProcessNameLocked(name, uid);
6802        if (mHeavyWeightProcess == app) {
6803            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6804                    mHeavyWeightProcess.userId, 0));
6805            mHeavyWeightProcess = null;
6806        }
6807        boolean needRestart = false;
6808        if (app.pid > 0 && app.pid != MY_PID) {
6809            int pid = app.pid;
6810            synchronized (mPidsSelfLocked) {
6811                mPidsSelfLocked.remove(pid);
6812                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6813            }
6814            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6815            boolean willRestart = false;
6816            if (app.persistent && !app.isolated) {
6817                if (!callerWillRestart) {
6818                    willRestart = true;
6819                } else {
6820                    needRestart = true;
6821                }
6822            }
6823            app.kill(reason, true);
6824            if (app.isolated) {
6825                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6826                getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6827            }
6828            handleAppDiedLocked(app, willRestart, allowRestart);
6829            if (willRestart) {
6830                removeLruProcessLocked(app);
6831                addAppLocked(app.info, null, false, null /* ABI override */);
6832            }
6833        } else {
6834            mRemovedProcesses.add(app);
6835        }
6836
6837        return needRestart;
6838    }
6839
6840    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6841        cleanupAppInLaunchingProvidersLocked(app, true);
6842        removeProcessLocked(app, false, true, "timeout publishing content providers");
6843    }
6844
6845    private final void processStartTimedOutLocked(ProcessRecord app) {
6846        final int pid = app.pid;
6847        boolean gone = false;
6848        synchronized (mPidsSelfLocked) {
6849            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6850            if (knownApp != null && knownApp.thread == null) {
6851                mPidsSelfLocked.remove(pid);
6852                gone = true;
6853            }
6854        }
6855
6856        if (gone) {
6857            Slog.w(TAG, "Process " + app + " failed to attach");
6858            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6859                    pid, app.uid, app.processName);
6860            removeProcessNameLocked(app.processName, app.uid);
6861            if (mHeavyWeightProcess == app) {
6862                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6863                        mHeavyWeightProcess.userId, 0));
6864                mHeavyWeightProcess = null;
6865            }
6866            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6867            // Take care of any launching providers waiting for this process.
6868            cleanupAppInLaunchingProvidersLocked(app, true);
6869            // Take care of any services that are waiting for the process.
6870            mServices.processStartTimedOutLocked(app);
6871            app.kill("start timeout", true);
6872            if (app.isolated) {
6873                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6874            }
6875            removeLruProcessLocked(app);
6876            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6877                Slog.w(TAG, "Unattached app died before backup, skipping");
6878                mHandler.post(new Runnable() {
6879                @Override
6880                    public void run(){
6881                        try {
6882                            IBackupManager bm = IBackupManager.Stub.asInterface(
6883                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6884                            bm.agentDisconnected(app.info.packageName);
6885                        } catch (RemoteException e) {
6886                            // Can't happen; the backup manager is local
6887                        }
6888                    }
6889                });
6890            }
6891            if (isPendingBroadcastProcessLocked(pid)) {
6892                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6893                skipPendingBroadcastLocked(pid);
6894            }
6895        } else {
6896            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6897        }
6898    }
6899
6900    private final boolean attachApplicationLocked(IApplicationThread thread,
6901            int pid) {
6902
6903        // Find the application record that is being attached...  either via
6904        // the pid if we are running in multiple processes, or just pull the
6905        // next app record if we are emulating process with anonymous threads.
6906        ProcessRecord app;
6907        long startTime = SystemClock.uptimeMillis();
6908        if (pid != MY_PID && pid >= 0) {
6909            synchronized (mPidsSelfLocked) {
6910                app = mPidsSelfLocked.get(pid);
6911            }
6912        } else {
6913            app = null;
6914        }
6915
6916        if (app == null) {
6917            Slog.w(TAG, "No pending application record for pid " + pid
6918                    + " (IApplicationThread " + thread + "); dropping process");
6919            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6920            if (pid > 0 && pid != MY_PID) {
6921                killProcessQuiet(pid);
6922                //TODO: killProcessGroup(app.info.uid, pid);
6923            } else {
6924                try {
6925                    thread.scheduleExit();
6926                } catch (Exception e) {
6927                    // Ignore exceptions.
6928                }
6929            }
6930            return false;
6931        }
6932
6933        // If this application record is still attached to a previous
6934        // process, clean it up now.
6935        if (app.thread != null) {
6936            handleAppDiedLocked(app, true, true);
6937        }
6938
6939        // Tell the process all about itself.
6940
6941        if (DEBUG_ALL) Slog.v(
6942                TAG, "Binding process pid " + pid + " to record " + app);
6943
6944        final String processName = app.processName;
6945        try {
6946            AppDeathRecipient adr = new AppDeathRecipient(
6947                    app, pid, thread);
6948            thread.asBinder().linkToDeath(adr, 0);
6949            app.deathRecipient = adr;
6950        } catch (RemoteException e) {
6951            app.resetPackageList(mProcessStats);
6952            startProcessLocked(app, "link fail", processName);
6953            return false;
6954        }
6955
6956        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6957
6958        app.makeActive(thread, mProcessStats);
6959        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6960        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6961        app.forcingToImportant = null;
6962        updateProcessForegroundLocked(app, false, false);
6963        app.hasShownUi = false;
6964        app.debugging = false;
6965        app.cached = false;
6966        app.killedByAm = false;
6967        app.killed = false;
6968
6969
6970        // We carefully use the same state that PackageManager uses for
6971        // filtering, since we use this flag to decide if we need to install
6972        // providers when user is unlocked later
6973        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6974
6975        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6976
6977        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6978        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6979
6980        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6981            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6982            msg.obj = app;
6983            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6984        }
6985
6986        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6987
6988        if (!normalMode) {
6989            Slog.i(TAG, "Launching preboot mode app: " + app);
6990        }
6991
6992        if (DEBUG_ALL) Slog.v(
6993            TAG, "New app record " + app
6994            + " thread=" + thread.asBinder() + " pid=" + pid);
6995        try {
6996            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6997            if (mDebugApp != null && mDebugApp.equals(processName)) {
6998                testMode = mWaitForDebugger
6999                    ? ApplicationThreadConstants.DEBUG_WAIT
7000                    : ApplicationThreadConstants.DEBUG_ON;
7001                app.debugging = true;
7002                if (mDebugTransient) {
7003                    mDebugApp = mOrigDebugApp;
7004                    mWaitForDebugger = mOrigWaitForDebugger;
7005                }
7006            }
7007
7008            ProfilerInfo profilerInfo = null;
7009            String agent = null;
7010            if (mProfileApp != null && mProfileApp.equals(processName)) {
7011                mProfileProc = app;
7012                profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ?
7013                        new ProfilerInfo(mProfilerInfo) : null;
7014                agent = mProfilerInfo != null ? mProfilerInfo.agent : null;
7015            } else if (app.instr != null && app.instr.mProfileFile != null) {
7016                profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7017                        null);
7018            }
7019
7020            boolean enableTrackAllocation = false;
7021            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7022                enableTrackAllocation = true;
7023                mTrackAllocationApp = null;
7024            }
7025
7026            // If the app is being launched for restore or full backup, set it up specially
7027            boolean isRestrictedBackupMode = false;
7028            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7029                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7030                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7031                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7032                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7033            }
7034
7035            if (app.instr != null) {
7036                notifyPackageUse(app.instr.mClass.getPackageName(),
7037                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7038            }
7039            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7040                    + processName + " with config " + getGlobalConfiguration());
7041            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7042            app.compat = compatibilityInfoForPackageLocked(appInfo);
7043
7044            if (profilerInfo != null && profilerInfo.profileFd != null) {
7045                profilerInfo.profileFd = profilerInfo.profileFd.dup();
7046            }
7047
7048            // We deprecated Build.SERIAL and it is not accessible to
7049            // apps that target the v2 security sandbox. Since access to
7050            // the serial is now behind a permission we push down the value.
7051            String buildSerial = appInfo.targetSandboxVersion < 2
7052                    ? sTheRealBuildSerial : Build.UNKNOWN;
7053
7054            // Check if this is a secondary process that should be incorporated into some
7055            // currently active instrumentation.  (Note we do this AFTER all of the profiling
7056            // stuff above because profiling can currently happen only in the primary
7057            // instrumentation process.)
7058            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7059                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7060                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7061                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7062                        if (aInstr.mTargetProcesses.length == 0) {
7063                            // This is the wildcard mode, where every process brought up for
7064                            // the target instrumentation should be included.
7065                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7066                                app.instr = aInstr;
7067                                aInstr.mRunningProcesses.add(app);
7068                            }
7069                        } else {
7070                            for (String proc : aInstr.mTargetProcesses) {
7071                                if (proc.equals(app.processName)) {
7072                                    app.instr = aInstr;
7073                                    aInstr.mRunningProcesses.add(app);
7074                                    break;
7075                                }
7076                            }
7077                        }
7078                    }
7079                }
7080            }
7081
7082            // If we were asked to attach an agent on startup, do so now, before we're binding
7083            // application code.
7084            if (agent != null) {
7085                thread.attachAgent(agent);
7086            }
7087
7088            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7089            mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7090            if (app.instr != null) {
7091                thread.bindApplication(processName, appInfo, providers,
7092                        app.instr.mClass,
7093                        profilerInfo, app.instr.mArguments,
7094                        app.instr.mWatcher,
7095                        app.instr.mUiAutomationConnection, testMode,
7096                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7097                        isRestrictedBackupMode || !normalMode, app.persistent,
7098                        new Configuration(getGlobalConfiguration()), app.compat,
7099                        getCommonServicesLocked(app.isolated),
7100                        mCoreSettingsObserver.getCoreSettingsLocked(),
7101                        buildSerial);
7102            } else {
7103                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7104                        null, null, null, testMode,
7105                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
7106                        isRestrictedBackupMode || !normalMode, app.persistent,
7107                        new Configuration(getGlobalConfiguration()), app.compat,
7108                        getCommonServicesLocked(app.isolated),
7109                        mCoreSettingsObserver.getCoreSettingsLocked(),
7110                        buildSerial);
7111            }
7112
7113            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7114            updateLruProcessLocked(app, false, null);
7115            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7116            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7117        } catch (Exception e) {
7118            // todo: Yikes!  What should we do?  For now we will try to
7119            // start another process, but that could easily get us in
7120            // an infinite loop of restarting processes...
7121            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7122
7123            app.resetPackageList(mProcessStats);
7124            app.unlinkDeathRecipient();
7125            startProcessLocked(app, "bind fail", processName);
7126            return false;
7127        }
7128
7129        // Remove this record from the list of starting applications.
7130        mPersistentStartingProcesses.remove(app);
7131        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7132                "Attach application locked removing on hold: " + app);
7133        mProcessesOnHold.remove(app);
7134
7135        boolean badApp = false;
7136        boolean didSomething = false;
7137
7138        // See if the top visible activity is waiting to run in this process...
7139        if (normalMode) {
7140            try {
7141                if (mStackSupervisor.attachApplicationLocked(app)) {
7142                    didSomething = true;
7143                }
7144            } catch (Exception e) {
7145                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7146                badApp = true;
7147            }
7148        }
7149
7150        // Find any services that should be running in this process...
7151        if (!badApp) {
7152            try {
7153                didSomething |= mServices.attachApplicationLocked(app, processName);
7154                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7155            } catch (Exception e) {
7156                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7157                badApp = true;
7158            }
7159        }
7160
7161        // Check if a next-broadcast receiver is in this process...
7162        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7163            try {
7164                didSomething |= sendPendingBroadcastsLocked(app);
7165                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7166            } catch (Exception e) {
7167                // If the app died trying to launch the receiver we declare it 'bad'
7168                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7169                badApp = true;
7170            }
7171        }
7172
7173        // Check whether the next backup agent is in this process...
7174        if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7175            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7176                    "New app is backup target, launching agent for " + app);
7177            notifyPackageUse(mBackupTarget.appInfo.packageName,
7178                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7179            try {
7180                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7181                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7182                        mBackupTarget.backupMode);
7183            } catch (Exception e) {
7184                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7185                badApp = true;
7186            }
7187        }
7188
7189        if (badApp) {
7190            app.kill("error during init", true);
7191            handleAppDiedLocked(app, false, true);
7192            return false;
7193        }
7194
7195        if (!didSomething) {
7196            updateOomAdjLocked();
7197            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7198        }
7199
7200        return true;
7201    }
7202
7203    @Override
7204    public final void attachApplication(IApplicationThread thread) {
7205        synchronized (this) {
7206            int callingPid = Binder.getCallingPid();
7207            final long origId = Binder.clearCallingIdentity();
7208            attachApplicationLocked(thread, callingPid);
7209            Binder.restoreCallingIdentity(origId);
7210        }
7211    }
7212
7213    @Override
7214    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7215        final long origId = Binder.clearCallingIdentity();
7216        synchronized (this) {
7217            ActivityStack stack = ActivityRecord.getStackLocked(token);
7218            if (stack != null) {
7219                ActivityRecord r =
7220                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7221                                false /* processPausingActivities */, config);
7222                if (stopProfiling) {
7223                    if ((mProfileProc == r.app) && mProfilerInfo != null) {
7224                        clearProfilerLocked();
7225                    }
7226                }
7227            }
7228        }
7229        Binder.restoreCallingIdentity(origId);
7230    }
7231
7232    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7233        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7234                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7235    }
7236
7237    void enableScreenAfterBoot() {
7238        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7239                SystemClock.uptimeMillis());
7240        mWindowManager.enableScreenAfterBoot();
7241
7242        synchronized (this) {
7243            updateEventDispatchingLocked();
7244        }
7245    }
7246
7247    @Override
7248    public void showBootMessage(final CharSequence msg, final boolean always) {
7249        if (Binder.getCallingUid() != myUid()) {
7250            throw new SecurityException();
7251        }
7252        mWindowManager.showBootMessage(msg, always);
7253    }
7254
7255    @Override
7256    public void keyguardGoingAway(int flags) {
7257        enforceNotIsolatedCaller("keyguardGoingAway");
7258        final long token = Binder.clearCallingIdentity();
7259        try {
7260            synchronized (this) {
7261                mKeyguardController.keyguardGoingAway(flags);
7262            }
7263        } finally {
7264            Binder.restoreCallingIdentity(token);
7265        }
7266    }
7267
7268    /**
7269     * @return whther the keyguard is currently locked.
7270     */
7271    boolean isKeyguardLocked() {
7272        return mKeyguardController.isKeyguardLocked();
7273    }
7274
7275    final void finishBooting() {
7276        synchronized (this) {
7277            if (!mBootAnimationComplete) {
7278                mCallFinishBooting = true;
7279                return;
7280            }
7281            mCallFinishBooting = false;
7282        }
7283
7284        ArraySet<String> completedIsas = new ArraySet<String>();
7285        for (String abi : Build.SUPPORTED_ABIS) {
7286            zygoteProcess.establishZygoteConnectionForAbi(abi);
7287            final String instructionSet = VMRuntime.getInstructionSet(abi);
7288            if (!completedIsas.contains(instructionSet)) {
7289                try {
7290                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7291                } catch (InstallerException e) {
7292                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7293                            e.getMessage() +")");
7294                }
7295                completedIsas.add(instructionSet);
7296            }
7297        }
7298
7299        IntentFilter pkgFilter = new IntentFilter();
7300        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7301        pkgFilter.addDataScheme("package");
7302        mContext.registerReceiver(new BroadcastReceiver() {
7303            @Override
7304            public void onReceive(Context context, Intent intent) {
7305                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7306                if (pkgs != null) {
7307                    for (String pkg : pkgs) {
7308                        synchronized (ActivityManagerService.this) {
7309                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7310                                    0, "query restart")) {
7311                                setResultCode(Activity.RESULT_OK);
7312                                return;
7313                            }
7314                        }
7315                    }
7316                }
7317            }
7318        }, pkgFilter);
7319
7320        IntentFilter dumpheapFilter = new IntentFilter();
7321        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7322        mContext.registerReceiver(new BroadcastReceiver() {
7323            @Override
7324            public void onReceive(Context context, Intent intent) {
7325                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7326                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7327                } else {
7328                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7329                }
7330            }
7331        }, dumpheapFilter);
7332
7333        // Let system services know.
7334        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7335
7336        synchronized (this) {
7337            // Ensure that any processes we had put on hold are now started
7338            // up.
7339            final int NP = mProcessesOnHold.size();
7340            if (NP > 0) {
7341                ArrayList<ProcessRecord> procs =
7342                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7343                for (int ip=0; ip<NP; ip++) {
7344                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7345                            + procs.get(ip));
7346                    startProcessLocked(procs.get(ip), "on-hold", null);
7347                }
7348            }
7349
7350            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7351                // Start looking for apps that are abusing wake locks.
7352                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7353                mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7354                // Tell anyone interested that we are done booting!
7355                SystemProperties.set("sys.boot_completed", "1");
7356
7357                // And trigger dev.bootcomplete if we are not showing encryption progress
7358                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7359                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7360                    SystemProperties.set("dev.bootcomplete", "1");
7361                }
7362                mUserController.sendBootCompletedLocked(
7363                        new IIntentReceiver.Stub() {
7364                            @Override
7365                            public void performReceive(Intent intent, int resultCode,
7366                                    String data, Bundle extras, boolean ordered,
7367                                    boolean sticky, int sendingUser) {
7368                                synchronized (ActivityManagerService.this) {
7369                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7370                                            true, false);
7371                                }
7372                            }
7373                        });
7374                scheduleStartProfilesLocked();
7375            }
7376        }
7377    }
7378
7379    @Override
7380    public void bootAnimationComplete() {
7381        final boolean callFinishBooting;
7382        synchronized (this) {
7383            callFinishBooting = mCallFinishBooting;
7384            mBootAnimationComplete = true;
7385        }
7386        if (callFinishBooting) {
7387            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7388            finishBooting();
7389            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7390        }
7391    }
7392
7393    final void ensureBootCompleted() {
7394        boolean booting;
7395        boolean enableScreen;
7396        synchronized (this) {
7397            booting = mBooting;
7398            mBooting = false;
7399            enableScreen = !mBooted;
7400            mBooted = true;
7401        }
7402
7403        if (booting) {
7404            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7405            finishBooting();
7406            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7407        }
7408
7409        if (enableScreen) {
7410            enableScreenAfterBoot();
7411        }
7412    }
7413
7414    @Override
7415    public final void activityResumed(IBinder token) {
7416        final long origId = Binder.clearCallingIdentity();
7417        synchronized(this) {
7418            ActivityRecord.activityResumedLocked(token);
7419            mWindowManager.notifyAppResumedFinished(token);
7420        }
7421        Binder.restoreCallingIdentity(origId);
7422    }
7423
7424    @Override
7425    public final void activityPaused(IBinder token) {
7426        final long origId = Binder.clearCallingIdentity();
7427        synchronized(this) {
7428            ActivityStack stack = ActivityRecord.getStackLocked(token);
7429            if (stack != null) {
7430                stack.activityPausedLocked(token, false);
7431            }
7432        }
7433        Binder.restoreCallingIdentity(origId);
7434    }
7435
7436    @Override
7437    public final void activityStopped(IBinder token, Bundle icicle,
7438            PersistableBundle persistentState, CharSequence description) {
7439        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7440
7441        // Refuse possible leaked file descriptors
7442        if (icicle != null && icicle.hasFileDescriptors()) {
7443            throw new IllegalArgumentException("File descriptors passed in Bundle");
7444        }
7445
7446        final long origId = Binder.clearCallingIdentity();
7447
7448        synchronized (this) {
7449            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7450            if (r != null) {
7451                r.activityStoppedLocked(icicle, persistentState, description);
7452            }
7453        }
7454
7455        trimApplications();
7456
7457        Binder.restoreCallingIdentity(origId);
7458    }
7459
7460    @Override
7461    public final void activityDestroyed(IBinder token) {
7462        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7463        synchronized (this) {
7464            ActivityStack stack = ActivityRecord.getStackLocked(token);
7465            if (stack != null) {
7466                stack.activityDestroyedLocked(token, "activityDestroyed");
7467            }
7468        }
7469    }
7470
7471    @Override
7472    public final void activityRelaunched(IBinder token) {
7473        final long origId = Binder.clearCallingIdentity();
7474        synchronized (this) {
7475            mStackSupervisor.activityRelaunchedLocked(token);
7476        }
7477        Binder.restoreCallingIdentity(origId);
7478    }
7479
7480    @Override
7481    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7482            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7483        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7484                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7485        synchronized (this) {
7486            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7487            if (record == null) {
7488                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7489                        + "found for: " + token);
7490            }
7491            record.setSizeConfigurations(horizontalSizeConfiguration,
7492                    verticalSizeConfigurations, smallestSizeConfigurations);
7493        }
7494    }
7495
7496    @Override
7497    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7498        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7499    }
7500
7501    @Override
7502    public final void notifyEnterAnimationComplete(IBinder token) {
7503        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7504    }
7505
7506    @Override
7507    public String getCallingPackage(IBinder token) {
7508        synchronized (this) {
7509            ActivityRecord r = getCallingRecordLocked(token);
7510            return r != null ? r.info.packageName : null;
7511        }
7512    }
7513
7514    @Override
7515    public ComponentName getCallingActivity(IBinder token) {
7516        synchronized (this) {
7517            ActivityRecord r = getCallingRecordLocked(token);
7518            return r != null ? r.intent.getComponent() : null;
7519        }
7520    }
7521
7522    private ActivityRecord getCallingRecordLocked(IBinder token) {
7523        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7524        if (r == null) {
7525            return null;
7526        }
7527        return r.resultTo;
7528    }
7529
7530    @Override
7531    public ComponentName getActivityClassForToken(IBinder token) {
7532        synchronized(this) {
7533            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7534            if (r == null) {
7535                return null;
7536            }
7537            return r.intent.getComponent();
7538        }
7539    }
7540
7541    @Override
7542    public String getPackageForToken(IBinder token) {
7543        synchronized(this) {
7544            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7545            if (r == null) {
7546                return null;
7547            }
7548            return r.packageName;
7549        }
7550    }
7551
7552    @Override
7553    public boolean isRootVoiceInteraction(IBinder token) {
7554        synchronized(this) {
7555            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7556            if (r == null) {
7557                return false;
7558            }
7559            return r.rootVoiceInteraction;
7560        }
7561    }
7562
7563    @Override
7564    public IIntentSender getIntentSender(int type,
7565            String packageName, IBinder token, String resultWho,
7566            int requestCode, Intent[] intents, String[] resolvedTypes,
7567            int flags, Bundle bOptions, int userId) {
7568        enforceNotIsolatedCaller("getIntentSender");
7569        // Refuse possible leaked file descriptors
7570        if (intents != null) {
7571            if (intents.length < 1) {
7572                throw new IllegalArgumentException("Intents array length must be >= 1");
7573            }
7574            for (int i=0; i<intents.length; i++) {
7575                Intent intent = intents[i];
7576                if (intent != null) {
7577                    if (intent.hasFileDescriptors()) {
7578                        throw new IllegalArgumentException("File descriptors passed in Intent");
7579                    }
7580                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7581                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7582                        throw new IllegalArgumentException(
7583                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7584                    }
7585                    intents[i] = new Intent(intent);
7586                }
7587            }
7588            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7589                throw new IllegalArgumentException(
7590                        "Intent array length does not match resolvedTypes length");
7591            }
7592        }
7593        if (bOptions != null) {
7594            if (bOptions.hasFileDescriptors()) {
7595                throw new IllegalArgumentException("File descriptors passed in options");
7596            }
7597        }
7598
7599        synchronized(this) {
7600            int callingUid = Binder.getCallingUid();
7601            int origUserId = userId;
7602            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7603                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7604                    ALLOW_NON_FULL, "getIntentSender", null);
7605            if (origUserId == UserHandle.USER_CURRENT) {
7606                // We don't want to evaluate this until the pending intent is
7607                // actually executed.  However, we do want to always do the
7608                // security checking for it above.
7609                userId = UserHandle.USER_CURRENT;
7610            }
7611            try {
7612                if (callingUid != 0 && callingUid != SYSTEM_UID) {
7613                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7614                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7615                    if (!UserHandle.isSameApp(callingUid, uid)) {
7616                        String msg = "Permission Denial: getIntentSender() from pid="
7617                            + Binder.getCallingPid()
7618                            + ", uid=" + Binder.getCallingUid()
7619                            + ", (need uid=" + uid + ")"
7620                            + " is not allowed to send as package " + packageName;
7621                        Slog.w(TAG, msg);
7622                        throw new SecurityException(msg);
7623                    }
7624                }
7625
7626                return getIntentSenderLocked(type, packageName, callingUid, userId,
7627                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7628
7629            } catch (RemoteException e) {
7630                throw new SecurityException(e);
7631            }
7632        }
7633    }
7634
7635    IIntentSender getIntentSenderLocked(int type, String packageName,
7636            int callingUid, int userId, IBinder token, String resultWho,
7637            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7638            Bundle bOptions) {
7639        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7640        ActivityRecord activity = null;
7641        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7642            activity = ActivityRecord.isInStackLocked(token);
7643            if (activity == null) {
7644                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7645                return null;
7646            }
7647            if (activity.finishing) {
7648                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7649                return null;
7650            }
7651        }
7652
7653        // We're going to be splicing together extras before sending, so we're
7654        // okay poking into any contained extras.
7655        if (intents != null) {
7656            for (int i = 0; i < intents.length; i++) {
7657                intents[i].setDefusable(true);
7658            }
7659        }
7660        Bundle.setDefusable(bOptions, true);
7661
7662        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7663        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7664        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7665        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7666                |PendingIntent.FLAG_UPDATE_CURRENT);
7667
7668        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7669                type, packageName, activity, resultWho,
7670                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7671        WeakReference<PendingIntentRecord> ref;
7672        ref = mIntentSenderRecords.get(key);
7673        PendingIntentRecord rec = ref != null ? ref.get() : null;
7674        if (rec != null) {
7675            if (!cancelCurrent) {
7676                if (updateCurrent) {
7677                    if (rec.key.requestIntent != null) {
7678                        rec.key.requestIntent.replaceExtras(intents != null ?
7679                                intents[intents.length - 1] : null);
7680                    }
7681                    if (intents != null) {
7682                        intents[intents.length-1] = rec.key.requestIntent;
7683                        rec.key.allIntents = intents;
7684                        rec.key.allResolvedTypes = resolvedTypes;
7685                    } else {
7686                        rec.key.allIntents = null;
7687                        rec.key.allResolvedTypes = null;
7688                    }
7689                }
7690                return rec;
7691            }
7692            makeIntentSenderCanceledLocked(rec);
7693            mIntentSenderRecords.remove(key);
7694        }
7695        if (noCreate) {
7696            return rec;
7697        }
7698        rec = new PendingIntentRecord(this, key, callingUid);
7699        mIntentSenderRecords.put(key, rec.ref);
7700        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7701            if (activity.pendingResults == null) {
7702                activity.pendingResults
7703                        = new HashSet<WeakReference<PendingIntentRecord>>();
7704            }
7705            activity.pendingResults.add(rec.ref);
7706        }
7707        return rec;
7708    }
7709
7710    @Override
7711    public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7712            Intent intent, String resolvedType,
7713            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7714        if (target instanceof PendingIntentRecord) {
7715            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7716                    whitelistToken, finishedReceiver, requiredPermission, options);
7717        } else {
7718            if (intent == null) {
7719                // Weird case: someone has given us their own custom IIntentSender, and now
7720                // they have someone else trying to send to it but of course this isn't
7721                // really a PendingIntent, so there is no base Intent, and the caller isn't
7722                // supplying an Intent... but we never want to dispatch a null Intent to
7723                // a receiver, so um...  let's make something up.
7724                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7725                intent = new Intent(Intent.ACTION_MAIN);
7726            }
7727            try {
7728                target.send(code, intent, resolvedType, whitelistToken, null,
7729                        requiredPermission, options);
7730            } catch (RemoteException e) {
7731            }
7732            // Platform code can rely on getting a result back when the send is done, but if
7733            // this intent sender is from outside of the system we can't rely on it doing that.
7734            // So instead we don't give it the result receiver, and instead just directly
7735            // report the finish immediately.
7736            if (finishedReceiver != null) {
7737                try {
7738                    finishedReceiver.performReceive(intent, 0,
7739                            null, null, false, false, UserHandle.getCallingUserId());
7740                } catch (RemoteException e) {
7741                }
7742            }
7743            return 0;
7744        }
7745    }
7746
7747    @Override
7748    public void cancelIntentSender(IIntentSender sender) {
7749        if (!(sender instanceof PendingIntentRecord)) {
7750            return;
7751        }
7752        synchronized(this) {
7753            PendingIntentRecord rec = (PendingIntentRecord)sender;
7754            try {
7755                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7756                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7757                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7758                    String msg = "Permission Denial: cancelIntentSender() from pid="
7759                        + Binder.getCallingPid()
7760                        + ", uid=" + Binder.getCallingUid()
7761                        + " is not allowed to cancel package "
7762                        + rec.key.packageName;
7763                    Slog.w(TAG, msg);
7764                    throw new SecurityException(msg);
7765                }
7766            } catch (RemoteException e) {
7767                throw new SecurityException(e);
7768            }
7769            cancelIntentSenderLocked(rec, true);
7770        }
7771    }
7772
7773    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7774        makeIntentSenderCanceledLocked(rec);
7775        mIntentSenderRecords.remove(rec.key);
7776        if (cleanActivity && rec.key.activity != null) {
7777            rec.key.activity.pendingResults.remove(rec.ref);
7778        }
7779    }
7780
7781    void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7782        rec.canceled = true;
7783        RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7784        if (callbacks != null) {
7785            mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7786        }
7787    }
7788
7789    @Override
7790    public String getPackageForIntentSender(IIntentSender pendingResult) {
7791        if (!(pendingResult instanceof PendingIntentRecord)) {
7792            return null;
7793        }
7794        try {
7795            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7796            return res.key.packageName;
7797        } catch (ClassCastException e) {
7798        }
7799        return null;
7800    }
7801
7802    @Override
7803    public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7804        if (!(sender instanceof PendingIntentRecord)) {
7805            return;
7806        }
7807        synchronized(this) {
7808            ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7809        }
7810    }
7811
7812    @Override
7813    public void unregisterIntentSenderCancelListener(IIntentSender sender,
7814            IResultReceiver receiver) {
7815        if (!(sender instanceof PendingIntentRecord)) {
7816            return;
7817        }
7818        synchronized(this) {
7819            ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7820        }
7821    }
7822
7823    @Override
7824    public int getUidForIntentSender(IIntentSender sender) {
7825        if (sender instanceof PendingIntentRecord) {
7826            try {
7827                PendingIntentRecord res = (PendingIntentRecord)sender;
7828                return res.uid;
7829            } catch (ClassCastException e) {
7830            }
7831        }
7832        return -1;
7833    }
7834
7835    @Override
7836    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7837        if (!(pendingResult instanceof PendingIntentRecord)) {
7838            return false;
7839        }
7840        try {
7841            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7842            if (res.key.allIntents == null) {
7843                return false;
7844            }
7845            for (int i=0; i<res.key.allIntents.length; i++) {
7846                Intent intent = res.key.allIntents[i];
7847                if (intent.getPackage() != null && intent.getComponent() != null) {
7848                    return false;
7849                }
7850            }
7851            return true;
7852        } catch (ClassCastException e) {
7853        }
7854        return false;
7855    }
7856
7857    @Override
7858    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7859        if (!(pendingResult instanceof PendingIntentRecord)) {
7860            return false;
7861        }
7862        try {
7863            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7864            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7865                return true;
7866            }
7867            return false;
7868        } catch (ClassCastException e) {
7869        }
7870        return false;
7871    }
7872
7873    @Override
7874    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7875        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7876                "getIntentForIntentSender()");
7877        if (!(pendingResult instanceof PendingIntentRecord)) {
7878            return null;
7879        }
7880        try {
7881            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7882            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7883        } catch (ClassCastException e) {
7884        }
7885        return null;
7886    }
7887
7888    @Override
7889    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7890        if (!(pendingResult instanceof PendingIntentRecord)) {
7891            return null;
7892        }
7893        try {
7894            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7895            synchronized (this) {
7896                return getTagForIntentSenderLocked(res, prefix);
7897            }
7898        } catch (ClassCastException e) {
7899        }
7900        return null;
7901    }
7902
7903    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7904        final Intent intent = res.key.requestIntent;
7905        if (intent != null) {
7906            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7907                    || res.lastTagPrefix.equals(prefix))) {
7908                return res.lastTag;
7909            }
7910            res.lastTagPrefix = prefix;
7911            final StringBuilder sb = new StringBuilder(128);
7912            if (prefix != null) {
7913                sb.append(prefix);
7914            }
7915            if (intent.getAction() != null) {
7916                sb.append(intent.getAction());
7917            } else if (intent.getComponent() != null) {
7918                intent.getComponent().appendShortString(sb);
7919            } else {
7920                sb.append("?");
7921            }
7922            return res.lastTag = sb.toString();
7923        }
7924        return null;
7925    }
7926
7927    @Override
7928    public void setProcessLimit(int max) {
7929        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7930                "setProcessLimit()");
7931        synchronized (this) {
7932            mConstants.setOverrideMaxCachedProcesses(max);
7933        }
7934        trimApplications();
7935    }
7936
7937    @Override
7938    public int getProcessLimit() {
7939        synchronized (this) {
7940            return mConstants.getOverrideMaxCachedProcesses();
7941        }
7942    }
7943
7944    void importanceTokenDied(ImportanceToken token) {
7945        synchronized (ActivityManagerService.this) {
7946            synchronized (mPidsSelfLocked) {
7947                ImportanceToken cur
7948                    = mImportantProcesses.get(token.pid);
7949                if (cur != token) {
7950                    return;
7951                }
7952                mImportantProcesses.remove(token.pid);
7953                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7954                if (pr == null) {
7955                    return;
7956                }
7957                pr.forcingToImportant = null;
7958                updateProcessForegroundLocked(pr, false, false);
7959            }
7960            updateOomAdjLocked();
7961        }
7962    }
7963
7964    @Override
7965    public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7966        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7967                "setProcessImportant()");
7968        synchronized(this) {
7969            boolean changed = false;
7970
7971            synchronized (mPidsSelfLocked) {
7972                ProcessRecord pr = mPidsSelfLocked.get(pid);
7973                if (pr == null && isForeground) {
7974                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7975                    return;
7976                }
7977                ImportanceToken oldToken = mImportantProcesses.get(pid);
7978                if (oldToken != null) {
7979                    oldToken.token.unlinkToDeath(oldToken, 0);
7980                    mImportantProcesses.remove(pid);
7981                    if (pr != null) {
7982                        pr.forcingToImportant = null;
7983                    }
7984                    changed = true;
7985                }
7986                if (isForeground && token != null) {
7987                    ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7988                        @Override
7989                        public void binderDied() {
7990                            importanceTokenDied(this);
7991                        }
7992                    };
7993                    try {
7994                        token.linkToDeath(newToken, 0);
7995                        mImportantProcesses.put(pid, newToken);
7996                        pr.forcingToImportant = newToken;
7997                        changed = true;
7998                    } catch (RemoteException e) {
7999                        // If the process died while doing this, we will later
8000                        // do the cleanup with the process death link.
8001                    }
8002                }
8003            }
8004
8005            if (changed) {
8006                updateOomAdjLocked();
8007            }
8008        }
8009    }
8010
8011    @Override
8012    public boolean isAppForeground(int uid) throws RemoteException {
8013        synchronized (this) {
8014            UidRecord uidRec = mActiveUids.get(uid);
8015            if (uidRec == null || uidRec.idle) {
8016                return false;
8017            }
8018            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8019        }
8020    }
8021
8022    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8023    // be guarded by permission checking.
8024    int getUidState(int uid) {
8025        synchronized (this) {
8026            return getUidStateLocked(uid);
8027        }
8028    }
8029
8030    int getUidStateLocked(int uid) {
8031        UidRecord uidRec = mActiveUids.get(uid);
8032        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8033    }
8034
8035    @Override
8036    public boolean isInMultiWindowMode(IBinder token) {
8037        final long origId = Binder.clearCallingIdentity();
8038        try {
8039            synchronized(this) {
8040                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8041                if (r == null) {
8042                    return false;
8043                }
8044                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8045                return !r.getTask().mFullscreen;
8046            }
8047        } finally {
8048            Binder.restoreCallingIdentity(origId);
8049        }
8050    }
8051
8052    @Override
8053    public boolean isInPictureInPictureMode(IBinder token) {
8054        final long origId = Binder.clearCallingIdentity();
8055        try {
8056            synchronized(this) {
8057                return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8058            }
8059        } finally {
8060            Binder.restoreCallingIdentity(origId);
8061        }
8062    }
8063
8064    private boolean isInPictureInPictureMode(ActivityRecord r) {
8065        if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8066                r.getStack().isInStackLocked(r) == null) {
8067            return false;
8068        }
8069
8070        // If we are animating to fullscreen then we have already dispatched the PIP mode
8071        // changed, so we should reflect that check here as well.
8072        final PinnedActivityStack stack = r.getStack();
8073        final PinnedStackWindowController windowController = stack.getWindowContainerController();
8074        return !windowController.isAnimatingBoundsToFullscreen();
8075    }
8076
8077    @Override
8078    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8079        final long origId = Binder.clearCallingIdentity();
8080        try {
8081            synchronized(this) {
8082                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8083                        "enterPictureInPictureMode", token, params);
8084
8085                // If the activity is already in picture in picture mode, then just return early
8086                if (isInPictureInPictureMode(r)) {
8087                    return true;
8088                }
8089
8090                // Activity supports picture-in-picture, now check that we can enter PiP at this
8091                // point, if it is
8092                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8093                        false /* beforeStopping */)) {
8094                    return false;
8095                }
8096
8097                final Runnable enterPipRunnable = () -> {
8098                    // Only update the saved args from the args that are set
8099                    r.pictureInPictureArgs.copyOnlySet(params);
8100                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8101                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8102                    // Adjust the source bounds by the insets for the transition down
8103                    final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8104                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8105                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8106                    final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8107                    stack.setPictureInPictureAspectRatio(aspectRatio);
8108                    stack.setPictureInPictureActions(actions);
8109
8110                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8111                            r.supportsEnterPipOnTaskSwitch);
8112                    logPictureInPictureArgs(params);
8113                };
8114
8115                if (isKeyguardLocked()) {
8116                    // If the keyguard is showing or occluded, then try and dismiss it before
8117                    // entering picture-in-picture (this will prompt the user to authenticate if the
8118                    // device is currently locked).
8119                    try {
8120                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8121                            @Override
8122                            public void onDismissError() throws RemoteException {
8123                                // Do nothing
8124                            }
8125
8126                            @Override
8127                            public void onDismissSucceeded() throws RemoteException {
8128                                mHandler.post(enterPipRunnable);
8129                            }
8130
8131                            @Override
8132                            public void onDismissCancelled() throws RemoteException {
8133                                // Do nothing
8134                            }
8135                        });
8136                    } catch (RemoteException e) {
8137                        // Local call
8138                    }
8139                } else {
8140                    // Enter picture in picture immediately otherwise
8141                    enterPipRunnable.run();
8142                }
8143                return true;
8144            }
8145        } finally {
8146            Binder.restoreCallingIdentity(origId);
8147        }
8148    }
8149
8150    @Override
8151    public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8152        final long origId = Binder.clearCallingIdentity();
8153        try {
8154            synchronized(this) {
8155                final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8156                        "setPictureInPictureParams", token, params);
8157
8158                // Only update the saved args from the args that are set
8159                r.pictureInPictureArgs.copyOnlySet(params);
8160                if (r.getStack().getStackId() == PINNED_STACK_ID) {
8161                    // If the activity is already in picture-in-picture, update the pinned stack now
8162                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
8163                    // be used the next time the activity enters PiP
8164                    final PinnedActivityStack stack = r.getStack();
8165                    if (!stack.isAnimatingBoundsToFullscreen()) {
8166                        stack.setPictureInPictureAspectRatio(
8167                                r.pictureInPictureArgs.getAspectRatio());
8168                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8169                    }
8170                }
8171                logPictureInPictureArgs(params);
8172            }
8173        } finally {
8174            Binder.restoreCallingIdentity(origId);
8175        }
8176    }
8177
8178    @Override
8179    public int getMaxNumPictureInPictureActions(IBinder token) {
8180        // Currently, this is a static constant, but later, we may change this to be dependent on
8181        // the context of the activity
8182        return 3;
8183    }
8184
8185    private void logPictureInPictureArgs(PictureInPictureParams params) {
8186        if (params.hasSetActions()) {
8187            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8188                    params.getActions().size());
8189        }
8190        if (params.hasSetAspectRatio()) {
8191            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8192            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8193            MetricsLogger.action(lm);
8194        }
8195    }
8196
8197    /**
8198     * Checks the state of the system and the activity associated with the given {@param token} to
8199     * verify that picture-in-picture is supported for that activity.
8200     *
8201     * @return the activity record for the given {@param token} if all the checks pass.
8202     */
8203    private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8204            IBinder token, PictureInPictureParams params) {
8205        if (!mSupportsPictureInPicture) {
8206            throw new IllegalStateException(caller
8207                    + ": Device doesn't support picture-in-picture mode.");
8208        }
8209
8210        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8211        if (r == null) {
8212            throw new IllegalStateException(caller
8213                    + ": Can't find activity for token=" + token);
8214        }
8215
8216        if (!r.supportsPictureInPicture()) {
8217            throw new IllegalStateException(caller
8218                    + ": Current activity does not support picture-in-picture.");
8219        }
8220
8221        if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8222            throw new IllegalStateException(caller
8223                    + ": Activities on the home, assistant, or recents stack not supported");
8224        }
8225
8226        if (params.hasSetAspectRatio()
8227                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8228                        params.getAspectRatio())) {
8229            final float minAspectRatio = mContext.getResources().getFloat(
8230                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8231            final float maxAspectRatio = mContext.getResources().getFloat(
8232                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8233            throw new IllegalArgumentException(String.format(caller
8234                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8235                            minAspectRatio, maxAspectRatio));
8236        }
8237
8238        // Truncate the number of actions if necessary
8239        params.truncateActions(getMaxNumPictureInPictureActions(token));
8240
8241        return r;
8242    }
8243
8244    // =========================================================
8245    // PROCESS INFO
8246    // =========================================================
8247
8248    static class ProcessInfoService extends IProcessInfoService.Stub {
8249        final ActivityManagerService mActivityManagerService;
8250        ProcessInfoService(ActivityManagerService activityManagerService) {
8251            mActivityManagerService = activityManagerService;
8252        }
8253
8254        @Override
8255        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8256            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8257                    /*in*/ pids, /*out*/ states, null);
8258        }
8259
8260        @Override
8261        public void getProcessStatesAndOomScoresFromPids(
8262                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8263            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8264                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8265        }
8266    }
8267
8268    /**
8269     * For each PID in the given input array, write the current process state
8270     * for that process into the states array, or -1 to indicate that no
8271     * process with the given PID exists. If scores array is provided, write
8272     * the oom score for the process into the scores array, with INVALID_ADJ
8273     * indicating the PID doesn't exist.
8274     */
8275    public void getProcessStatesAndOomScoresForPIDs(
8276            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8277        if (scores != null) {
8278            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8279                    "getProcessStatesAndOomScoresForPIDs()");
8280        }
8281
8282        if (pids == null) {
8283            throw new NullPointerException("pids");
8284        } else if (states == null) {
8285            throw new NullPointerException("states");
8286        } else if (pids.length != states.length) {
8287            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8288        } else if (scores != null && pids.length != scores.length) {
8289            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8290        }
8291
8292        synchronized (mPidsSelfLocked) {
8293            for (int i = 0; i < pids.length; i++) {
8294                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8295                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8296                        pr.curProcState;
8297                if (scores != null) {
8298                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8299                }
8300            }
8301        }
8302    }
8303
8304    // =========================================================
8305    // PERMISSIONS
8306    // =========================================================
8307
8308    static class PermissionController extends IPermissionController.Stub {
8309        ActivityManagerService mActivityManagerService;
8310        PermissionController(ActivityManagerService activityManagerService) {
8311            mActivityManagerService = activityManagerService;
8312        }
8313
8314        @Override
8315        public boolean checkPermission(String permission, int pid, int uid) {
8316            return mActivityManagerService.checkPermission(permission, pid,
8317                    uid) == PackageManager.PERMISSION_GRANTED;
8318        }
8319
8320        @Override
8321        public String[] getPackagesForUid(int uid) {
8322            return mActivityManagerService.mContext.getPackageManager()
8323                    .getPackagesForUid(uid);
8324        }
8325
8326        @Override
8327        public boolean isRuntimePermission(String permission) {
8328            try {
8329                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8330                        .getPermissionInfo(permission, 0);
8331                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8332                        == PermissionInfo.PROTECTION_DANGEROUS;
8333            } catch (NameNotFoundException nnfe) {
8334                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8335            }
8336            return false;
8337        }
8338    }
8339
8340    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8341        @Override
8342        public int checkComponentPermission(String permission, int pid, int uid,
8343                int owningUid, boolean exported) {
8344            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8345                    owningUid, exported);
8346        }
8347
8348        @Override
8349        public Object getAMSLock() {
8350            return ActivityManagerService.this;
8351        }
8352    }
8353
8354    /**
8355     * This can be called with or without the global lock held.
8356     */
8357    int checkComponentPermission(String permission, int pid, int uid,
8358            int owningUid, boolean exported) {
8359        if (pid == MY_PID) {
8360            return PackageManager.PERMISSION_GRANTED;
8361        }
8362        return ActivityManager.checkComponentPermission(permission, uid,
8363                owningUid, exported);
8364    }
8365
8366    /**
8367     * As the only public entry point for permissions checking, this method
8368     * can enforce the semantic that requesting a check on a null global
8369     * permission is automatically denied.  (Internally a null permission
8370     * string is used when calling {@link #checkComponentPermission} in cases
8371     * when only uid-based security is needed.)
8372     *
8373     * This can be called with or without the global lock held.
8374     */
8375    @Override
8376    public int checkPermission(String permission, int pid, int uid) {
8377        if (permission == null) {
8378            return PackageManager.PERMISSION_DENIED;
8379        }
8380        return checkComponentPermission(permission, pid, uid, -1, true);
8381    }
8382
8383    @Override
8384    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8385        if (permission == null) {
8386            return PackageManager.PERMISSION_DENIED;
8387        }
8388
8389        // We might be performing an operation on behalf of an indirect binder
8390        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8391        // client identity accordingly before proceeding.
8392        Identity tlsIdentity = sCallerIdentity.get();
8393        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8394            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8395                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8396            uid = tlsIdentity.uid;
8397            pid = tlsIdentity.pid;
8398        }
8399
8400        return checkComponentPermission(permission, pid, uid, -1, true);
8401    }
8402
8403    /**
8404     * Binder IPC calls go through the public entry point.
8405     * This can be called with or without the global lock held.
8406     */
8407    int checkCallingPermission(String permission) {
8408        return checkPermission(permission,
8409                Binder.getCallingPid(),
8410                UserHandle.getAppId(Binder.getCallingUid()));
8411    }
8412
8413    /**
8414     * This can be called with or without the global lock held.
8415     */
8416    void enforceCallingPermission(String permission, String func) {
8417        if (checkCallingPermission(permission)
8418                == PackageManager.PERMISSION_GRANTED) {
8419            return;
8420        }
8421
8422        String msg = "Permission Denial: " + func + " from pid="
8423                + Binder.getCallingPid()
8424                + ", uid=" + Binder.getCallingUid()
8425                + " requires " + permission;
8426        Slog.w(TAG, msg);
8427        throw new SecurityException(msg);
8428    }
8429
8430    /**
8431     * Determine if UID is holding permissions required to access {@link Uri} in
8432     * the given {@link ProviderInfo}. Final permission checking is always done
8433     * in {@link ContentProvider}.
8434     */
8435    private final boolean checkHoldingPermissionsLocked(
8436            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8437        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8438                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8439        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8440            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8441                    != PERMISSION_GRANTED) {
8442                return false;
8443            }
8444        }
8445        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8446    }
8447
8448    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8449            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8450        if (pi.applicationInfo.uid == uid) {
8451            return true;
8452        } else if (!pi.exported) {
8453            return false;
8454        }
8455
8456        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8457        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8458        try {
8459            // check if target holds top-level <provider> permissions
8460            if (!readMet && pi.readPermission != null && considerUidPermissions
8461                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8462                readMet = true;
8463            }
8464            if (!writeMet && pi.writePermission != null && considerUidPermissions
8465                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8466                writeMet = true;
8467            }
8468
8469            // track if unprotected read/write is allowed; any denied
8470            // <path-permission> below removes this ability
8471            boolean allowDefaultRead = pi.readPermission == null;
8472            boolean allowDefaultWrite = pi.writePermission == null;
8473
8474            // check if target holds any <path-permission> that match uri
8475            final PathPermission[] pps = pi.pathPermissions;
8476            if (pps != null) {
8477                final String path = grantUri.uri.getPath();
8478                int i = pps.length;
8479                while (i > 0 && (!readMet || !writeMet)) {
8480                    i--;
8481                    PathPermission pp = pps[i];
8482                    if (pp.match(path)) {
8483                        if (!readMet) {
8484                            final String pprperm = pp.getReadPermission();
8485                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8486                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8487                                    + ": match=" + pp.match(path)
8488                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8489                            if (pprperm != null) {
8490                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8491                                        == PERMISSION_GRANTED) {
8492                                    readMet = true;
8493                                } else {
8494                                    allowDefaultRead = false;
8495                                }
8496                            }
8497                        }
8498                        if (!writeMet) {
8499                            final String ppwperm = pp.getWritePermission();
8500                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8501                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8502                                    + ": match=" + pp.match(path)
8503                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8504                            if (ppwperm != null) {
8505                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8506                                        == PERMISSION_GRANTED) {
8507                                    writeMet = true;
8508                                } else {
8509                                    allowDefaultWrite = false;
8510                                }
8511                            }
8512                        }
8513                    }
8514                }
8515            }
8516
8517            // grant unprotected <provider> read/write, if not blocked by
8518            // <path-permission> above
8519            if (allowDefaultRead) readMet = true;
8520            if (allowDefaultWrite) writeMet = true;
8521
8522        } catch (RemoteException e) {
8523            return false;
8524        }
8525
8526        return readMet && writeMet;
8527    }
8528
8529    public boolean isAppStartModeDisabled(int uid, String packageName) {
8530        synchronized (this) {
8531            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8532                    == ActivityManager.APP_START_MODE_DISABLED;
8533        }
8534    }
8535
8536    // Unified app-op and target sdk check
8537    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8538        // Apps that target O+ are always subject to background check
8539        if (packageTargetSdk >= Build.VERSION_CODES.O) {
8540            if (DEBUG_BACKGROUND_CHECK) {
8541                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8542            }
8543            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8544        }
8545        // ...and legacy apps get an AppOp check
8546        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8547                uid, packageName);
8548        if (DEBUG_BACKGROUND_CHECK) {
8549            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8550        }
8551        switch (appop) {
8552            case AppOpsManager.MODE_ALLOWED:
8553                return ActivityManager.APP_START_MODE_NORMAL;
8554            case AppOpsManager.MODE_IGNORED:
8555                return ActivityManager.APP_START_MODE_DELAYED;
8556            default:
8557                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8558        }
8559    }
8560
8561    // Service launch is available to apps with run-in-background exemptions but
8562    // some other background operations are not.  If we're doing a check
8563    // of service-launch policy, allow those callers to proceed unrestricted.
8564    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8565        // Persistent app?
8566        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8567            if (DEBUG_BACKGROUND_CHECK) {
8568                Slog.i(TAG, "App " + uid + "/" + packageName
8569                        + " is persistent; not restricted in background");
8570            }
8571            return ActivityManager.APP_START_MODE_NORMAL;
8572        }
8573
8574        // Non-persistent but background whitelisted?
8575        if (uidOnBackgroundWhitelist(uid)) {
8576            if (DEBUG_BACKGROUND_CHECK) {
8577                Slog.i(TAG, "App " + uid + "/" + packageName
8578                        + " on background whitelist; not restricted in background");
8579            }
8580            return ActivityManager.APP_START_MODE_NORMAL;
8581        }
8582
8583        // Is this app on the battery whitelist?
8584        if (isOnDeviceIdleWhitelistLocked(uid)) {
8585            if (DEBUG_BACKGROUND_CHECK) {
8586                Slog.i(TAG, "App " + uid + "/" + packageName
8587                        + " on idle whitelist; not restricted in background");
8588            }
8589            return ActivityManager.APP_START_MODE_NORMAL;
8590        }
8591
8592        // None of the service-policy criteria apply, so we apply the common criteria
8593        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8594    }
8595
8596    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8597            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8598        UidRecord uidRec = mActiveUids.get(uid);
8599        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8600                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8601                + (uidRec != null ? uidRec.idle : false));
8602        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8603            boolean ephemeral;
8604            if (uidRec == null) {
8605                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8606                        UserHandle.getUserId(uid), packageName);
8607            } else {
8608                ephemeral = uidRec.ephemeral;
8609            }
8610
8611            if (ephemeral) {
8612                // We are hard-core about ephemeral apps not running in the background.
8613                return ActivityManager.APP_START_MODE_DISABLED;
8614            } else {
8615                if (disabledOnly) {
8616                    // The caller is only interested in whether app starts are completely
8617                    // disabled for the given package (that is, it is an instant app).  So
8618                    // we don't need to go further, which is all just seeing if we should
8619                    // apply a "delayed" mode for a regular app.
8620                    return ActivityManager.APP_START_MODE_NORMAL;
8621                }
8622                final int startMode = (alwaysRestrict)
8623                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8624                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8625                                packageTargetSdk);
8626                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8627                        + " pkg=" + packageName + " startMode=" + startMode
8628                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8629                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8630                    // This is an old app that has been forced into a "compatible as possible"
8631                    // mode of background check.  To increase compatibility, we will allow other
8632                    // foreground apps to cause its services to start.
8633                    if (callingPid >= 0) {
8634                        ProcessRecord proc;
8635                        synchronized (mPidsSelfLocked) {
8636                            proc = mPidsSelfLocked.get(callingPid);
8637                        }
8638                        if (proc != null &&
8639                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
8640                            // Whoever is instigating this is in the foreground, so we will allow it
8641                            // to go through.
8642                            return ActivityManager.APP_START_MODE_NORMAL;
8643                        }
8644                    }
8645                }
8646                return startMode;
8647            }
8648        }
8649        return ActivityManager.APP_START_MODE_NORMAL;
8650    }
8651
8652    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8653        final int appId = UserHandle.getAppId(uid);
8654        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8655                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8656                || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8657    }
8658
8659    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8660        ProviderInfo pi = null;
8661        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8662        if (cpr != null) {
8663            pi = cpr.info;
8664        } else {
8665            try {
8666                pi = AppGlobals.getPackageManager().resolveContentProvider(
8667                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8668                        userHandle);
8669            } catch (RemoteException ex) {
8670            }
8671        }
8672        return pi;
8673    }
8674
8675    void grantEphemeralAccessLocked(int userId, Intent intent,
8676            int targetAppId, int ephemeralAppId) {
8677        getPackageManagerInternalLocked().
8678                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8679    }
8680
8681    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8682        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8683        if (targetUris != null) {
8684            return targetUris.get(grantUri);
8685        }
8686        return null;
8687    }
8688
8689    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8690            String targetPkg, int targetUid, GrantUri grantUri) {
8691        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8692        if (targetUris == null) {
8693            targetUris = Maps.newArrayMap();
8694            mGrantedUriPermissions.put(targetUid, targetUris);
8695        }
8696
8697        UriPermission perm = targetUris.get(grantUri);
8698        if (perm == null) {
8699            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8700            targetUris.put(grantUri, perm);
8701        }
8702
8703        return perm;
8704    }
8705
8706    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8707            final int modeFlags) {
8708        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8709        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8710                : UriPermission.STRENGTH_OWNED;
8711
8712        // Root gets to do everything.
8713        if (uid == 0) {
8714            return true;
8715        }
8716
8717        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8718        if (perms == null) return false;
8719
8720        // First look for exact match
8721        final UriPermission exactPerm = perms.get(grantUri);
8722        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8723            return true;
8724        }
8725
8726        // No exact match, look for prefixes
8727        final int N = perms.size();
8728        for (int i = 0; i < N; i++) {
8729            final UriPermission perm = perms.valueAt(i);
8730            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8731                    && perm.getStrength(modeFlags) >= minStrength) {
8732                return true;
8733            }
8734        }
8735
8736        return false;
8737    }
8738
8739    /**
8740     * @param uri This uri must NOT contain an embedded userId.
8741     * @param userId The userId in which the uri is to be resolved.
8742     */
8743    @Override
8744    public int checkUriPermission(Uri uri, int pid, int uid,
8745            final int modeFlags, int userId, IBinder callerToken) {
8746        enforceNotIsolatedCaller("checkUriPermission");
8747
8748        // Another redirected-binder-call permissions check as in
8749        // {@link checkPermissionWithToken}.
8750        Identity tlsIdentity = sCallerIdentity.get();
8751        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8752            uid = tlsIdentity.uid;
8753            pid = tlsIdentity.pid;
8754        }
8755
8756        // Our own process gets to do everything.
8757        if (pid == MY_PID) {
8758            return PackageManager.PERMISSION_GRANTED;
8759        }
8760        synchronized (this) {
8761            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8762                    ? PackageManager.PERMISSION_GRANTED
8763                    : PackageManager.PERMISSION_DENIED;
8764        }
8765    }
8766
8767    /**
8768     * Check if the targetPkg can be granted permission to access uri by
8769     * the callingUid using the given modeFlags.  Throws a security exception
8770     * if callingUid is not allowed to do this.  Returns the uid of the target
8771     * if the URI permission grant should be performed; returns -1 if it is not
8772     * needed (for example targetPkg already has permission to access the URI).
8773     * If you already know the uid of the target, you can supply it in
8774     * lastTargetUid else set that to -1.
8775     */
8776    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8777            final int modeFlags, int lastTargetUid) {
8778        if (!Intent.isAccessUriMode(modeFlags)) {
8779            return -1;
8780        }
8781
8782        if (targetPkg != null) {
8783            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8784                    "Checking grant " + targetPkg + " permission to " + grantUri);
8785        }
8786
8787        final IPackageManager pm = AppGlobals.getPackageManager();
8788
8789        // If this is not a content: uri, we can't do anything with it.
8790        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8791            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8792                    "Can't grant URI permission for non-content URI: " + grantUri);
8793            return -1;
8794        }
8795
8796        // Bail early if system is trying to hand out permissions directly; it
8797        // must always grant permissions on behalf of someone explicit.
8798        final int callingAppId = UserHandle.getAppId(callingUid);
8799        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8800            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8801                // Exempted authority for cropping user photos in Settings app
8802            } else {
8803                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8804                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8805                return -1;
8806            }
8807        }
8808
8809        final String authority = grantUri.uri.getAuthority();
8810        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8811                MATCH_DEBUG_TRIAGED_MISSING);
8812        if (pi == null) {
8813            Slog.w(TAG, "No content provider found for permission check: " +
8814                    grantUri.uri.toSafeString());
8815            return -1;
8816        }
8817
8818        int targetUid = lastTargetUid;
8819        if (targetUid < 0 && targetPkg != null) {
8820            try {
8821                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8822                        UserHandle.getUserId(callingUid));
8823                if (targetUid < 0) {
8824                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8825                            "Can't grant URI permission no uid for: " + targetPkg);
8826                    return -1;
8827                }
8828            } catch (RemoteException ex) {
8829                return -1;
8830            }
8831        }
8832
8833        // If we're extending a persistable grant, then we always need to create
8834        // the grant data structure so that take/release APIs work
8835        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8836            return targetUid;
8837        }
8838
8839        if (targetUid >= 0) {
8840            // First...  does the target actually need this permission?
8841            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8842                // No need to grant the target this permission.
8843                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8844                        "Target " + targetPkg + " already has full permission to " + grantUri);
8845                return -1;
8846            }
8847        } else {
8848            // First...  there is no target package, so can anyone access it?
8849            boolean allowed = pi.exported;
8850            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8851                if (pi.readPermission != null) {
8852                    allowed = false;
8853                }
8854            }
8855            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8856                if (pi.writePermission != null) {
8857                    allowed = false;
8858                }
8859            }
8860            if (allowed) {
8861                return -1;
8862            }
8863        }
8864
8865        /* There is a special cross user grant if:
8866         * - The target is on another user.
8867         * - Apps on the current user can access the uri without any uid permissions.
8868         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8869         * grant uri permissions.
8870         */
8871        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8872                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8873                modeFlags, false /*without considering the uid permissions*/);
8874
8875        // Second...  is the provider allowing granting of URI permissions?
8876        if (!specialCrossUserGrant) {
8877            if (!pi.grantUriPermissions) {
8878                throw new SecurityException("Provider " + pi.packageName
8879                        + "/" + pi.name
8880                        + " does not allow granting of Uri permissions (uri "
8881                        + grantUri + ")");
8882            }
8883            if (pi.uriPermissionPatterns != null) {
8884                final int N = pi.uriPermissionPatterns.length;
8885                boolean allowed = false;
8886                for (int i=0; i<N; i++) {
8887                    if (pi.uriPermissionPatterns[i] != null
8888                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8889                        allowed = true;
8890                        break;
8891                    }
8892                }
8893                if (!allowed) {
8894                    throw new SecurityException("Provider " + pi.packageName
8895                            + "/" + pi.name
8896                            + " does not allow granting of permission to path of Uri "
8897                            + grantUri);
8898                }
8899            }
8900        }
8901
8902        // Third...  does the caller itself have permission to access
8903        // this uri?
8904        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8905            // Require they hold a strong enough Uri permission
8906            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8907                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8908                    throw new SecurityException(
8909                            "UID " + callingUid + " does not have permission to " + grantUri
8910                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8911                                    + "or related APIs");
8912                } else {
8913                    throw new SecurityException(
8914                            "UID " + callingUid + " does not have permission to " + grantUri);
8915                }
8916            }
8917        }
8918        return targetUid;
8919    }
8920
8921    /**
8922     * @param uri This uri must NOT contain an embedded userId.
8923     * @param userId The userId in which the uri is to be resolved.
8924     */
8925    @Override
8926    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8927            final int modeFlags, int userId) {
8928        enforceNotIsolatedCaller("checkGrantUriPermission");
8929        synchronized(this) {
8930            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8931                    new GrantUri(userId, uri, false), modeFlags, -1);
8932        }
8933    }
8934
8935    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8936            final int modeFlags, UriPermissionOwner owner) {
8937        if (!Intent.isAccessUriMode(modeFlags)) {
8938            return;
8939        }
8940
8941        // So here we are: the caller has the assumed permission
8942        // to the uri, and the target doesn't.  Let's now give this to
8943        // the target.
8944
8945        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8946                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8947
8948        final String authority = grantUri.uri.getAuthority();
8949        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8950                MATCH_DEBUG_TRIAGED_MISSING);
8951        if (pi == null) {
8952            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8953            return;
8954        }
8955
8956        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8957            grantUri.prefix = true;
8958        }
8959        final UriPermission perm = findOrCreateUriPermissionLocked(
8960                pi.packageName, targetPkg, targetUid, grantUri);
8961        perm.grantModes(modeFlags, owner);
8962    }
8963
8964    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8965            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8966        if (targetPkg == null) {
8967            throw new NullPointerException("targetPkg");
8968        }
8969        int targetUid;
8970        final IPackageManager pm = AppGlobals.getPackageManager();
8971        try {
8972            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8973        } catch (RemoteException ex) {
8974            return;
8975        }
8976
8977        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8978                targetUid);
8979        if (targetUid < 0) {
8980            return;
8981        }
8982
8983        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8984                owner);
8985    }
8986
8987    static class NeededUriGrants extends ArrayList<GrantUri> {
8988        final String targetPkg;
8989        final int targetUid;
8990        final int flags;
8991
8992        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8993            this.targetPkg = targetPkg;
8994            this.targetUid = targetUid;
8995            this.flags = flags;
8996        }
8997    }
8998
8999    /**
9000     * Like checkGrantUriPermissionLocked, but takes an Intent.
9001     */
9002    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9003            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9004        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9005                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9006                + " clip=" + (intent != null ? intent.getClipData() : null)
9007                + " from " + intent + "; flags=0x"
9008                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9009
9010        if (targetPkg == null) {
9011            throw new NullPointerException("targetPkg");
9012        }
9013
9014        if (intent == null) {
9015            return null;
9016        }
9017        Uri data = intent.getData();
9018        ClipData clip = intent.getClipData();
9019        if (data == null && clip == null) {
9020            return null;
9021        }
9022        // Default userId for uris in the intent (if they don't specify it themselves)
9023        int contentUserHint = intent.getContentUserHint();
9024        if (contentUserHint == UserHandle.USER_CURRENT) {
9025            contentUserHint = UserHandle.getUserId(callingUid);
9026        }
9027        final IPackageManager pm = AppGlobals.getPackageManager();
9028        int targetUid;
9029        if (needed != null) {
9030            targetUid = needed.targetUid;
9031        } else {
9032            try {
9033                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9034                        targetUserId);
9035            } catch (RemoteException ex) {
9036                return null;
9037            }
9038            if (targetUid < 0) {
9039                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9040                        "Can't grant URI permission no uid for: " + targetPkg
9041                        + " on user " + targetUserId);
9042                return null;
9043            }
9044        }
9045        if (data != null) {
9046            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9047            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9048                    targetUid);
9049            if (targetUid > 0) {
9050                if (needed == null) {
9051                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
9052                }
9053                needed.add(grantUri);
9054            }
9055        }
9056        if (clip != null) {
9057            for (int i=0; i<clip.getItemCount(); i++) {
9058                Uri uri = clip.getItemAt(i).getUri();
9059                if (uri != null) {
9060                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9061                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9062                            targetUid);
9063                    if (targetUid > 0) {
9064                        if (needed == null) {
9065                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
9066                        }
9067                        needed.add(grantUri);
9068                    }
9069                } else {
9070                    Intent clipIntent = clip.getItemAt(i).getIntent();
9071                    if (clipIntent != null) {
9072                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9073                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9074                        if (newNeeded != null) {
9075                            needed = newNeeded;
9076                        }
9077                    }
9078                }
9079            }
9080        }
9081
9082        return needed;
9083    }
9084
9085    /**
9086     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9087     */
9088    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9089            UriPermissionOwner owner) {
9090        if (needed != null) {
9091            for (int i=0; i<needed.size(); i++) {
9092                GrantUri grantUri = needed.get(i);
9093                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9094                        grantUri, needed.flags, owner);
9095            }
9096        }
9097    }
9098
9099    void grantUriPermissionFromIntentLocked(int callingUid,
9100            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9101        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9102                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9103        if (needed == null) {
9104            return;
9105        }
9106
9107        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9108    }
9109
9110    /**
9111     * @param uri This uri must NOT contain an embedded userId.
9112     * @param userId The userId in which the uri is to be resolved.
9113     */
9114    @Override
9115    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9116            final int modeFlags, int userId) {
9117        enforceNotIsolatedCaller("grantUriPermission");
9118        GrantUri grantUri = new GrantUri(userId, uri, false);
9119        synchronized(this) {
9120            final ProcessRecord r = getRecordForAppLocked(caller);
9121            if (r == null) {
9122                throw new SecurityException("Unable to find app for caller "
9123                        + caller
9124                        + " when granting permission to uri " + grantUri);
9125            }
9126            if (targetPkg == null) {
9127                throw new IllegalArgumentException("null target");
9128            }
9129            if (grantUri == null) {
9130                throw new IllegalArgumentException("null uri");
9131            }
9132
9133            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9134                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9135                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9136                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9137
9138            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9139                    UserHandle.getUserId(r.uid));
9140        }
9141    }
9142
9143    void removeUriPermissionIfNeededLocked(UriPermission perm) {
9144        if (perm.modeFlags == 0) {
9145            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9146                    perm.targetUid);
9147            if (perms != null) {
9148                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9149                        "Removing " + perm.targetUid + " permission to " + perm.uri);
9150
9151                perms.remove(perm.uri);
9152                if (perms.isEmpty()) {
9153                    mGrantedUriPermissions.remove(perm.targetUid);
9154                }
9155            }
9156        }
9157    }
9158
9159    private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9160            final int modeFlags) {
9161        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9162                "Revoking all granted permissions to " + grantUri);
9163
9164        final IPackageManager pm = AppGlobals.getPackageManager();
9165        final String authority = grantUri.uri.getAuthority();
9166        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9167                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9168        if (pi == null) {
9169            Slog.w(TAG, "No content provider found for permission revoke: "
9170                    + grantUri.toSafeString());
9171            return;
9172        }
9173
9174        // Does the caller have this permission on the URI?
9175        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9176            // If they don't have direct access to the URI, then revoke any
9177            // ownerless URI permissions that have been granted to them.
9178            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9179            if (perms != null) {
9180                boolean persistChanged = false;
9181                for (int i = perms.size()-1; i >= 0; i--) {
9182                    final UriPermission perm = perms.valueAt(i);
9183                    if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9184                        continue;
9185                    }
9186                    if (perm.uri.sourceUserId == grantUri.sourceUserId
9187                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9188                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9189                                "Revoking non-owned " + perm.targetUid
9190                                + " permission to " + perm.uri);
9191                        persistChanged |= perm.revokeModes(
9192                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9193                        if (perm.modeFlags == 0) {
9194                            perms.removeAt(i);
9195                        }
9196                    }
9197                }
9198                if (perms.isEmpty()) {
9199                    mGrantedUriPermissions.remove(callingUid);
9200                }
9201                if (persistChanged) {
9202                    schedulePersistUriGrants();
9203                }
9204            }
9205            return;
9206        }
9207
9208        boolean persistChanged = false;
9209
9210        // Go through all of the permissions and remove any that match.
9211        for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9212            final int targetUid = mGrantedUriPermissions.keyAt(i);
9213            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9214
9215            for (int j = perms.size()-1; j >= 0; j--) {
9216                final UriPermission perm = perms.valueAt(j);
9217                if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9218                    continue;
9219                }
9220                if (perm.uri.sourceUserId == grantUri.sourceUserId
9221                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9222                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9223                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9224                    persistChanged |= perm.revokeModes(
9225                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9226                            targetPackage == null);
9227                    if (perm.modeFlags == 0) {
9228                        perms.removeAt(j);
9229                    }
9230                }
9231            }
9232
9233            if (perms.isEmpty()) {
9234                mGrantedUriPermissions.removeAt(i);
9235            }
9236        }
9237
9238        if (persistChanged) {
9239            schedulePersistUriGrants();
9240        }
9241    }
9242
9243    /**
9244     * @param uri This uri must NOT contain an embedded userId.
9245     * @param userId The userId in which the uri is to be resolved.
9246     */
9247    @Override
9248    public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9249            final int modeFlags, int userId) {
9250        enforceNotIsolatedCaller("revokeUriPermission");
9251        synchronized(this) {
9252            final ProcessRecord r = getRecordForAppLocked(caller);
9253            if (r == null) {
9254                throw new SecurityException("Unable to find app for caller "
9255                        + caller
9256                        + " when revoking permission to uri " + uri);
9257            }
9258            if (uri == null) {
9259                Slog.w(TAG, "revokeUriPermission: null uri");
9260                return;
9261            }
9262
9263            if (!Intent.isAccessUriMode(modeFlags)) {
9264                return;
9265            }
9266
9267            final String authority = uri.getAuthority();
9268            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9269                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9270            if (pi == null) {
9271                Slog.w(TAG, "No content provider found for permission revoke: "
9272                        + uri.toSafeString());
9273                return;
9274            }
9275
9276            revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9277                    modeFlags);
9278        }
9279    }
9280
9281    /**
9282     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9283     * given package.
9284     *
9285     * @param packageName Package name to match, or {@code null} to apply to all
9286     *            packages.
9287     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9288     *            to all users.
9289     * @param persistable If persistable grants should be removed.
9290     */
9291    private void removeUriPermissionsForPackageLocked(
9292            String packageName, int userHandle, boolean persistable) {
9293        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9294            throw new IllegalArgumentException("Must narrow by either package or user");
9295        }
9296
9297        boolean persistChanged = false;
9298
9299        int N = mGrantedUriPermissions.size();
9300        for (int i = 0; i < N; i++) {
9301            final int targetUid = mGrantedUriPermissions.keyAt(i);
9302            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9303
9304            // Only inspect grants matching user
9305            if (userHandle == UserHandle.USER_ALL
9306                    || userHandle == UserHandle.getUserId(targetUid)) {
9307                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9308                    final UriPermission perm = it.next();
9309
9310                    // Only inspect grants matching package
9311                    if (packageName == null || perm.sourcePkg.equals(packageName)
9312                            || perm.targetPkg.equals(packageName)) {
9313                        // Hacky solution as part of fixing a security bug; ignore
9314                        // grants associated with DownloadManager so we don't have
9315                        // to immediately launch it to regrant the permissions
9316                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9317                                && !persistable) continue;
9318
9319                        persistChanged |= perm.revokeModes(persistable
9320                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9321
9322                        // Only remove when no modes remain; any persisted grants
9323                        // will keep this alive.
9324                        if (perm.modeFlags == 0) {
9325                            it.remove();
9326                        }
9327                    }
9328                }
9329
9330                if (perms.isEmpty()) {
9331                    mGrantedUriPermissions.remove(targetUid);
9332                    N--;
9333                    i--;
9334                }
9335            }
9336        }
9337
9338        if (persistChanged) {
9339            schedulePersistUriGrants();
9340        }
9341    }
9342
9343    @Override
9344    public IBinder newUriPermissionOwner(String name) {
9345        enforceNotIsolatedCaller("newUriPermissionOwner");
9346        synchronized(this) {
9347            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9348            return owner.getExternalTokenLocked();
9349        }
9350    }
9351
9352    @Override
9353    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9354        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9355        synchronized(this) {
9356            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9357            if (r == null) {
9358                throw new IllegalArgumentException("Activity does not exist; token="
9359                        + activityToken);
9360            }
9361            return r.getUriPermissionsLocked().getExternalTokenLocked();
9362        }
9363    }
9364    /**
9365     * @param uri This uri must NOT contain an embedded userId.
9366     * @param sourceUserId The userId in which the uri is to be resolved.
9367     * @param targetUserId The userId of the app that receives the grant.
9368     */
9369    @Override
9370    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9371            final int modeFlags, int sourceUserId, int targetUserId) {
9372        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9373                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9374                "grantUriPermissionFromOwner", null);
9375        synchronized(this) {
9376            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9377            if (owner == null) {
9378                throw new IllegalArgumentException("Unknown owner: " + token);
9379            }
9380            if (fromUid != Binder.getCallingUid()) {
9381                if (Binder.getCallingUid() != myUid()) {
9382                    // Only system code can grant URI permissions on behalf
9383                    // of other users.
9384                    throw new SecurityException("nice try");
9385                }
9386            }
9387            if (targetPkg == null) {
9388                throw new IllegalArgumentException("null target");
9389            }
9390            if (uri == null) {
9391                throw new IllegalArgumentException("null uri");
9392            }
9393
9394            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9395                    modeFlags, owner, targetUserId);
9396        }
9397    }
9398
9399    /**
9400     * @param uri This uri must NOT contain an embedded userId.
9401     * @param userId The userId in which the uri is to be resolved.
9402     */
9403    @Override
9404    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9405        synchronized(this) {
9406            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9407            if (owner == null) {
9408                throw new IllegalArgumentException("Unknown owner: " + token);
9409            }
9410
9411            if (uri == null) {
9412                owner.removeUriPermissionsLocked(mode);
9413            } else {
9414                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9415                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9416            }
9417        }
9418    }
9419
9420    private void schedulePersistUriGrants() {
9421        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9422            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9423                    10 * DateUtils.SECOND_IN_MILLIS);
9424        }
9425    }
9426
9427    private void writeGrantedUriPermissions() {
9428        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9429
9430        // Snapshot permissions so we can persist without lock
9431        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9432        synchronized (this) {
9433            final int size = mGrantedUriPermissions.size();
9434            for (int i = 0; i < size; i++) {
9435                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9436                for (UriPermission perm : perms.values()) {
9437                    if (perm.persistedModeFlags != 0) {
9438                        persist.add(perm.snapshot());
9439                    }
9440                }
9441            }
9442        }
9443
9444        FileOutputStream fos = null;
9445        try {
9446            fos = mGrantFile.startWrite();
9447
9448            XmlSerializer out = new FastXmlSerializer();
9449            out.setOutput(fos, StandardCharsets.UTF_8.name());
9450            out.startDocument(null, true);
9451            out.startTag(null, TAG_URI_GRANTS);
9452            for (UriPermission.Snapshot perm : persist) {
9453                out.startTag(null, TAG_URI_GRANT);
9454                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9455                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9456                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9457                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9458                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9459                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9460                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9461                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9462                out.endTag(null, TAG_URI_GRANT);
9463            }
9464            out.endTag(null, TAG_URI_GRANTS);
9465            out.endDocument();
9466
9467            mGrantFile.finishWrite(fos);
9468        } catch (IOException e) {
9469            if (fos != null) {
9470                mGrantFile.failWrite(fos);
9471            }
9472        }
9473    }
9474
9475    private void readGrantedUriPermissionsLocked() {
9476        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9477
9478        final long now = System.currentTimeMillis();
9479
9480        FileInputStream fis = null;
9481        try {
9482            fis = mGrantFile.openRead();
9483            final XmlPullParser in = Xml.newPullParser();
9484            in.setInput(fis, StandardCharsets.UTF_8.name());
9485
9486            int type;
9487            while ((type = in.next()) != END_DOCUMENT) {
9488                final String tag = in.getName();
9489                if (type == START_TAG) {
9490                    if (TAG_URI_GRANT.equals(tag)) {
9491                        final int sourceUserId;
9492                        final int targetUserId;
9493                        final int userHandle = readIntAttribute(in,
9494                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9495                        if (userHandle != UserHandle.USER_NULL) {
9496                            // For backwards compatibility.
9497                            sourceUserId = userHandle;
9498                            targetUserId = userHandle;
9499                        } else {
9500                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9501                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9502                        }
9503                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9504                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9505                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9506                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9507                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9508                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9509
9510                        // Sanity check that provider still belongs to source package
9511                        // Both direct boot aware and unaware packages are fine as we
9512                        // will do filtering at query time to avoid multiple parsing.
9513                        final ProviderInfo pi = getProviderInfoLocked(
9514                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9515                                        | MATCH_DIRECT_BOOT_UNAWARE);
9516                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9517                            int targetUid = -1;
9518                            try {
9519                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9520                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9521                            } catch (RemoteException e) {
9522                            }
9523                            if (targetUid != -1) {
9524                                final UriPermission perm = findOrCreateUriPermissionLocked(
9525                                        sourcePkg, targetPkg, targetUid,
9526                                        new GrantUri(sourceUserId, uri, prefix));
9527                                perm.initPersistedModes(modeFlags, createdTime);
9528                            }
9529                        } else {
9530                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9531                                    + " but instead found " + pi);
9532                        }
9533                    }
9534                }
9535            }
9536        } catch (FileNotFoundException e) {
9537            // Missing grants is okay
9538        } catch (IOException e) {
9539            Slog.wtf(TAG, "Failed reading Uri grants", e);
9540        } catch (XmlPullParserException e) {
9541            Slog.wtf(TAG, "Failed reading Uri grants", e);
9542        } finally {
9543            IoUtils.closeQuietly(fis);
9544        }
9545    }
9546
9547    /**
9548     * @param uri This uri must NOT contain an embedded userId.
9549     * @param userId The userId in which the uri is to be resolved.
9550     */
9551    @Override
9552    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9553        enforceNotIsolatedCaller("takePersistableUriPermission");
9554
9555        Preconditions.checkFlagsArgument(modeFlags,
9556                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9557
9558        synchronized (this) {
9559            final int callingUid = Binder.getCallingUid();
9560            boolean persistChanged = false;
9561            GrantUri grantUri = new GrantUri(userId, uri, false);
9562
9563            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9564                    new GrantUri(userId, uri, false));
9565            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9566                    new GrantUri(userId, uri, true));
9567
9568            final boolean exactValid = (exactPerm != null)
9569                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9570            final boolean prefixValid = (prefixPerm != null)
9571                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9572
9573            if (!(exactValid || prefixValid)) {
9574                throw new SecurityException("No persistable permission grants found for UID "
9575                        + callingUid + " and Uri " + grantUri.toSafeString());
9576            }
9577
9578            if (exactValid) {
9579                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9580            }
9581            if (prefixValid) {
9582                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9583            }
9584
9585            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9586
9587            if (persistChanged) {
9588                schedulePersistUriGrants();
9589            }
9590        }
9591    }
9592
9593    /**
9594     * @param uri This uri must NOT contain an embedded userId.
9595     * @param userId The userId in which the uri is to be resolved.
9596     */
9597    @Override
9598    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9599        enforceNotIsolatedCaller("releasePersistableUriPermission");
9600
9601        Preconditions.checkFlagsArgument(modeFlags,
9602                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9603
9604        synchronized (this) {
9605            final int callingUid = Binder.getCallingUid();
9606            boolean persistChanged = false;
9607
9608            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9609                    new GrantUri(userId, uri, false));
9610            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9611                    new GrantUri(userId, uri, true));
9612            if (exactPerm == null && prefixPerm == null) {
9613                throw new SecurityException("No permission grants found for UID " + callingUid
9614                        + " and Uri " + uri.toSafeString());
9615            }
9616
9617            if (exactPerm != null) {
9618                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9619                removeUriPermissionIfNeededLocked(exactPerm);
9620            }
9621            if (prefixPerm != null) {
9622                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9623                removeUriPermissionIfNeededLocked(prefixPerm);
9624            }
9625
9626            if (persistChanged) {
9627                schedulePersistUriGrants();
9628            }
9629        }
9630    }
9631
9632    /**
9633     * Prune any older {@link UriPermission} for the given UID until outstanding
9634     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9635     *
9636     * @return if any mutations occured that require persisting.
9637     */
9638    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9639        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9640        if (perms == null) return false;
9641        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9642
9643        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9644        for (UriPermission perm : perms.values()) {
9645            if (perm.persistedModeFlags != 0) {
9646                persisted.add(perm);
9647            }
9648        }
9649
9650        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9651        if (trimCount <= 0) return false;
9652
9653        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9654        for (int i = 0; i < trimCount; i++) {
9655            final UriPermission perm = persisted.get(i);
9656
9657            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9658                    "Trimming grant created at " + perm.persistedCreateTime);
9659
9660            perm.releasePersistableModes(~0);
9661            removeUriPermissionIfNeededLocked(perm);
9662        }
9663
9664        return true;
9665    }
9666
9667    @Override
9668    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9669            String packageName, boolean incoming) {
9670        enforceNotIsolatedCaller("getPersistedUriPermissions");
9671        Preconditions.checkNotNull(packageName, "packageName");
9672
9673        final int callingUid = Binder.getCallingUid();
9674        final int callingUserId = UserHandle.getUserId(callingUid);
9675        final IPackageManager pm = AppGlobals.getPackageManager();
9676        try {
9677            final int packageUid = pm.getPackageUid(packageName,
9678                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9679            if (packageUid != callingUid) {
9680                throw new SecurityException(
9681                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9682            }
9683        } catch (RemoteException e) {
9684            throw new SecurityException("Failed to verify package name ownership");
9685        }
9686
9687        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9688        synchronized (this) {
9689            if (incoming) {
9690                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9691                        callingUid);
9692                if (perms == null) {
9693                    Slog.w(TAG, "No permission grants found for " + packageName);
9694                } else {
9695                    for (UriPermission perm : perms.values()) {
9696                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9697                            result.add(perm.buildPersistedPublicApiObject());
9698                        }
9699                    }
9700                }
9701            } else {
9702                final int size = mGrantedUriPermissions.size();
9703                for (int i = 0; i < size; i++) {
9704                    final ArrayMap<GrantUri, UriPermission> perms =
9705                            mGrantedUriPermissions.valueAt(i);
9706                    for (UriPermission perm : perms.values()) {
9707                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9708                            result.add(perm.buildPersistedPublicApiObject());
9709                        }
9710                    }
9711                }
9712            }
9713        }
9714        return new ParceledListSlice<android.content.UriPermission>(result);
9715    }
9716
9717    @Override
9718    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9719            String packageName, int userId) {
9720        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9721                "getGrantedUriPermissions");
9722
9723        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9724        synchronized (this) {
9725            final int size = mGrantedUriPermissions.size();
9726            for (int i = 0; i < size; i++) {
9727                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9728                for (UriPermission perm : perms.values()) {
9729                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9730                            && perm.persistedModeFlags != 0) {
9731                        result.add(perm.buildPersistedPublicApiObject());
9732                    }
9733                }
9734            }
9735        }
9736        return new ParceledListSlice<android.content.UriPermission>(result);
9737    }
9738
9739    @Override
9740    public void clearGrantedUriPermissions(String packageName, int userId) {
9741        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9742                "clearGrantedUriPermissions");
9743        removeUriPermissionsForPackageLocked(packageName, userId, true);
9744    }
9745
9746    @Override
9747    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9748        synchronized (this) {
9749            ProcessRecord app =
9750                who != null ? getRecordForAppLocked(who) : null;
9751            if (app == null) return;
9752
9753            Message msg = Message.obtain();
9754            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9755            msg.obj = app;
9756            msg.arg1 = waiting ? 1 : 0;
9757            mUiHandler.sendMessage(msg);
9758        }
9759    }
9760
9761    @Override
9762    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9763        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9764        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9765        outInfo.availMem = getFreeMemory();
9766        outInfo.totalMem = getTotalMemory();
9767        outInfo.threshold = homeAppMem;
9768        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9769        outInfo.hiddenAppThreshold = cachedAppMem;
9770        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9771                ProcessList.SERVICE_ADJ);
9772        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9773                ProcessList.VISIBLE_APP_ADJ);
9774        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9775                ProcessList.FOREGROUND_APP_ADJ);
9776    }
9777
9778    // =========================================================
9779    // TASK MANAGEMENT
9780    // =========================================================
9781
9782    @Override
9783    public List<IBinder> getAppTasks(String callingPackage) {
9784        int callingUid = Binder.getCallingUid();
9785        long ident = Binder.clearCallingIdentity();
9786
9787        synchronized(this) {
9788            ArrayList<IBinder> list = new ArrayList<IBinder>();
9789            try {
9790                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9791
9792                final int N = mRecentTasks.size();
9793                for (int i = 0; i < N; i++) {
9794                    TaskRecord tr = mRecentTasks.get(i);
9795                    // Skip tasks that do not match the caller.  We don't need to verify
9796                    // callingPackage, because we are also limiting to callingUid and know
9797                    // that will limit to the correct security sandbox.
9798                    if (tr.effectiveUid != callingUid) {
9799                        continue;
9800                    }
9801                    Intent intent = tr.getBaseIntent();
9802                    if (intent == null ||
9803                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9804                        continue;
9805                    }
9806                    ActivityManager.RecentTaskInfo taskInfo =
9807                            createRecentTaskInfoFromTaskRecord(tr);
9808                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9809                    list.add(taskImpl.asBinder());
9810                }
9811            } finally {
9812                Binder.restoreCallingIdentity(ident);
9813            }
9814            return list;
9815        }
9816    }
9817
9818    @Override
9819    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9820        final int callingUid = Binder.getCallingUid();
9821        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9822
9823        synchronized(this) {
9824            if (DEBUG_ALL) Slog.v(
9825                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9826
9827            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9828                    callingUid);
9829
9830            // TODO: Improve with MRU list from all ActivityStacks.
9831            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9832        }
9833
9834        return list;
9835    }
9836
9837    /**
9838     * Creates a new RecentTaskInfo from a TaskRecord.
9839     */
9840    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9841        // Update the task description to reflect any changes in the task stack
9842        tr.updateTaskDescription();
9843
9844        // Compose the recent task info
9845        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9846        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9847        rti.persistentId = tr.taskId;
9848        rti.baseIntent = new Intent(tr.getBaseIntent());
9849        rti.origActivity = tr.origActivity;
9850        rti.realActivity = tr.realActivity;
9851        rti.description = tr.lastDescription;
9852        rti.stackId = tr.getStackId();
9853        rti.userId = tr.userId;
9854        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9855        rti.firstActiveTime = tr.firstActiveTime;
9856        rti.lastActiveTime = tr.lastActiveTime;
9857        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9858        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9859        rti.numActivities = 0;
9860        if (tr.mBounds != null) {
9861            rti.bounds = new Rect(tr.mBounds);
9862        }
9863        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9864        rti.resizeMode = tr.mResizeMode;
9865
9866        ActivityRecord base = null;
9867        ActivityRecord top = null;
9868        ActivityRecord tmp;
9869
9870        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9871            tmp = tr.mActivities.get(i);
9872            if (tmp.finishing) {
9873                continue;
9874            }
9875            base = tmp;
9876            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9877                top = base;
9878            }
9879            rti.numActivities++;
9880        }
9881
9882        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9883        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9884
9885        return rti;
9886    }
9887
9888    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9889        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9890                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9891        if (!allowed) {
9892            if (checkPermission(android.Manifest.permission.GET_TASKS,
9893                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9894                // Temporary compatibility: some existing apps on the system image may
9895                // still be requesting the old permission and not switched to the new
9896                // one; if so, we'll still allow them full access.  This means we need
9897                // to see if they are holding the old permission and are a system app.
9898                try {
9899                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9900                        allowed = true;
9901                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9902                                + " is using old GET_TASKS but privileged; allowing");
9903                    }
9904                } catch (RemoteException e) {
9905                }
9906            }
9907        }
9908        if (!allowed) {
9909            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9910                    + " does not hold REAL_GET_TASKS; limiting output");
9911        }
9912        return allowed;
9913    }
9914
9915    @Override
9916    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9917            int userId) {
9918        final int callingUid = Binder.getCallingUid();
9919        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9920                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9921
9922        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9923        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9924        synchronized (this) {
9925            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9926                    callingUid);
9927            final boolean detailed = checkCallingPermission(
9928                    android.Manifest.permission.GET_DETAILED_TASKS)
9929                    == PackageManager.PERMISSION_GRANTED;
9930
9931            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9932                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9933                return ParceledListSlice.emptyList();
9934            }
9935            mRecentTasks.loadUserRecentsLocked(userId);
9936
9937            final int recentsCount = mRecentTasks.size();
9938            ArrayList<ActivityManager.RecentTaskInfo> res =
9939                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9940
9941            final Set<Integer> includedUsers;
9942            if (includeProfiles) {
9943                includedUsers = mUserController.getProfileIds(userId);
9944            } else {
9945                includedUsers = new HashSet<>();
9946            }
9947            includedUsers.add(Integer.valueOf(userId));
9948
9949            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9950                TaskRecord tr = mRecentTasks.get(i);
9951                // Only add calling user or related users recent tasks
9952                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9953                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9954                    continue;
9955                }
9956
9957                if (tr.realActivitySuspended) {
9958                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9959                    continue;
9960                }
9961
9962                // Return the entry if desired by the caller.  We always return
9963                // the first entry, because callers always expect this to be the
9964                // foreground app.  We may filter others if the caller has
9965                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9966                // we should exclude the entry.
9967
9968                if (i == 0
9969                        || withExcluded
9970                        || (tr.intent == null)
9971                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9972                                == 0)) {
9973                    if (!allowed) {
9974                        // If the caller doesn't have the GET_TASKS permission, then only
9975                        // allow them to see a small subset of tasks -- their own and home.
9976                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9977                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9978                            continue;
9979                        }
9980                    }
9981                    final ActivityStack stack = tr.getStack();
9982                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9983                        if (stack != null && stack.isHomeOrRecentsStack()) {
9984                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9985                                    "Skipping, home or recents stack task: " + tr);
9986                            continue;
9987                        }
9988                    }
9989                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9990                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9991                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9992                                    "Skipping, top task in docked stack: " + tr);
9993                            continue;
9994                        }
9995                    }
9996                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9997                        if (stack != null && stack.isPinnedStack()) {
9998                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9999                                    "Skipping, pinned stack task: " + tr);
10000                            continue;
10001                        }
10002                    }
10003                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10004                        // Don't include auto remove tasks that are finished or finishing.
10005                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10006                                "Skipping, auto-remove without activity: " + tr);
10007                        continue;
10008                    }
10009                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10010                            && !tr.isAvailable) {
10011                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10012                                "Skipping, unavail real act: " + tr);
10013                        continue;
10014                    }
10015
10016                    if (!tr.mUserSetupComplete) {
10017                        // Don't include task launched while user is not done setting-up.
10018                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10019                                "Skipping, user setup not complete: " + tr);
10020                        continue;
10021                    }
10022
10023                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10024                    if (!detailed) {
10025                        rti.baseIntent.replaceExtras((Bundle)null);
10026                    }
10027
10028                    res.add(rti);
10029                    maxNum--;
10030                }
10031            }
10032            return new ParceledListSlice<>(res);
10033        }
10034    }
10035
10036    @Override
10037    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10038        synchronized (this) {
10039            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10040                    "getTaskThumbnail()");
10041            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10042                    id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10043            if (tr != null) {
10044                return tr.getTaskThumbnailLocked();
10045            }
10046        }
10047        return null;
10048    }
10049
10050    @Override
10051    public ActivityManager.TaskDescription getTaskDescription(int id) {
10052        synchronized (this) {
10053            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10054                    "getTaskDescription()");
10055            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10056                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10057            if (tr != null) {
10058                return tr.lastTaskDescription;
10059            }
10060        }
10061        return null;
10062    }
10063
10064    @Override
10065    public int addAppTask(IBinder activityToken, Intent intent,
10066            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10067        final int callingUid = Binder.getCallingUid();
10068        final long callingIdent = Binder.clearCallingIdentity();
10069
10070        try {
10071            synchronized (this) {
10072                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10073                if (r == null) {
10074                    throw new IllegalArgumentException("Activity does not exist; token="
10075                            + activityToken);
10076                }
10077                ComponentName comp = intent.getComponent();
10078                if (comp == null) {
10079                    throw new IllegalArgumentException("Intent " + intent
10080                            + " must specify explicit component");
10081                }
10082                if (thumbnail.getWidth() != mThumbnailWidth
10083                        || thumbnail.getHeight() != mThumbnailHeight) {
10084                    throw new IllegalArgumentException("Bad thumbnail size: got "
10085                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10086                            + mThumbnailWidth + "x" + mThumbnailHeight);
10087                }
10088                if (intent.getSelector() != null) {
10089                    intent.setSelector(null);
10090                }
10091                if (intent.getSourceBounds() != null) {
10092                    intent.setSourceBounds(null);
10093                }
10094                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10095                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10096                        // The caller has added this as an auto-remove task...  that makes no
10097                        // sense, so turn off auto-remove.
10098                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10099                    }
10100                }
10101                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10102                    mLastAddedTaskActivity = null;
10103                }
10104                ActivityInfo ainfo = mLastAddedTaskActivity;
10105                if (ainfo == null) {
10106                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10107                            comp, 0, UserHandle.getUserId(callingUid));
10108                    if (ainfo.applicationInfo.uid != callingUid) {
10109                        throw new SecurityException(
10110                                "Can't add task for another application: target uid="
10111                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10112                    }
10113                }
10114
10115                TaskRecord task = new TaskRecord(this,
10116                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10117                        ainfo, intent, description, new TaskThumbnailInfo());
10118
10119                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10120                if (trimIdx >= 0) {
10121                    // If this would have caused a trim, then we'll abort because that
10122                    // means it would be added at the end of the list but then just removed.
10123                    return INVALID_TASK_ID;
10124                }
10125
10126                final int N = mRecentTasks.size();
10127                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10128                    final TaskRecord tr = mRecentTasks.remove(N - 1);
10129                    tr.removedFromRecents();
10130                }
10131
10132                task.inRecents = true;
10133                mRecentTasks.add(task);
10134                r.getStack().addTask(task, false, "addAppTask");
10135
10136                task.setLastThumbnailLocked(thumbnail);
10137                task.freeLastThumbnail();
10138                return task.taskId;
10139            }
10140        } finally {
10141            Binder.restoreCallingIdentity(callingIdent);
10142        }
10143    }
10144
10145    @Override
10146    public Point getAppTaskThumbnailSize() {
10147        synchronized (this) {
10148            return new Point(mThumbnailWidth,  mThumbnailHeight);
10149        }
10150    }
10151
10152    @Override
10153    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10154        synchronized (this) {
10155            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10156            if (r != null) {
10157                r.setTaskDescription(td);
10158                final TaskRecord task = r.getTask();
10159                task.updateTaskDescription();
10160                mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10161            }
10162        }
10163    }
10164
10165    @Override
10166    public void setTaskResizeable(int taskId, int resizeableMode) {
10167        synchronized (this) {
10168            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10169                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10170            if (task == null) {
10171                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10172                return;
10173            }
10174            task.setResizeMode(resizeableMode);
10175        }
10176    }
10177
10178    @Override
10179    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10180        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10181        long ident = Binder.clearCallingIdentity();
10182        try {
10183            synchronized (this) {
10184                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10185                if (task == null) {
10186                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10187                    return;
10188                }
10189                // Place the task in the right stack if it isn't there already based on
10190                // the requested bounds.
10191                // The stack transition logic is:
10192                // - a null bounds on a freeform task moves that task to fullscreen
10193                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10194                //   that task to freeform
10195                // - otherwise the task is not moved
10196                int stackId = task.getStackId();
10197                if (!StackId.isTaskResizeAllowed(stackId)) {
10198                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10199                }
10200                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10201                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10202                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10203                    stackId = FREEFORM_WORKSPACE_STACK_ID;
10204                }
10205
10206                // Reparent the task to the right stack if necessary
10207                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10208                if (stackId != task.getStackId()) {
10209                    // Defer resume until the task is resized below
10210                    task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10211                            DEFER_RESUME, "resizeTask");
10212                    preserveWindow = false;
10213                }
10214
10215                // After reparenting (which only resizes the task to the stack bounds), resize the
10216                // task to the actual bounds provided
10217                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10218            }
10219        } finally {
10220            Binder.restoreCallingIdentity(ident);
10221        }
10222    }
10223
10224    @Override
10225    public Rect getTaskBounds(int taskId) {
10226        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10227        long ident = Binder.clearCallingIdentity();
10228        Rect rect = new Rect();
10229        try {
10230            synchronized (this) {
10231                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10232                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10233                if (task == null) {
10234                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10235                    return rect;
10236                }
10237                if (task.getStack() != null) {
10238                    // Return the bounds from window manager since it will be adjusted for various
10239                    // things like the presense of a docked stack for tasks that aren't resizeable.
10240                    task.getWindowContainerBounds(rect);
10241                } else {
10242                    // Task isn't in window manager yet since it isn't associated with a stack.
10243                    // Return the persist value from activity manager
10244                    if (task.mBounds != null) {
10245                        rect.set(task.mBounds);
10246                    } else if (task.mLastNonFullscreenBounds != null) {
10247                        rect.set(task.mLastNonFullscreenBounds);
10248                    }
10249                }
10250            }
10251        } finally {
10252            Binder.restoreCallingIdentity(ident);
10253        }
10254        return rect;
10255    }
10256
10257    @Override
10258    public void cancelTaskWindowTransition(int taskId) {
10259        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10260        final long ident = Binder.clearCallingIdentity();
10261        try {
10262            synchronized (this) {
10263                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10264                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10265                if (task == null) {
10266                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10267                    return;
10268                }
10269                task.cancelWindowTransition();
10270            }
10271        } finally {
10272            Binder.restoreCallingIdentity(ident);
10273        }
10274    }
10275
10276    @Override
10277    public void cancelTaskThumbnailTransition(int taskId) {
10278        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10279        final long ident = Binder.clearCallingIdentity();
10280        try {
10281            synchronized (this) {
10282                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10283                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10284                if (task == null) {
10285                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10286                    return;
10287                }
10288                task.cancelThumbnailTransition();
10289            }
10290        } finally {
10291            Binder.restoreCallingIdentity(ident);
10292        }
10293    }
10294
10295    @Override
10296    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10297        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10298        final long ident = Binder.clearCallingIdentity();
10299        try {
10300            final TaskRecord task;
10301            synchronized (this) {
10302                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10303                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10304                if (task == null) {
10305                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10306                    return null;
10307                }
10308            }
10309            // Don't call this while holding the lock as this operation might hit the disk.
10310            return task.getSnapshot(reducedResolution);
10311        } finally {
10312            Binder.restoreCallingIdentity(ident);
10313        }
10314    }
10315
10316    @Override
10317    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10318        if (userId != UserHandle.getCallingUserId()) {
10319            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10320                    "getTaskDescriptionIcon");
10321        }
10322        final File passedIconFile = new File(filePath);
10323        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10324                passedIconFile.getName());
10325        if (!legitIconFile.getPath().equals(filePath)
10326                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10327            throw new IllegalArgumentException("Bad file path: " + filePath
10328                    + " passed for userId " + userId);
10329        }
10330        return mRecentTasks.getTaskDescriptionIcon(filePath);
10331    }
10332
10333    @Override
10334    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10335            throws RemoteException {
10336        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10337        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10338                activityOptions.getCustomInPlaceResId() == 0) {
10339            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10340                    "with valid animation");
10341        }
10342        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10343        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10344                activityOptions.getCustomInPlaceResId());
10345        mWindowManager.executeAppTransition();
10346    }
10347
10348    private void removeTasksByPackageNameLocked(String packageName, int userId) {
10349        // Remove all tasks with activities in the specified package from the list of recent tasks
10350        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10351            TaskRecord tr = mRecentTasks.get(i);
10352            if (tr.userId != userId) continue;
10353
10354            ComponentName cn = tr.intent.getComponent();
10355            if (cn != null && cn.getPackageName().equals(packageName)) {
10356                // If the package name matches, remove the task.
10357                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10358            }
10359        }
10360    }
10361
10362    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10363            int userId) {
10364
10365        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10366            TaskRecord tr = mRecentTasks.get(i);
10367            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10368                continue;
10369            }
10370
10371            ComponentName cn = tr.intent.getComponent();
10372            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10373                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10374            if (sameComponent) {
10375                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10376            }
10377        }
10378    }
10379
10380    @Override
10381    public void removeStack(int stackId) {
10382        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10383        if (StackId.isHomeOrRecentsStack(stackId)) {
10384            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10385        }
10386
10387        synchronized (this) {
10388            final long ident = Binder.clearCallingIdentity();
10389            try {
10390                mStackSupervisor.removeStackLocked(stackId);
10391            } finally {
10392                Binder.restoreCallingIdentity(ident);
10393            }
10394        }
10395    }
10396
10397    @Override
10398    public void moveStackToDisplay(int stackId, int displayId) {
10399        enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10400
10401        synchronized (this) {
10402            final long ident = Binder.clearCallingIdentity();
10403            try {
10404                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10405                        + " to displayId=" + displayId);
10406                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10407            } finally {
10408                Binder.restoreCallingIdentity(ident);
10409            }
10410        }
10411    }
10412
10413    @Override
10414    public boolean removeTask(int taskId) {
10415        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10416        synchronized (this) {
10417            final long ident = Binder.clearCallingIdentity();
10418            try {
10419                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10420            } finally {
10421                Binder.restoreCallingIdentity(ident);
10422            }
10423        }
10424    }
10425
10426    /**
10427     * TODO: Add mController hook
10428     */
10429    @Override
10430    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10431        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10432
10433        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10434        synchronized(this) {
10435            moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10436        }
10437    }
10438
10439    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10440        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10441
10442        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10443                Binder.getCallingUid(), -1, -1, "Task to front")) {
10444            ActivityOptions.abort(options);
10445            return;
10446        }
10447        final long origId = Binder.clearCallingIdentity();
10448        try {
10449            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10450            if (task == null) {
10451                Slog.d(TAG, "Could not find task for id: "+ taskId);
10452                return;
10453            }
10454            if (mStackSupervisor.isLockTaskModeViolation(task)) {
10455                mStackSupervisor.showLockTaskToast();
10456                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10457                return;
10458            }
10459            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10460            if (prev != null) {
10461                task.setTaskToReturnTo(prev);
10462            }
10463            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10464                    false /* forceNonResizable */);
10465
10466            final ActivityRecord topActivity = task.getTopActivity();
10467            if (topActivity != null) {
10468
10469                // We are reshowing a task, use a starting window to hide the initial draw delay
10470                // so the transition can start earlier.
10471                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10472                        true /* taskSwitch */, fromRecents);
10473            }
10474        } finally {
10475            Binder.restoreCallingIdentity(origId);
10476        }
10477        ActivityOptions.abort(options);
10478    }
10479
10480    /**
10481     * Attempts to move a task backwards in z-order (the order of activities within the task is
10482     * unchanged).
10483     *
10484     * There are several possible results of this call:
10485     * - if the task is locked, then we will show the lock toast
10486     * - if there is a task behind the provided task, then that task is made visible and resumed as
10487     *   this task is moved to the back
10488     * - otherwise, if there are no other tasks in the stack:
10489     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10490     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10491     *       (depending on whether it is visible)
10492     *     - otherwise, we simply return home and hide this task
10493     *
10494     * @param token A reference to the activity we wish to move
10495     * @param nonRoot If false then this only works if the activity is the root
10496     *                of a task; if true it will work for any activity in a task.
10497     * @return Returns true if the move completed, false if not.
10498     */
10499    @Override
10500    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10501        enforceNotIsolatedCaller("moveActivityTaskToBack");
10502        synchronized(this) {
10503            final long origId = Binder.clearCallingIdentity();
10504            try {
10505                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10506                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10507                if (task != null) {
10508                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10509                }
10510            } finally {
10511                Binder.restoreCallingIdentity(origId);
10512            }
10513        }
10514        return false;
10515    }
10516
10517    @Override
10518    public void moveTaskBackwards(int task) {
10519        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10520                "moveTaskBackwards()");
10521
10522        synchronized(this) {
10523            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10524                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10525                return;
10526            }
10527            final long origId = Binder.clearCallingIdentity();
10528            moveTaskBackwardsLocked(task);
10529            Binder.restoreCallingIdentity(origId);
10530        }
10531    }
10532
10533    private final void moveTaskBackwardsLocked(int task) {
10534        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10535    }
10536
10537    @Override
10538    public int createStackOnDisplay(int displayId) throws RemoteException {
10539        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10540        synchronized (this) {
10541            final int stackId = mStackSupervisor.getNextStackId();
10542            final ActivityStack stack =
10543                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10544            if (stack == null) {
10545                return INVALID_STACK_ID;
10546            }
10547            return stack.mStackId;
10548        }
10549    }
10550
10551    @Override
10552    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10553        synchronized (this) {
10554            final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10555            if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10556                return stack.mDisplayId;
10557            }
10558            return DEFAULT_DISPLAY;
10559        }
10560    }
10561
10562    @Override
10563    public int getActivityStackId(IBinder token) throws RemoteException {
10564        synchronized (this) {
10565            ActivityStack stack = ActivityRecord.getStackLocked(token);
10566            if (stack == null) {
10567                return INVALID_STACK_ID;
10568            }
10569            return stack.mStackId;
10570        }
10571    }
10572
10573    @Override
10574    public void exitFreeformMode(IBinder token) throws RemoteException {
10575        synchronized (this) {
10576            long ident = Binder.clearCallingIdentity();
10577            try {
10578                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10579                if (r == null) {
10580                    throw new IllegalArgumentException(
10581                            "exitFreeformMode: No activity record matching token=" + token);
10582                }
10583
10584                final ActivityStack stack = r.getStack();
10585                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10586                    throw new IllegalStateException(
10587                            "exitFreeformMode: You can only go fullscreen from freeform.");
10588                }
10589
10590                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10591                r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10592                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10593            } finally {
10594                Binder.restoreCallingIdentity(ident);
10595            }
10596        }
10597    }
10598
10599    @Override
10600    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10601        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10602        if (StackId.isHomeOrRecentsStack(stackId)) {
10603            throw new IllegalArgumentException(
10604                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10605        }
10606        synchronized (this) {
10607            long ident = Binder.clearCallingIdentity();
10608            try {
10609                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10610                if (task == null) {
10611                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10612                    return;
10613                }
10614
10615                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10616                        + " to stackId=" + stackId + " toTop=" + toTop);
10617                if (stackId == DOCKED_STACK_ID) {
10618                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10619                            null /* initialBounds */);
10620                }
10621                task.reparent(stackId, toTop,
10622                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10623            } finally {
10624                Binder.restoreCallingIdentity(ident);
10625            }
10626        }
10627    }
10628
10629    @Override
10630    public void swapDockedAndFullscreenStack() throws RemoteException {
10631        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10632        synchronized (this) {
10633            long ident = Binder.clearCallingIdentity();
10634            try {
10635                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10636                        FULLSCREEN_WORKSPACE_STACK_ID);
10637                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10638                        : null;
10639                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10640                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10641                        : null;
10642                if (topTask == null || tasks == null || tasks.size() == 0) {
10643                    Slog.w(TAG,
10644                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10645                    return;
10646                }
10647
10648                // TODO: App transition
10649                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10650
10651                // Defer the resume until we move all the docked tasks to the fullscreen stack below
10652                topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10653                        DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10654                final int size = tasks.size();
10655                for (int i = 0; i < size; i++) {
10656                    final int id = tasks.get(i).taskId;
10657                    if (id == topTask.taskId) {
10658                        continue;
10659                    }
10660
10661                    // Defer the resume until after all the tasks have been moved
10662                    tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10663                            REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10664                            "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10665                }
10666
10667                // Because we deferred the resume to avoid conflicts with stack switches while
10668                // resuming, we need to do it after all the tasks are moved.
10669                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10670                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10671
10672                mWindowManager.executeAppTransition();
10673            } finally {
10674                Binder.restoreCallingIdentity(ident);
10675            }
10676        }
10677    }
10678
10679    /**
10680     * Moves the input task to the docked stack.
10681     *
10682     * @param taskId Id of task to move.
10683     * @param createMode The mode the docked stack should be created in if it doesn't exist
10684     *                   already. See
10685     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10686     *                   and
10687     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10688     * @param toTop If the task and stack should be moved to the top.
10689     * @param animate Whether we should play an animation for the moving the task
10690     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10691     *                      docked stack. Pass {@code null} to use default bounds.
10692     */
10693    @Override
10694    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10695            Rect initialBounds) {
10696        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10697        synchronized (this) {
10698            long ident = Binder.clearCallingIdentity();
10699            try {
10700                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10701                if (task == null) {
10702                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10703                    return false;
10704                }
10705
10706                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10707                        + " to createMode=" + createMode + " toTop=" + toTop);
10708                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10709
10710                // Defer resuming until we move the home stack to the front below
10711                final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10712                        REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10713                        "moveTaskToDockedStack");
10714                if (moved) {
10715                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10716                }
10717                return moved;
10718            } finally {
10719                Binder.restoreCallingIdentity(ident);
10720            }
10721        }
10722    }
10723
10724    /**
10725     * Moves the top activity in the input stackId to the pinned stack.
10726     *
10727     * @param stackId Id of stack to move the top activity to pinned stack.
10728     * @param bounds Bounds to use for pinned stack.
10729     *
10730     * @return True if the top activity of the input stack was successfully moved to the pinned
10731     *          stack.
10732     */
10733    @Override
10734    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10735        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10736        synchronized (this) {
10737            if (!mSupportsPictureInPicture) {
10738                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10739                        + "Device doesn't support picture-in-picture mode");
10740            }
10741
10742            long ident = Binder.clearCallingIdentity();
10743            try {
10744                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10745            } finally {
10746                Binder.restoreCallingIdentity(ident);
10747            }
10748        }
10749    }
10750
10751    @Override
10752    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10753            boolean preserveWindows, boolean animate, int animationDuration) {
10754        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10755        long ident = Binder.clearCallingIdentity();
10756        try {
10757            synchronized (this) {
10758                if (animate) {
10759                    if (stackId == PINNED_STACK_ID) {
10760                        final PinnedActivityStack pinnedStack =
10761                                mStackSupervisor.getStack(PINNED_STACK_ID);
10762                        if (pinnedStack != null) {
10763                            pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10764                                    destBounds, animationDuration, false /* fromFullscreen */);
10765                        }
10766                    } else {
10767                        throw new IllegalArgumentException("Stack: " + stackId
10768                                + " doesn't support animated resize.");
10769                    }
10770                } else {
10771                    mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10772                            null /* tempTaskInsetBounds */, preserveWindows,
10773                            allowResizeInDockedMode, !DEFER_RESUME);
10774                }
10775            }
10776        } finally {
10777            Binder.restoreCallingIdentity(ident);
10778        }
10779    }
10780
10781    @Override
10782    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10783            Rect tempDockedTaskInsetBounds,
10784            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10785        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10786                "resizeDockedStack()");
10787        long ident = Binder.clearCallingIdentity();
10788        try {
10789            synchronized (this) {
10790                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10791                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10792                        PRESERVE_WINDOWS);
10793            }
10794        } finally {
10795            Binder.restoreCallingIdentity(ident);
10796        }
10797    }
10798
10799    @Override
10800    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10801        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10802                "resizePinnedStack()");
10803        final long ident = Binder.clearCallingIdentity();
10804        try {
10805            synchronized (this) {
10806                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10807            }
10808        } finally {
10809            Binder.restoreCallingIdentity(ident);
10810        }
10811    }
10812
10813    /**
10814     * Try to place task to provided position. The final position might be different depending on
10815     * current user and stacks state. The task will be moved to target stack if it's currently in
10816     * different stack.
10817     */
10818    @Override
10819    public void positionTaskInStack(int taskId, int stackId, int position) {
10820        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10821        if (StackId.isHomeOrRecentsStack(stackId)) {
10822            throw new IllegalArgumentException(
10823                    "positionTaskInStack: Attempt to change the position of task "
10824                    + taskId + " in/to home/recents stack");
10825        }
10826        synchronized (this) {
10827            long ident = Binder.clearCallingIdentity();
10828            try {
10829                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10830                        + taskId + " in stackId=" + stackId + " at position=" + position);
10831                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10832                if (task == null) {
10833                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10834                            + taskId);
10835                }
10836
10837                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10838                        !ON_TOP);
10839
10840                // TODO: Have the callers of this API call a separate reparent method if that is
10841                // what they intended to do vs. having this method also do reparenting.
10842                if (task.getStack() == stack) {
10843                    // Change position in current stack.
10844                    stack.positionChildAt(task, position);
10845                } else {
10846                    // Reparent to new stack.
10847                    task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10848                            !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10849                }
10850            } finally {
10851                Binder.restoreCallingIdentity(ident);
10852            }
10853        }
10854    }
10855
10856    @Override
10857    public List<StackInfo> getAllStackInfos() {
10858        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10859        long ident = Binder.clearCallingIdentity();
10860        try {
10861            synchronized (this) {
10862                return mStackSupervisor.getAllStackInfosLocked();
10863            }
10864        } finally {
10865            Binder.restoreCallingIdentity(ident);
10866        }
10867    }
10868
10869    @Override
10870    public StackInfo getStackInfo(int stackId) {
10871        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10872        long ident = Binder.clearCallingIdentity();
10873        try {
10874            synchronized (this) {
10875                return mStackSupervisor.getStackInfoLocked(stackId);
10876            }
10877        } finally {
10878            Binder.restoreCallingIdentity(ident);
10879        }
10880    }
10881
10882    @Override
10883    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10884        synchronized(this) {
10885            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10886        }
10887    }
10888
10889    @Override
10890    public void updateDeviceOwner(String packageName) {
10891        final int callingUid = Binder.getCallingUid();
10892        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10893            throw new SecurityException("updateDeviceOwner called from non-system process");
10894        }
10895        synchronized (this) {
10896            mDeviceOwnerName = packageName;
10897        }
10898    }
10899
10900    @Override
10901    public void updateLockTaskPackages(int userId, String[] packages) {
10902        final int callingUid = Binder.getCallingUid();
10903        if (callingUid != 0 && callingUid != SYSTEM_UID) {
10904            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10905                    "updateLockTaskPackages()");
10906        }
10907        synchronized (this) {
10908            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10909                    Arrays.toString(packages));
10910            mLockTaskPackages.put(userId, packages);
10911            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10912        }
10913    }
10914
10915
10916    void startLockTaskModeLocked(TaskRecord task) {
10917        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10918        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10919            return;
10920        }
10921
10922        // When a task is locked, dismiss the pinned stack if it exists
10923        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10924                PINNED_STACK_ID);
10925        if (pinnedStack != null) {
10926            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10927        }
10928
10929        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10930        // is initiated by system after the pinning request was shown and locked mode is initiated
10931        // by an authorized app directly
10932        final int callingUid = Binder.getCallingUid();
10933        boolean isSystemInitiated = callingUid == SYSTEM_UID;
10934        long ident = Binder.clearCallingIdentity();
10935        try {
10936            if (!isSystemInitiated) {
10937                task.mLockTaskUid = callingUid;
10938                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10939                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10940                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10941                    StatusBarManagerInternal statusBarManager =
10942                            LocalServices.getService(StatusBarManagerInternal.class);
10943                    if (statusBarManager != null) {
10944                        statusBarManager.showScreenPinningRequest(task.taskId);
10945                    }
10946                    return;
10947                }
10948
10949                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10950                if (stack == null || task != stack.topTask()) {
10951                    throw new IllegalArgumentException("Invalid task, not in foreground");
10952                }
10953            }
10954            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10955                    "Locking fully");
10956            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10957                    ActivityManager.LOCK_TASK_MODE_PINNED :
10958                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10959                    "startLockTask", true);
10960        } finally {
10961            Binder.restoreCallingIdentity(ident);
10962        }
10963    }
10964
10965    @Override
10966    public void startLockTaskModeById(int taskId) {
10967        synchronized (this) {
10968            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10969            if (task != null) {
10970                startLockTaskModeLocked(task);
10971            }
10972        }
10973    }
10974
10975    @Override
10976    public void startLockTaskModeByToken(IBinder token) {
10977        synchronized (this) {
10978            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10979            if (r == null) {
10980                return;
10981            }
10982            final TaskRecord task = r.getTask();
10983            if (task != null) {
10984                startLockTaskModeLocked(task);
10985            }
10986        }
10987    }
10988
10989    @Override
10990    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10991        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10992        // This makes inner call to look as if it was initiated by system.
10993        long ident = Binder.clearCallingIdentity();
10994        try {
10995            synchronized (this) {
10996                startLockTaskModeById(taskId);
10997            }
10998        } finally {
10999            Binder.restoreCallingIdentity(ident);
11000        }
11001    }
11002
11003    @Override
11004    public void stopLockTaskMode() {
11005        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11006        if (lockTask == null) {
11007            // Our work here is done.
11008            return;
11009        }
11010
11011        final int callingUid = Binder.getCallingUid();
11012        final int lockTaskUid = lockTask.mLockTaskUid;
11013        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11014        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11015            // Done.
11016            return;
11017        } else {
11018            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11019            // It is possible lockTaskMode was started by the system process because
11020            // android:lockTaskMode is set to a locking value in the application manifest
11021            // instead of the app calling startLockTaskMode. In this case
11022            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11023            // {@link TaskRecord.effectiveUid} instead. Also caller with
11024            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11025            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11026                    && callingUid != lockTaskUid
11027                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11028                throw new SecurityException("Invalid uid, expected " + lockTaskUid
11029                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11030            }
11031        }
11032        long ident = Binder.clearCallingIdentity();
11033        try {
11034            Log.d(TAG, "stopLockTaskMode");
11035            // Stop lock task
11036            synchronized (this) {
11037                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11038                        "stopLockTask", true);
11039            }
11040            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11041            if (tm != null) {
11042                tm.showInCallScreen(false);
11043            }
11044        } finally {
11045            Binder.restoreCallingIdentity(ident);
11046        }
11047    }
11048
11049    /**
11050     * This API should be called by SystemUI only when user perform certain action to dismiss
11051     * lock task mode. We should only dismiss pinned lock task mode in this case.
11052     */
11053    @Override
11054    public void stopSystemLockTaskMode() throws RemoteException {
11055        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11056            stopLockTaskMode();
11057        } else {
11058            mStackSupervisor.showLockTaskToast();
11059        }
11060    }
11061
11062    @Override
11063    public boolean isInLockTaskMode() {
11064        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11065    }
11066
11067    @Override
11068    public int getLockTaskModeState() {
11069        synchronized (this) {
11070            return mStackSupervisor.getLockTaskModeState();
11071        }
11072    }
11073
11074    @Override
11075    public void showLockTaskEscapeMessage(IBinder token) {
11076        synchronized (this) {
11077            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11078            if (r == null) {
11079                return;
11080            }
11081            mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11082        }
11083    }
11084
11085    @Override
11086    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11087            throws RemoteException {
11088        synchronized (this) {
11089            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11090            if (r == null) {
11091                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11092                        + token);
11093                return;
11094            }
11095            final long origId = Binder.clearCallingIdentity();
11096            try {
11097                r.setDisablePreviewScreenshots(disable);
11098            } finally {
11099                Binder.restoreCallingIdentity(origId);
11100            }
11101        }
11102    }
11103
11104    // =========================================================
11105    // CONTENT PROVIDERS
11106    // =========================================================
11107
11108    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11109        List<ProviderInfo> providers = null;
11110        try {
11111            providers = AppGlobals.getPackageManager()
11112                    .queryContentProviders(app.processName, app.uid,
11113                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11114                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11115                    .getList();
11116        } catch (RemoteException ex) {
11117        }
11118        if (DEBUG_MU) Slog.v(TAG_MU,
11119                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11120        int userId = app.userId;
11121        if (providers != null) {
11122            int N = providers.size();
11123            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11124            for (int i=0; i<N; i++) {
11125                // TODO: keep logic in sync with installEncryptionUnawareProviders
11126                ProviderInfo cpi =
11127                    (ProviderInfo)providers.get(i);
11128                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11129                        cpi.name, cpi.flags);
11130                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11131                    // This is a singleton provider, but a user besides the
11132                    // default user is asking to initialize a process it runs
11133                    // in...  well, no, it doesn't actually run in this process,
11134                    // it runs in the process of the default user.  Get rid of it.
11135                    providers.remove(i);
11136                    N--;
11137                    i--;
11138                    continue;
11139                }
11140
11141                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11142                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11143                if (cpr == null) {
11144                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11145                    mProviderMap.putProviderByClass(comp, cpr);
11146                }
11147                if (DEBUG_MU) Slog.v(TAG_MU,
11148                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11149                app.pubProviders.put(cpi.name, cpr);
11150                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11151                    // Don't add this if it is a platform component that is marked
11152                    // to run in multiple processes, because this is actually
11153                    // part of the framework so doesn't make sense to track as a
11154                    // separate apk in the process.
11155                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11156                            mProcessStats);
11157                }
11158                notifyPackageUse(cpi.applicationInfo.packageName,
11159                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11160            }
11161        }
11162        return providers;
11163    }
11164
11165    /**
11166     * Check if the calling UID has a possible chance at accessing the provider
11167     * at the given authority and user.
11168     */
11169    public String checkContentProviderAccess(String authority, int userId) {
11170        if (userId == UserHandle.USER_ALL) {
11171            mContext.enforceCallingOrSelfPermission(
11172                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11173            userId = UserHandle.getCallingUserId();
11174        }
11175
11176        ProviderInfo cpi = null;
11177        try {
11178            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11179                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11180                            | PackageManager.MATCH_DISABLED_COMPONENTS
11181                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
11182                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11183                    userId);
11184        } catch (RemoteException ignored) {
11185        }
11186        if (cpi == null) {
11187            return "Failed to find provider " + authority + " for user " + userId
11188                    + "; expected to find a valid ContentProvider for this authority";
11189        }
11190
11191        ProcessRecord r = null;
11192        synchronized (mPidsSelfLocked) {
11193            r = mPidsSelfLocked.get(Binder.getCallingPid());
11194        }
11195        if (r == null) {
11196            return "Failed to find PID " + Binder.getCallingPid();
11197        }
11198
11199        synchronized (this) {
11200            return checkContentProviderPermissionLocked(cpi, r, userId, true);
11201        }
11202    }
11203
11204    /**
11205     * Check if {@link ProcessRecord} has a possible chance at accessing the
11206     * given {@link ProviderInfo}. Final permission checking is always done
11207     * in {@link ContentProvider}.
11208     */
11209    private final String checkContentProviderPermissionLocked(
11210            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11211        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11212        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11213        boolean checkedGrants = false;
11214        if (checkUser) {
11215            // Looking for cross-user grants before enforcing the typical cross-users permissions
11216            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11217            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11218                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11219                    return null;
11220                }
11221                checkedGrants = true;
11222            }
11223            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11224                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11225            if (userId != tmpTargetUserId) {
11226                // When we actually went to determine the final targer user ID, this ended
11227                // up different than our initial check for the authority.  This is because
11228                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11229                // SELF.  So we need to re-check the grants again.
11230                checkedGrants = false;
11231            }
11232        }
11233        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11234                cpi.applicationInfo.uid, cpi.exported)
11235                == PackageManager.PERMISSION_GRANTED) {
11236            return null;
11237        }
11238        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11239                cpi.applicationInfo.uid, cpi.exported)
11240                == PackageManager.PERMISSION_GRANTED) {
11241            return null;
11242        }
11243
11244        PathPermission[] pps = cpi.pathPermissions;
11245        if (pps != null) {
11246            int i = pps.length;
11247            while (i > 0) {
11248                i--;
11249                PathPermission pp = pps[i];
11250                String pprperm = pp.getReadPermission();
11251                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11252                        cpi.applicationInfo.uid, cpi.exported)
11253                        == PackageManager.PERMISSION_GRANTED) {
11254                    return null;
11255                }
11256                String ppwperm = pp.getWritePermission();
11257                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11258                        cpi.applicationInfo.uid, cpi.exported)
11259                        == PackageManager.PERMISSION_GRANTED) {
11260                    return null;
11261                }
11262            }
11263        }
11264        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11265            return null;
11266        }
11267
11268        final String suffix;
11269        if (!cpi.exported) {
11270            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11271        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11272            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11273        } else {
11274            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11275        }
11276        final String msg = "Permission Denial: opening provider " + cpi.name
11277                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11278                + ", uid=" + callingUid + ")" + suffix;
11279        Slog.w(TAG, msg);
11280        return msg;
11281    }
11282
11283    /**
11284     * Returns if the ContentProvider has granted a uri to callingUid
11285     */
11286    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11287        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11288        if (perms != null) {
11289            for (int i=perms.size()-1; i>=0; i--) {
11290                GrantUri grantUri = perms.keyAt(i);
11291                if (grantUri.sourceUserId == userId || !checkUser) {
11292                    if (matchesProvider(grantUri.uri, cpi)) {
11293                        return true;
11294                    }
11295                }
11296            }
11297        }
11298        return false;
11299    }
11300
11301    /**
11302     * Returns true if the uri authority is one of the authorities specified in the provider.
11303     */
11304    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11305        String uriAuth = uri.getAuthority();
11306        String cpiAuth = cpi.authority;
11307        if (cpiAuth.indexOf(';') == -1) {
11308            return cpiAuth.equals(uriAuth);
11309        }
11310        String[] cpiAuths = cpiAuth.split(";");
11311        int length = cpiAuths.length;
11312        for (int i = 0; i < length; i++) {
11313            if (cpiAuths[i].equals(uriAuth)) return true;
11314        }
11315        return false;
11316    }
11317
11318    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11319            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11320        if (r != null) {
11321            for (int i=0; i<r.conProviders.size(); i++) {
11322                ContentProviderConnection conn = r.conProviders.get(i);
11323                if (conn.provider == cpr) {
11324                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11325                            "Adding provider requested by "
11326                            + r.processName + " from process "
11327                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11328                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11329                    if (stable) {
11330                        conn.stableCount++;
11331                        conn.numStableIncs++;
11332                    } else {
11333                        conn.unstableCount++;
11334                        conn.numUnstableIncs++;
11335                    }
11336                    return conn;
11337                }
11338            }
11339            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11340            if (stable) {
11341                conn.stableCount = 1;
11342                conn.numStableIncs = 1;
11343            } else {
11344                conn.unstableCount = 1;
11345                conn.numUnstableIncs = 1;
11346            }
11347            cpr.connections.add(conn);
11348            r.conProviders.add(conn);
11349            startAssociationLocked(r.uid, r.processName, r.curProcState,
11350                    cpr.uid, cpr.name, cpr.info.processName);
11351            return conn;
11352        }
11353        cpr.addExternalProcessHandleLocked(externalProcessToken);
11354        return null;
11355    }
11356
11357    boolean decProviderCountLocked(ContentProviderConnection conn,
11358            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11359        if (conn != null) {
11360            cpr = conn.provider;
11361            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11362                    "Removing provider requested by "
11363                    + conn.client.processName + " from process "
11364                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11365                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11366            if (stable) {
11367                conn.stableCount--;
11368            } else {
11369                conn.unstableCount--;
11370            }
11371            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11372                cpr.connections.remove(conn);
11373                conn.client.conProviders.remove(conn);
11374                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11375                    // The client is more important than last activity -- note the time this
11376                    // is happening, so we keep the old provider process around a bit as last
11377                    // activity to avoid thrashing it.
11378                    if (cpr.proc != null) {
11379                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11380                    }
11381                }
11382                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11383                return true;
11384            }
11385            return false;
11386        }
11387        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11388        return false;
11389    }
11390
11391    private void checkTime(long startTime, String where) {
11392        long now = SystemClock.uptimeMillis();
11393        if ((now-startTime) > 50) {
11394            // If we are taking more than 50ms, log about it.
11395            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11396        }
11397    }
11398
11399    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11400            PROC_SPACE_TERM,
11401            PROC_SPACE_TERM|PROC_PARENS,
11402            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11403    };
11404
11405    private final long[] mProcessStateStatsLongs = new long[1];
11406
11407    boolean isProcessAliveLocked(ProcessRecord proc) {
11408        if (proc.procStatFile == null) {
11409            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11410        }
11411        mProcessStateStatsLongs[0] = 0;
11412        if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11413                mProcessStateStatsLongs, null)) {
11414            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11415            return false;
11416        }
11417        final long state = mProcessStateStatsLongs[0];
11418        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11419                + (char)state);
11420        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11421    }
11422
11423    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11424            String name, IBinder token, boolean stable, int userId) {
11425        ContentProviderRecord cpr;
11426        ContentProviderConnection conn = null;
11427        ProviderInfo cpi = null;
11428
11429        synchronized(this) {
11430            long startTime = SystemClock.uptimeMillis();
11431
11432            ProcessRecord r = null;
11433            if (caller != null) {
11434                r = getRecordForAppLocked(caller);
11435                if (r == null) {
11436                    throw new SecurityException(
11437                            "Unable to find app for caller " + caller
11438                          + " (pid=" + Binder.getCallingPid()
11439                          + ") when getting content provider " + name);
11440                }
11441            }
11442
11443            boolean checkCrossUser = true;
11444
11445            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11446
11447            // First check if this content provider has been published...
11448            cpr = mProviderMap.getProviderByName(name, userId);
11449            // If that didn't work, check if it exists for user 0 and then
11450            // verify that it's a singleton provider before using it.
11451            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11452                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11453                if (cpr != null) {
11454                    cpi = cpr.info;
11455                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11456                            cpi.name, cpi.flags)
11457                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11458                        userId = UserHandle.USER_SYSTEM;
11459                        checkCrossUser = false;
11460                    } else {
11461                        cpr = null;
11462                        cpi = null;
11463                    }
11464                }
11465            }
11466
11467            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11468            if (providerRunning) {
11469                cpi = cpr.info;
11470                String msg;
11471                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11472                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11473                        != null) {
11474                    throw new SecurityException(msg);
11475                }
11476                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11477
11478                if (r != null && cpr.canRunHere(r)) {
11479                    // This provider has been published or is in the process
11480                    // of being published...  but it is also allowed to run
11481                    // in the caller's process, so don't make a connection
11482                    // and just let the caller instantiate its own instance.
11483                    ContentProviderHolder holder = cpr.newHolder(null);
11484                    // don't give caller the provider object, it needs
11485                    // to make its own.
11486                    holder.provider = null;
11487                    return holder;
11488                }
11489                // Don't expose providers between normal apps and instant apps
11490                try {
11491                    if (AppGlobals.getPackageManager()
11492                            .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11493                        return null;
11494                    }
11495                } catch (RemoteException e) {
11496                }
11497
11498                final long origId = Binder.clearCallingIdentity();
11499
11500                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11501
11502                // In this case the provider instance already exists, so we can
11503                // return it right away.
11504                conn = incProviderCountLocked(r, cpr, token, stable);
11505                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11506                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11507                        // If this is a perceptible app accessing the provider,
11508                        // make sure to count it as being accessed and thus
11509                        // back up on the LRU list.  This is good because
11510                        // content providers are often expensive to start.
11511                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11512                        updateLruProcessLocked(cpr.proc, false, null);
11513                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11514                    }
11515                }
11516
11517                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11518                final int verifiedAdj = cpr.proc.verifiedAdj;
11519                boolean success = updateOomAdjLocked(cpr.proc, true);
11520                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11521                // if the process has been successfully adjusted.  So to reduce races with
11522                // it, we will check whether the process still exists.  Note that this doesn't
11523                // completely get rid of races with LMK killing the process, but should make
11524                // them much smaller.
11525                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11526                    success = false;
11527                }
11528                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11529                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11530                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11531                // NOTE: there is still a race here where a signal could be
11532                // pending on the process even though we managed to update its
11533                // adj level.  Not sure what to do about this, but at least
11534                // the race is now smaller.
11535                if (!success) {
11536                    // Uh oh...  it looks like the provider's process
11537                    // has been killed on us.  We need to wait for a new
11538                    // process to be started, and make sure its death
11539                    // doesn't kill our process.
11540                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11541                            + " is crashing; detaching " + r);
11542                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11543                    checkTime(startTime, "getContentProviderImpl: before appDied");
11544                    appDiedLocked(cpr.proc);
11545                    checkTime(startTime, "getContentProviderImpl: after appDied");
11546                    if (!lastRef) {
11547                        // This wasn't the last ref our process had on
11548                        // the provider...  we have now been killed, bail.
11549                        return null;
11550                    }
11551                    providerRunning = false;
11552                    conn = null;
11553                } else {
11554                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11555                }
11556
11557                Binder.restoreCallingIdentity(origId);
11558            }
11559
11560            if (!providerRunning) {
11561                try {
11562                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11563                    cpi = AppGlobals.getPackageManager().
11564                        resolveContentProvider(name,
11565                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11566                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11567                } catch (RemoteException ex) {
11568                }
11569                if (cpi == null) {
11570                    return null;
11571                }
11572                // If the provider is a singleton AND
11573                // (it's a call within the same user || the provider is a
11574                // privileged app)
11575                // Then allow connecting to the singleton provider
11576                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11577                        cpi.name, cpi.flags)
11578                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11579                if (singleton) {
11580                    userId = UserHandle.USER_SYSTEM;
11581                }
11582                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11583                checkTime(startTime, "getContentProviderImpl: got app info for user");
11584
11585                String msg;
11586                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11587                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11588                        != null) {
11589                    throw new SecurityException(msg);
11590                }
11591                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11592
11593                if (!mProcessesReady
11594                        && !cpi.processName.equals("system")) {
11595                    // If this content provider does not run in the system
11596                    // process, and the system is not yet ready to run other
11597                    // processes, then fail fast instead of hanging.
11598                    throw new IllegalArgumentException(
11599                            "Attempt to launch content provider before system ready");
11600                }
11601
11602                // Make sure that the user who owns this provider is running.  If not,
11603                // we don't want to allow it to run.
11604                if (!mUserController.isUserRunningLocked(userId, 0)) {
11605                    Slog.w(TAG, "Unable to launch app "
11606                            + cpi.applicationInfo.packageName + "/"
11607                            + cpi.applicationInfo.uid + " for provider "
11608                            + name + ": user " + userId + " is stopped");
11609                    return null;
11610                }
11611
11612                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11613                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11614                cpr = mProviderMap.getProviderByClass(comp, userId);
11615                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11616                final boolean firstClass = cpr == null;
11617                if (firstClass) {
11618                    final long ident = Binder.clearCallingIdentity();
11619
11620                    // If permissions need a review before any of the app components can run,
11621                    // we return no provider and launch a review activity if the calling app
11622                    // is in the foreground.
11623                    if (mPermissionReviewRequired) {
11624                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11625                            return null;
11626                        }
11627                    }
11628
11629                    try {
11630                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11631                        ApplicationInfo ai =
11632                            AppGlobals.getPackageManager().
11633                                getApplicationInfo(
11634                                        cpi.applicationInfo.packageName,
11635                                        STOCK_PM_FLAGS, userId);
11636                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11637                        if (ai == null) {
11638                            Slog.w(TAG, "No package info for content provider "
11639                                    + cpi.name);
11640                            return null;
11641                        }
11642                        ai = getAppInfoForUser(ai, userId);
11643                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11644                    } catch (RemoteException ex) {
11645                        // pm is in same process, this will never happen.
11646                    } finally {
11647                        Binder.restoreCallingIdentity(ident);
11648                    }
11649                }
11650
11651                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11652
11653                if (r != null && cpr.canRunHere(r)) {
11654                    // If this is a multiprocess provider, then just return its
11655                    // info and allow the caller to instantiate it.  Only do
11656                    // this if the provider is the same user as the caller's
11657                    // process, or can run as root (so can be in any process).
11658                    return cpr.newHolder(null);
11659                }
11660
11661                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11662                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11663                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11664
11665                // This is single process, and our app is now connecting to it.
11666                // See if we are already in the process of launching this
11667                // provider.
11668                final int N = mLaunchingProviders.size();
11669                int i;
11670                for (i = 0; i < N; i++) {
11671                    if (mLaunchingProviders.get(i) == cpr) {
11672                        break;
11673                    }
11674                }
11675
11676                // If the provider is not already being launched, then get it
11677                // started.
11678                if (i >= N) {
11679                    final long origId = Binder.clearCallingIdentity();
11680
11681                    try {
11682                        // Content provider is now in use, its package can't be stopped.
11683                        try {
11684                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11685                            AppGlobals.getPackageManager().setPackageStoppedState(
11686                                    cpr.appInfo.packageName, false, userId);
11687                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11688                        } catch (RemoteException e) {
11689                        } catch (IllegalArgumentException e) {
11690                            Slog.w(TAG, "Failed trying to unstop package "
11691                                    + cpr.appInfo.packageName + ": " + e);
11692                        }
11693
11694                        // Use existing process if already started
11695                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11696                        ProcessRecord proc = getProcessRecordLocked(
11697                                cpi.processName, cpr.appInfo.uid, false);
11698                        if (proc != null && proc.thread != null && !proc.killed) {
11699                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11700                                    "Installing in existing process " + proc);
11701                            if (!proc.pubProviders.containsKey(cpi.name)) {
11702                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11703                                proc.pubProviders.put(cpi.name, cpr);
11704                                try {
11705                                    proc.thread.scheduleInstallProvider(cpi);
11706                                } catch (RemoteException e) {
11707                                }
11708                            }
11709                        } else {
11710                            checkTime(startTime, "getContentProviderImpl: before start process");
11711                            proc = startProcessLocked(cpi.processName,
11712                                    cpr.appInfo, false, 0, "content provider",
11713                                    new ComponentName(cpi.applicationInfo.packageName,
11714                                            cpi.name), false, false, false);
11715                            checkTime(startTime, "getContentProviderImpl: after start process");
11716                            if (proc == null) {
11717                                Slog.w(TAG, "Unable to launch app "
11718                                        + cpi.applicationInfo.packageName + "/"
11719                                        + cpi.applicationInfo.uid + " for provider "
11720                                        + name + ": process is bad");
11721                                return null;
11722                            }
11723                        }
11724                        cpr.launchingApp = proc;
11725                        mLaunchingProviders.add(cpr);
11726                    } finally {
11727                        Binder.restoreCallingIdentity(origId);
11728                    }
11729                }
11730
11731                checkTime(startTime, "getContentProviderImpl: updating data structures");
11732
11733                // Make sure the provider is published (the same provider class
11734                // may be published under multiple names).
11735                if (firstClass) {
11736                    mProviderMap.putProviderByClass(comp, cpr);
11737                }
11738
11739                mProviderMap.putProviderByName(name, cpr);
11740                conn = incProviderCountLocked(r, cpr, token, stable);
11741                if (conn != null) {
11742                    conn.waiting = true;
11743                }
11744            }
11745            checkTime(startTime, "getContentProviderImpl: done!");
11746
11747            grantEphemeralAccessLocked(userId, null /*intent*/,
11748                    cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11749        }
11750
11751        // Wait for the provider to be published...
11752        synchronized (cpr) {
11753            while (cpr.provider == null) {
11754                if (cpr.launchingApp == null) {
11755                    Slog.w(TAG, "Unable to launch app "
11756                            + cpi.applicationInfo.packageName + "/"
11757                            + cpi.applicationInfo.uid + " for provider "
11758                            + name + ": launching app became null");
11759                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11760                            UserHandle.getUserId(cpi.applicationInfo.uid),
11761                            cpi.applicationInfo.packageName,
11762                            cpi.applicationInfo.uid, name);
11763                    return null;
11764                }
11765                try {
11766                    if (DEBUG_MU) Slog.v(TAG_MU,
11767                            "Waiting to start provider " + cpr
11768                            + " launchingApp=" + cpr.launchingApp);
11769                    if (conn != null) {
11770                        conn.waiting = true;
11771                    }
11772                    cpr.wait();
11773                } catch (InterruptedException ex) {
11774                } finally {
11775                    if (conn != null) {
11776                        conn.waiting = false;
11777                    }
11778                }
11779            }
11780        }
11781        return cpr != null ? cpr.newHolder(conn) : null;
11782    }
11783
11784    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11785            ProcessRecord r, final int userId) {
11786        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11787                cpi.packageName, userId)) {
11788
11789            final boolean callerForeground = r == null || r.setSchedGroup
11790                    != ProcessList.SCHED_GROUP_BACKGROUND;
11791
11792            // Show a permission review UI only for starting from a foreground app
11793            if (!callerForeground) {
11794                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11795                        + cpi.packageName + " requires a permissions review");
11796                return false;
11797            }
11798
11799            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11800            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11801                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11802            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11803
11804            if (DEBUG_PERMISSIONS_REVIEW) {
11805                Slog.i(TAG, "u" + userId + " Launching permission review "
11806                        + "for package " + cpi.packageName);
11807            }
11808
11809            final UserHandle userHandle = new UserHandle(userId);
11810            mHandler.post(new Runnable() {
11811                @Override
11812                public void run() {
11813                    mContext.startActivityAsUser(intent, userHandle);
11814                }
11815            });
11816
11817            return false;
11818        }
11819
11820        return true;
11821    }
11822
11823    PackageManagerInternal getPackageManagerInternalLocked() {
11824        if (mPackageManagerInt == null) {
11825            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11826        }
11827        return mPackageManagerInt;
11828    }
11829
11830    @Override
11831    public final ContentProviderHolder getContentProvider(
11832            IApplicationThread caller, String name, int userId, boolean stable) {
11833        enforceNotIsolatedCaller("getContentProvider");
11834        if (caller == null) {
11835            String msg = "null IApplicationThread when getting content provider "
11836                    + name;
11837            Slog.w(TAG, msg);
11838            throw new SecurityException(msg);
11839        }
11840        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11841        // with cross-user grant.
11842        return getContentProviderImpl(caller, name, null, stable, userId);
11843    }
11844
11845    public ContentProviderHolder getContentProviderExternal(
11846            String name, int userId, IBinder token) {
11847        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11848            "Do not have permission in call getContentProviderExternal()");
11849        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11850                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11851        return getContentProviderExternalUnchecked(name, token, userId);
11852    }
11853
11854    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11855            IBinder token, int userId) {
11856        return getContentProviderImpl(null, name, token, true, userId);
11857    }
11858
11859    /**
11860     * Drop a content provider from a ProcessRecord's bookkeeping
11861     */
11862    public void removeContentProvider(IBinder connection, boolean stable) {
11863        enforceNotIsolatedCaller("removeContentProvider");
11864        long ident = Binder.clearCallingIdentity();
11865        try {
11866            synchronized (this) {
11867                ContentProviderConnection conn;
11868                try {
11869                    conn = (ContentProviderConnection)connection;
11870                } catch (ClassCastException e) {
11871                    String msg ="removeContentProvider: " + connection
11872                            + " not a ContentProviderConnection";
11873                    Slog.w(TAG, msg);
11874                    throw new IllegalArgumentException(msg);
11875                }
11876                if (conn == null) {
11877                    throw new NullPointerException("connection is null");
11878                }
11879                if (decProviderCountLocked(conn, null, null, stable)) {
11880                    updateOomAdjLocked();
11881                }
11882            }
11883        } finally {
11884            Binder.restoreCallingIdentity(ident);
11885        }
11886    }
11887
11888    public void removeContentProviderExternal(String name, IBinder token) {
11889        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11890            "Do not have permission in call removeContentProviderExternal()");
11891        int userId = UserHandle.getCallingUserId();
11892        long ident = Binder.clearCallingIdentity();
11893        try {
11894            removeContentProviderExternalUnchecked(name, token, userId);
11895        } finally {
11896            Binder.restoreCallingIdentity(ident);
11897        }
11898    }
11899
11900    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11901        synchronized (this) {
11902            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11903            if(cpr == null) {
11904                //remove from mProvidersByClass
11905                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11906                return;
11907            }
11908
11909            //update content provider record entry info
11910            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11911            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11912            if (localCpr.hasExternalProcessHandles()) {
11913                if (localCpr.removeExternalProcessHandleLocked(token)) {
11914                    updateOomAdjLocked();
11915                } else {
11916                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11917                            + " with no external reference for token: "
11918                            + token + ".");
11919                }
11920            } else {
11921                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11922                        + " with no external references.");
11923            }
11924        }
11925    }
11926
11927    public final void publishContentProviders(IApplicationThread caller,
11928            List<ContentProviderHolder> providers) {
11929        if (providers == null) {
11930            return;
11931        }
11932
11933        enforceNotIsolatedCaller("publishContentProviders");
11934        synchronized (this) {
11935            final ProcessRecord r = getRecordForAppLocked(caller);
11936            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11937            if (r == null) {
11938                throw new SecurityException(
11939                        "Unable to find app for caller " + caller
11940                      + " (pid=" + Binder.getCallingPid()
11941                      + ") when publishing content providers");
11942            }
11943
11944            final long origId = Binder.clearCallingIdentity();
11945
11946            final int N = providers.size();
11947            for (int i = 0; i < N; i++) {
11948                ContentProviderHolder src = providers.get(i);
11949                if (src == null || src.info == null || src.provider == null) {
11950                    continue;
11951                }
11952                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11953                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11954                if (dst != null) {
11955                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11956                    mProviderMap.putProviderByClass(comp, dst);
11957                    String names[] = dst.info.authority.split(";");
11958                    for (int j = 0; j < names.length; j++) {
11959                        mProviderMap.putProviderByName(names[j], dst);
11960                    }
11961
11962                    int launchingCount = mLaunchingProviders.size();
11963                    int j;
11964                    boolean wasInLaunchingProviders = false;
11965                    for (j = 0; j < launchingCount; j++) {
11966                        if (mLaunchingProviders.get(j) == dst) {
11967                            mLaunchingProviders.remove(j);
11968                            wasInLaunchingProviders = true;
11969                            j--;
11970                            launchingCount--;
11971                        }
11972                    }
11973                    if (wasInLaunchingProviders) {
11974                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11975                    }
11976                    synchronized (dst) {
11977                        dst.provider = src.provider;
11978                        dst.proc = r;
11979                        dst.notifyAll();
11980                    }
11981                    updateOomAdjLocked(r, true);
11982                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11983                            src.info.authority);
11984                }
11985            }
11986
11987            Binder.restoreCallingIdentity(origId);
11988        }
11989    }
11990
11991    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11992        ContentProviderConnection conn;
11993        try {
11994            conn = (ContentProviderConnection)connection;
11995        } catch (ClassCastException e) {
11996            String msg ="refContentProvider: " + connection
11997                    + " not a ContentProviderConnection";
11998            Slog.w(TAG, msg);
11999            throw new IllegalArgumentException(msg);
12000        }
12001        if (conn == null) {
12002            throw new NullPointerException("connection is null");
12003        }
12004
12005        synchronized (this) {
12006            if (stable > 0) {
12007                conn.numStableIncs += stable;
12008            }
12009            stable = conn.stableCount + stable;
12010            if (stable < 0) {
12011                throw new IllegalStateException("stableCount < 0: " + stable);
12012            }
12013
12014            if (unstable > 0) {
12015                conn.numUnstableIncs += unstable;
12016            }
12017            unstable = conn.unstableCount + unstable;
12018            if (unstable < 0) {
12019                throw new IllegalStateException("unstableCount < 0: " + unstable);
12020            }
12021
12022            if ((stable+unstable) <= 0) {
12023                throw new IllegalStateException("ref counts can't go to zero here: stable="
12024                        + stable + " unstable=" + unstable);
12025            }
12026            conn.stableCount = stable;
12027            conn.unstableCount = unstable;
12028            return !conn.dead;
12029        }
12030    }
12031
12032    public void unstableProviderDied(IBinder connection) {
12033        ContentProviderConnection conn;
12034        try {
12035            conn = (ContentProviderConnection)connection;
12036        } catch (ClassCastException e) {
12037            String msg ="refContentProvider: " + connection
12038                    + " not a ContentProviderConnection";
12039            Slog.w(TAG, msg);
12040            throw new IllegalArgumentException(msg);
12041        }
12042        if (conn == null) {
12043            throw new NullPointerException("connection is null");
12044        }
12045
12046        // Safely retrieve the content provider associated with the connection.
12047        IContentProvider provider;
12048        synchronized (this) {
12049            provider = conn.provider.provider;
12050        }
12051
12052        if (provider == null) {
12053            // Um, yeah, we're way ahead of you.
12054            return;
12055        }
12056
12057        // Make sure the caller is being honest with us.
12058        if (provider.asBinder().pingBinder()) {
12059            // Er, no, still looks good to us.
12060            synchronized (this) {
12061                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12062                        + " says " + conn + " died, but we don't agree");
12063                return;
12064            }
12065        }
12066
12067        // Well look at that!  It's dead!
12068        synchronized (this) {
12069            if (conn.provider.provider != provider) {
12070                // But something changed...  good enough.
12071                return;
12072            }
12073
12074            ProcessRecord proc = conn.provider.proc;
12075            if (proc == null || proc.thread == null) {
12076                // Seems like the process is already cleaned up.
12077                return;
12078            }
12079
12080            // As far as we're concerned, this is just like receiving a
12081            // death notification...  just a bit prematurely.
12082            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12083                    + ") early provider death");
12084            final long ident = Binder.clearCallingIdentity();
12085            try {
12086                appDiedLocked(proc);
12087            } finally {
12088                Binder.restoreCallingIdentity(ident);
12089            }
12090        }
12091    }
12092
12093    @Override
12094    public void appNotRespondingViaProvider(IBinder connection) {
12095        enforceCallingPermission(
12096                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12097
12098        final ContentProviderConnection conn = (ContentProviderConnection) connection;
12099        if (conn == null) {
12100            Slog.w(TAG, "ContentProviderConnection is null");
12101            return;
12102        }
12103
12104        final ProcessRecord host = conn.provider.proc;
12105        if (host == null) {
12106            Slog.w(TAG, "Failed to find hosting ProcessRecord");
12107            return;
12108        }
12109
12110        mHandler.post(new Runnable() {
12111            @Override
12112            public void run() {
12113                mAppErrors.appNotResponding(host, null, null, false,
12114                        "ContentProvider not responding");
12115            }
12116        });
12117    }
12118
12119    public final void installSystemProviders() {
12120        List<ProviderInfo> providers;
12121        synchronized (this) {
12122            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12123            providers = generateApplicationProvidersLocked(app);
12124            if (providers != null) {
12125                for (int i=providers.size()-1; i>=0; i--) {
12126                    ProviderInfo pi = (ProviderInfo)providers.get(i);
12127                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12128                        Slog.w(TAG, "Not installing system proc provider " + pi.name
12129                                + ": not system .apk");
12130                        providers.remove(i);
12131                    }
12132                }
12133            }
12134        }
12135        if (providers != null) {
12136            mSystemThread.installSystemProviders(providers);
12137        }
12138
12139        mConstants.start(mContext.getContentResolver());
12140        mCoreSettingsObserver = new CoreSettingsObserver(this);
12141        mFontScaleSettingObserver = new FontScaleSettingObserver();
12142
12143        // Now that the settings provider is published we can consider sending
12144        // in a rescue party.
12145        RescueParty.onSettingsProviderPublished(mContext);
12146
12147        //mUsageStatsService.monitorPackages();
12148    }
12149
12150    private void startPersistentApps(int matchFlags) {
12151        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12152
12153        synchronized (this) {
12154            try {
12155                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12156                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12157                for (ApplicationInfo app : apps) {
12158                    if (!"android".equals(app.packageName)) {
12159                        addAppLocked(app, null, false, null /* ABI override */);
12160                    }
12161                }
12162            } catch (RemoteException ex) {
12163            }
12164        }
12165    }
12166
12167    /**
12168     * When a user is unlocked, we need to install encryption-unaware providers
12169     * belonging to any running apps.
12170     */
12171    private void installEncryptionUnawareProviders(int userId) {
12172        // We're only interested in providers that are encryption unaware, and
12173        // we don't care about uninstalled apps, since there's no way they're
12174        // running at this point.
12175        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12176
12177        synchronized (this) {
12178            final int NP = mProcessNames.getMap().size();
12179            for (int ip = 0; ip < NP; ip++) {
12180                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12181                final int NA = apps.size();
12182                for (int ia = 0; ia < NA; ia++) {
12183                    final ProcessRecord app = apps.valueAt(ia);
12184                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
12185
12186                    final int NG = app.pkgList.size();
12187                    for (int ig = 0; ig < NG; ig++) {
12188                        try {
12189                            final String pkgName = app.pkgList.keyAt(ig);
12190                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12191                                    .getPackageInfo(pkgName, matchFlags, userId);
12192                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12193                                for (ProviderInfo pi : pkgInfo.providers) {
12194                                    // TODO: keep in sync with generateApplicationProvidersLocked
12195                                    final boolean processMatch = Objects.equals(pi.processName,
12196                                            app.processName) || pi.multiprocess;
12197                                    final boolean userMatch = isSingleton(pi.processName,
12198                                            pi.applicationInfo, pi.name, pi.flags)
12199                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
12200                                    if (processMatch && userMatch) {
12201                                        Log.v(TAG, "Installing " + pi);
12202                                        app.thread.scheduleInstallProvider(pi);
12203                                    } else {
12204                                        Log.v(TAG, "Skipping " + pi);
12205                                    }
12206                                }
12207                            }
12208                        } catch (RemoteException ignored) {
12209                        }
12210                    }
12211                }
12212            }
12213        }
12214    }
12215
12216    /**
12217     * Allows apps to retrieve the MIME type of a URI.
12218     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12219     * users, then it does not need permission to access the ContentProvider.
12220     * Either, it needs cross-user uri grants.
12221     *
12222     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12223     *
12224     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12225     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12226     */
12227    public String getProviderMimeType(Uri uri, int userId) {
12228        enforceNotIsolatedCaller("getProviderMimeType");
12229        final String name = uri.getAuthority();
12230        int callingUid = Binder.getCallingUid();
12231        int callingPid = Binder.getCallingPid();
12232        long ident = 0;
12233        boolean clearedIdentity = false;
12234        synchronized (this) {
12235            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12236        }
12237        if (canClearIdentity(callingPid, callingUid, userId)) {
12238            clearedIdentity = true;
12239            ident = Binder.clearCallingIdentity();
12240        }
12241        ContentProviderHolder holder = null;
12242        try {
12243            holder = getContentProviderExternalUnchecked(name, null, userId);
12244            if (holder != null) {
12245                return holder.provider.getType(uri);
12246            }
12247        } catch (RemoteException e) {
12248            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12249            return null;
12250        } catch (Exception e) {
12251            Log.w(TAG, "Exception while determining type of " + uri, e);
12252            return null;
12253        } finally {
12254            // We need to clear the identity to call removeContentProviderExternalUnchecked
12255            if (!clearedIdentity) {
12256                ident = Binder.clearCallingIdentity();
12257            }
12258            try {
12259                if (holder != null) {
12260                    removeContentProviderExternalUnchecked(name, null, userId);
12261                }
12262            } finally {
12263                Binder.restoreCallingIdentity(ident);
12264            }
12265        }
12266
12267        return null;
12268    }
12269
12270    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12271        if (UserHandle.getUserId(callingUid) == userId) {
12272            return true;
12273        }
12274        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12275                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12276                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12277                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12278                return true;
12279        }
12280        return false;
12281    }
12282
12283    // =========================================================
12284    // GLOBAL MANAGEMENT
12285    // =========================================================
12286
12287    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12288            boolean isolated, int isolatedUid) {
12289        String proc = customProcess != null ? customProcess : info.processName;
12290        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12291        final int userId = UserHandle.getUserId(info.uid);
12292        int uid = info.uid;
12293        if (isolated) {
12294            if (isolatedUid == 0) {
12295                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12296                while (true) {
12297                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12298                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12299                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12300                    }
12301                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12302                    mNextIsolatedProcessUid++;
12303                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12304                        // No process for this uid, use it.
12305                        break;
12306                    }
12307                    stepsLeft--;
12308                    if (stepsLeft <= 0) {
12309                        return null;
12310                    }
12311                }
12312            } else {
12313                // Special case for startIsolatedProcess (internal only), where
12314                // the uid of the isolated process is specified by the caller.
12315                uid = isolatedUid;
12316            }
12317            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12318
12319            // Register the isolated UID with this application so BatteryStats knows to
12320            // attribute resource usage to the application.
12321            //
12322            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12323            // about the process state of the isolated UID *before* it is registered with the
12324            // owning application.
12325            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12326        }
12327        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12328        if (!mBooted && !mBooting
12329                && userId == UserHandle.USER_SYSTEM
12330                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12331            r.persistent = true;
12332            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12333        }
12334        addProcessNameLocked(r);
12335        return r;
12336    }
12337
12338    private boolean uidOnBackgroundWhitelist(final int uid) {
12339        final int appId = UserHandle.getAppId(uid);
12340        final int[] whitelist = mBackgroundAppIdWhitelist;
12341        final int N = whitelist.length;
12342        for (int i = 0; i < N; i++) {
12343            if (appId == whitelist[i]) {
12344                return true;
12345            }
12346        }
12347        return false;
12348    }
12349
12350    @Override
12351    public void backgroundWhitelistUid(final int uid) {
12352        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12353            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12354        }
12355
12356        if (DEBUG_BACKGROUND_CHECK) {
12357            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12358        }
12359        synchronized (this) {
12360            final int N = mBackgroundAppIdWhitelist.length;
12361            int[] newList = new int[N+1];
12362            System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12363            newList[N] = UserHandle.getAppId(uid);
12364            mBackgroundAppIdWhitelist = newList;
12365        }
12366    }
12367
12368    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12369            String abiOverride) {
12370        ProcessRecord app;
12371        if (!isolated) {
12372            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12373                    info.uid, true);
12374        } else {
12375            app = null;
12376        }
12377
12378        if (app == null) {
12379            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12380            updateLruProcessLocked(app, false, null);
12381            updateOomAdjLocked();
12382        }
12383
12384        // This package really, really can not be stopped.
12385        try {
12386            AppGlobals.getPackageManager().setPackageStoppedState(
12387                    info.packageName, false, UserHandle.getUserId(app.uid));
12388        } catch (RemoteException e) {
12389        } catch (IllegalArgumentException e) {
12390            Slog.w(TAG, "Failed trying to unstop package "
12391                    + info.packageName + ": " + e);
12392        }
12393
12394        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12395            app.persistent = true;
12396            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12397        }
12398        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12399            mPersistentStartingProcesses.add(app);
12400            startProcessLocked(app, "added application",
12401                    customProcess != null ? customProcess : app.processName, abiOverride,
12402                    null /* entryPoint */, null /* entryPointArgs */);
12403        }
12404
12405        return app;
12406    }
12407
12408    public void unhandledBack() {
12409        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12410                "unhandledBack()");
12411
12412        synchronized(this) {
12413            final long origId = Binder.clearCallingIdentity();
12414            try {
12415                getFocusedStack().unhandledBackLocked();
12416            } finally {
12417                Binder.restoreCallingIdentity(origId);
12418            }
12419        }
12420    }
12421
12422    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12423        enforceNotIsolatedCaller("openContentUri");
12424        final int userId = UserHandle.getCallingUserId();
12425        final Uri uri = Uri.parse(uriString);
12426        String name = uri.getAuthority();
12427        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12428        ParcelFileDescriptor pfd = null;
12429        if (cph != null) {
12430            // We record the binder invoker's uid in thread-local storage before
12431            // going to the content provider to open the file.  Later, in the code
12432            // that handles all permissions checks, we look for this uid and use
12433            // that rather than the Activity Manager's own uid.  The effect is that
12434            // we do the check against the caller's permissions even though it looks
12435            // to the content provider like the Activity Manager itself is making
12436            // the request.
12437            Binder token = new Binder();
12438            sCallerIdentity.set(new Identity(
12439                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12440            try {
12441                pfd = cph.provider.openFile(null, uri, "r", null, token);
12442            } catch (FileNotFoundException e) {
12443                // do nothing; pfd will be returned null
12444            } finally {
12445                // Ensure that whatever happens, we clean up the identity state
12446                sCallerIdentity.remove();
12447                // Ensure we're done with the provider.
12448                removeContentProviderExternalUnchecked(name, null, userId);
12449            }
12450        } else {
12451            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12452        }
12453        return pfd;
12454    }
12455
12456    // Actually is sleeping or shutting down or whatever else in the future
12457    // is an inactive state.
12458    boolean isSleepingOrShuttingDownLocked() {
12459        return isSleepingLocked() || mShuttingDown;
12460    }
12461
12462    boolean isShuttingDownLocked() {
12463        return mShuttingDown;
12464    }
12465
12466    boolean isSleepingLocked() {
12467        return mSleeping;
12468    }
12469
12470    void onWakefulnessChanged(int wakefulness) {
12471        synchronized(this) {
12472            boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12473            boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12474            mWakefulness = wakefulness;
12475
12476            if (wasAwake != isAwake) {
12477                // Also update state in a special way for running foreground services UI.
12478                mServices.updateScreenStateLocked(isAwake);
12479                sendNotifyVrManagerOfSleepState(!isAwake);
12480            }
12481        }
12482    }
12483
12484    void finishRunningVoiceLocked() {
12485        if (mRunningVoice != null) {
12486            mRunningVoice = null;
12487            mVoiceWakeLock.release();
12488            updateSleepIfNeededLocked();
12489        }
12490    }
12491
12492    void startTimeTrackingFocusedActivityLocked() {
12493        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12494        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12495            mCurAppTimeTracker.start(resumedActivity.packageName);
12496        }
12497    }
12498
12499    void updateSleepIfNeededLocked() {
12500        final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12501        final boolean wasSleeping = mSleeping;
12502
12503        if (!shouldSleep) {
12504            // If wasSleeping is true, we need to wake up activity manager state from when
12505            // we started sleeping. In either case, we need to apply the sleep tokens, which
12506            // will wake up stacks or put them to sleep as appropriate.
12507            if (wasSleeping) {
12508                mSleeping = false;
12509                startTimeTrackingFocusedActivityLocked();
12510                mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12511                mStackSupervisor.comeOutOfSleepIfNeededLocked();
12512            }
12513            mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12514            if (wasSleeping) {
12515                updateOomAdjLocked();
12516            }
12517        } else if (!mSleeping && shouldSleep) {
12518            mSleeping = true;
12519            if (mCurAppTimeTracker != null) {
12520                mCurAppTimeTracker.stop();
12521            }
12522            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12523            mStackSupervisor.goingToSleepLocked();
12524            updateOomAdjLocked();
12525        }
12526    }
12527
12528    /** Pokes the task persister. */
12529    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12530        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12531    }
12532
12533    /**
12534     * Notifies all listeners when the pinned stack animation starts.
12535     */
12536    @Override
12537    public void notifyPinnedStackAnimationStarted() {
12538        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12539    }
12540
12541    /**
12542     * Notifies all listeners when the pinned stack animation ends.
12543     */
12544    @Override
12545    public void notifyPinnedStackAnimationEnded() {
12546        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12547    }
12548
12549    @Override
12550    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12551        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12552    }
12553
12554    @Override
12555    public boolean shutdown(int timeout) {
12556        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12557                != PackageManager.PERMISSION_GRANTED) {
12558            throw new SecurityException("Requires permission "
12559                    + android.Manifest.permission.SHUTDOWN);
12560        }
12561
12562        boolean timedout = false;
12563
12564        synchronized(this) {
12565            mShuttingDown = true;
12566            mStackSupervisor.prepareForShutdownLocked();
12567            updateEventDispatchingLocked();
12568            timedout = mStackSupervisor.shutdownLocked(timeout);
12569        }
12570
12571        mAppOpsService.shutdown();
12572        if (mUsageStatsService != null) {
12573            mUsageStatsService.prepareShutdown();
12574        }
12575        mBatteryStatsService.shutdown();
12576        synchronized (this) {
12577            mProcessStats.shutdownLocked();
12578            notifyTaskPersisterLocked(null, true);
12579        }
12580
12581        return timedout;
12582    }
12583
12584    public final void activitySlept(IBinder token) {
12585        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12586
12587        final long origId = Binder.clearCallingIdentity();
12588
12589        synchronized (this) {
12590            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12591            if (r != null) {
12592                mStackSupervisor.activitySleptLocked(r);
12593            }
12594        }
12595
12596        Binder.restoreCallingIdentity(origId);
12597    }
12598
12599    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12600        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12601        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12602        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12603            boolean wasRunningVoice = mRunningVoice != null;
12604            mRunningVoice = session;
12605            if (!wasRunningVoice) {
12606                mVoiceWakeLock.acquire();
12607                updateSleepIfNeededLocked();
12608            }
12609        }
12610    }
12611
12612    private void updateEventDispatchingLocked() {
12613        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12614    }
12615
12616    @Override
12617    public void setLockScreenShown(boolean showing) {
12618        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12619                != PackageManager.PERMISSION_GRANTED) {
12620            throw new SecurityException("Requires permission "
12621                    + android.Manifest.permission.DEVICE_POWER);
12622        }
12623
12624        synchronized(this) {
12625            long ident = Binder.clearCallingIdentity();
12626            try {
12627                mKeyguardController.setKeyguardShown(showing);
12628            } finally {
12629                Binder.restoreCallingIdentity(ident);
12630            }
12631        }
12632    }
12633
12634    @Override
12635    public void notifyLockedProfile(@UserIdInt int userId) {
12636        try {
12637            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12638                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12639            }
12640        } catch (RemoteException ex) {
12641            throw new SecurityException("Fail to check is caller a privileged app", ex);
12642        }
12643
12644        synchronized (this) {
12645            final long ident = Binder.clearCallingIdentity();
12646            try {
12647                if (mUserController.shouldConfirmCredentials(userId)) {
12648                    if (mKeyguardController.isKeyguardLocked()) {
12649                        // Showing launcher to avoid user entering credential twice.
12650                        final int currentUserId = mUserController.getCurrentUserIdLocked();
12651                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12652                    }
12653                    mStackSupervisor.lockAllProfileTasks(userId);
12654                }
12655            } finally {
12656                Binder.restoreCallingIdentity(ident);
12657            }
12658        }
12659    }
12660
12661    @Override
12662    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12663        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12664        synchronized (this) {
12665            final long ident = Binder.clearCallingIdentity();
12666            try {
12667                mActivityStarter.startConfirmCredentialIntent(intent, options);
12668            } finally {
12669                Binder.restoreCallingIdentity(ident);
12670            }
12671        }
12672    }
12673
12674    @Override
12675    public void stopAppSwitches() {
12676        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12677                != PackageManager.PERMISSION_GRANTED) {
12678            throw new SecurityException("viewquires permission "
12679                    + android.Manifest.permission.STOP_APP_SWITCHES);
12680        }
12681
12682        synchronized(this) {
12683            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12684                    + APP_SWITCH_DELAY_TIME;
12685            mDidAppSwitch = false;
12686            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12687            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12688            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12689        }
12690    }
12691
12692    public void resumeAppSwitches() {
12693        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12694                != PackageManager.PERMISSION_GRANTED) {
12695            throw new SecurityException("Requires permission "
12696                    + android.Manifest.permission.STOP_APP_SWITCHES);
12697        }
12698
12699        synchronized(this) {
12700            // Note that we don't execute any pending app switches... we will
12701            // let those wait until either the timeout, or the next start
12702            // activity request.
12703            mAppSwitchesAllowedTime = 0;
12704        }
12705    }
12706
12707    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12708            int callingPid, int callingUid, String name) {
12709        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12710            return true;
12711        }
12712
12713        int perm = checkComponentPermission(
12714                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12715                sourceUid, -1, true);
12716        if (perm == PackageManager.PERMISSION_GRANTED) {
12717            return true;
12718        }
12719
12720        // If the actual IPC caller is different from the logical source, then
12721        // also see if they are allowed to control app switches.
12722        if (callingUid != -1 && callingUid != sourceUid) {
12723            perm = checkComponentPermission(
12724                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12725                    callingUid, -1, true);
12726            if (perm == PackageManager.PERMISSION_GRANTED) {
12727                return true;
12728            }
12729        }
12730
12731        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12732        return false;
12733    }
12734
12735    public void setDebugApp(String packageName, boolean waitForDebugger,
12736            boolean persistent) {
12737        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12738                "setDebugApp()");
12739
12740        long ident = Binder.clearCallingIdentity();
12741        try {
12742            // Note that this is not really thread safe if there are multiple
12743            // callers into it at the same time, but that's not a situation we
12744            // care about.
12745            if (persistent) {
12746                final ContentResolver resolver = mContext.getContentResolver();
12747                Settings.Global.putString(
12748                    resolver, Settings.Global.DEBUG_APP,
12749                    packageName);
12750                Settings.Global.putInt(
12751                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12752                    waitForDebugger ? 1 : 0);
12753            }
12754
12755            synchronized (this) {
12756                if (!persistent) {
12757                    mOrigDebugApp = mDebugApp;
12758                    mOrigWaitForDebugger = mWaitForDebugger;
12759                }
12760                mDebugApp = packageName;
12761                mWaitForDebugger = waitForDebugger;
12762                mDebugTransient = !persistent;
12763                if (packageName != null) {
12764                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12765                            false, UserHandle.USER_ALL, "set debug app");
12766                }
12767            }
12768        } finally {
12769            Binder.restoreCallingIdentity(ident);
12770        }
12771    }
12772
12773    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12774        synchronized (this) {
12775            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12776            if (!isDebuggable) {
12777                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12778                    throw new SecurityException("Process not debuggable: " + app.packageName);
12779                }
12780            }
12781
12782            mTrackAllocationApp = processName;
12783        }
12784    }
12785
12786    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12787        synchronized (this) {
12788            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12789            if (!isDebuggable) {
12790                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12791                    throw new SecurityException("Process not debuggable: " + app.packageName);
12792                }
12793            }
12794            mProfileApp = processName;
12795
12796            if (mProfilerInfo != null) {
12797                if (mProfilerInfo.profileFd != null) {
12798                    try {
12799                        mProfilerInfo.profileFd.close();
12800                    } catch (IOException e) {
12801                    }
12802                }
12803            }
12804            mProfilerInfo = new ProfilerInfo(profilerInfo);
12805            mProfileType = 0;
12806        }
12807    }
12808
12809    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12810        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12811        if (!isDebuggable) {
12812            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12813                throw new SecurityException("Process not debuggable: " + app.packageName);
12814            }
12815        }
12816        mNativeDebuggingApp = processName;
12817    }
12818
12819    @Override
12820    public void setAlwaysFinish(boolean enabled) {
12821        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12822                "setAlwaysFinish()");
12823
12824        long ident = Binder.clearCallingIdentity();
12825        try {
12826            Settings.Global.putInt(
12827                    mContext.getContentResolver(),
12828                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12829
12830            synchronized (this) {
12831                mAlwaysFinishActivities = enabled;
12832            }
12833        } finally {
12834            Binder.restoreCallingIdentity(ident);
12835        }
12836    }
12837
12838    @Override
12839    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12840        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12841                "setActivityController()");
12842        synchronized (this) {
12843            mController = controller;
12844            mControllerIsAMonkey = imAMonkey;
12845            Watchdog.getInstance().setActivityController(controller);
12846        }
12847    }
12848
12849    @Override
12850    public void setUserIsMonkey(boolean userIsMonkey) {
12851        synchronized (this) {
12852            synchronized (mPidsSelfLocked) {
12853                final int callingPid = Binder.getCallingPid();
12854                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12855                if (proc == null) {
12856                    throw new SecurityException("Unknown process: " + callingPid);
12857                }
12858                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12859                    throw new SecurityException("Only an instrumentation process "
12860                            + "with a UiAutomation can call setUserIsMonkey");
12861                }
12862            }
12863            mUserIsMonkey = userIsMonkey;
12864        }
12865    }
12866
12867    @Override
12868    public boolean isUserAMonkey() {
12869        synchronized (this) {
12870            // If there is a controller also implies the user is a monkey.
12871            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12872        }
12873    }
12874
12875    /**
12876     * @deprecated This method is only used by a few internal components and it will soon be
12877     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12878     * No new code should be calling it.
12879     */
12880    @Deprecated
12881    @Override
12882    public void requestBugReport(int bugreportType) {
12883        String extraOptions = null;
12884        switch (bugreportType) {
12885            case ActivityManager.BUGREPORT_OPTION_FULL:
12886                // Default options.
12887                break;
12888            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12889                extraOptions = "bugreportplus";
12890                break;
12891            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12892                extraOptions = "bugreportremote";
12893                break;
12894            case ActivityManager.BUGREPORT_OPTION_WEAR:
12895                extraOptions = "bugreportwear";
12896                break;
12897            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12898                extraOptions = "bugreporttelephony";
12899                break;
12900            default:
12901                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12902                        + bugreportType);
12903        }
12904        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12905        if (extraOptions != null) {
12906            SystemProperties.set("dumpstate.options", extraOptions);
12907        }
12908        SystemProperties.set("ctl.start", "bugreport");
12909    }
12910
12911    /**
12912     * @deprecated This method is only used by a few internal components and it will soon be
12913     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12914     * No new code should be calling it.
12915     */
12916    @Deprecated
12917    @Override
12918    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12919
12920        if (!TextUtils.isEmpty(shareTitle)) {
12921            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12922                String errorStr = "shareTitle should be less than " +
12923                        MAX_BUGREPORT_TITLE_SIZE + " characters";
12924                throw new IllegalArgumentException(errorStr);
12925            } else {
12926                if (!TextUtils.isEmpty(shareDescription)) {
12927                    int length;
12928                    try {
12929                        length = shareDescription.getBytes("UTF-8").length;
12930                    } catch (UnsupportedEncodingException e) {
12931                        String errorStr = "shareDescription: UnsupportedEncodingException";
12932                        throw new IllegalArgumentException(errorStr);
12933                    }
12934                    if (length > SystemProperties.PROP_VALUE_MAX) {
12935                        String errorStr = "shareTitle should be less than " +
12936                                SystemProperties.PROP_VALUE_MAX + " bytes";
12937                        throw new IllegalArgumentException(errorStr);
12938                    } else {
12939                        SystemProperties.set("dumpstate.options.description", shareDescription);
12940                    }
12941                }
12942                SystemProperties.set("dumpstate.options.title", shareTitle);
12943            }
12944        }
12945
12946        Slog.d(TAG, "Bugreport notification title " + shareTitle
12947                + " description " + shareDescription);
12948        requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12949    }
12950
12951    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12952        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12953    }
12954
12955    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12956        if (r != null && (r.instr != null || r.usingWrapper)) {
12957            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12958        }
12959        return KEY_DISPATCHING_TIMEOUT;
12960    }
12961
12962    @Override
12963    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12964        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12965                != PackageManager.PERMISSION_GRANTED) {
12966            throw new SecurityException("Requires permission "
12967                    + android.Manifest.permission.FILTER_EVENTS);
12968        }
12969        ProcessRecord proc;
12970        long timeout;
12971        synchronized (this) {
12972            synchronized (mPidsSelfLocked) {
12973                proc = mPidsSelfLocked.get(pid);
12974            }
12975            timeout = getInputDispatchingTimeoutLocked(proc);
12976        }
12977
12978        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12979            return -1;
12980        }
12981
12982        return timeout;
12983    }
12984
12985    /**
12986     * Handle input dispatching timeouts.
12987     * Returns whether input dispatching should be aborted or not.
12988     */
12989    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12990            final ActivityRecord activity, final ActivityRecord parent,
12991            final boolean aboveSystem, String reason) {
12992        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12993                != PackageManager.PERMISSION_GRANTED) {
12994            throw new SecurityException("Requires permission "
12995                    + android.Manifest.permission.FILTER_EVENTS);
12996        }
12997
12998        final String annotation;
12999        if (reason == null) {
13000            annotation = "Input dispatching timed out";
13001        } else {
13002            annotation = "Input dispatching timed out (" + reason + ")";
13003        }
13004
13005        if (proc != null) {
13006            synchronized (this) {
13007                if (proc.debugging) {
13008                    return false;
13009                }
13010
13011                if (proc.instr != null) {
13012                    Bundle info = new Bundle();
13013                    info.putString("shortMsg", "keyDispatchingTimedOut");
13014                    info.putString("longMsg", annotation);
13015                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13016                    return true;
13017                }
13018            }
13019            mHandler.post(new Runnable() {
13020                @Override
13021                public void run() {
13022                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13023                }
13024            });
13025        }
13026
13027        return true;
13028    }
13029
13030    @Override
13031    public Bundle getAssistContextExtras(int requestType) {
13032        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13033                null, null, true /* focused */, true /* newSessionId */,
13034                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13035        if (pae == null) {
13036            return null;
13037        }
13038        synchronized (pae) {
13039            while (!pae.haveResult) {
13040                try {
13041                    pae.wait();
13042                } catch (InterruptedException e) {
13043                }
13044            }
13045        }
13046        synchronized (this) {
13047            buildAssistBundleLocked(pae, pae.result);
13048            mPendingAssistExtras.remove(pae);
13049            mUiHandler.removeCallbacks(pae);
13050        }
13051        return pae.extras;
13052    }
13053
13054    @Override
13055    public boolean isAssistDataAllowedOnCurrentActivity() {
13056        int userId;
13057        synchronized (this) {
13058            final ActivityStack focusedStack = getFocusedStack();
13059            if (focusedStack == null || focusedStack.isAssistantStack()) {
13060                return false;
13061            }
13062
13063            final ActivityRecord activity = focusedStack.topActivity();
13064            if (activity == null) {
13065                return false;
13066            }
13067            userId = activity.userId;
13068        }
13069        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13070                Context.DEVICE_POLICY_SERVICE);
13071        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13072    }
13073
13074    @Override
13075    public boolean showAssistFromActivity(IBinder token, Bundle args) {
13076        long ident = Binder.clearCallingIdentity();
13077        try {
13078            synchronized (this) {
13079                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13080                ActivityRecord top = getFocusedStack().topActivity();
13081                if (top != caller) {
13082                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13083                            + " is not current top " + top);
13084                    return false;
13085                }
13086                if (!top.nowVisible) {
13087                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13088                            + " is not visible");
13089                    return false;
13090                }
13091            }
13092            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13093                    token);
13094        } finally {
13095            Binder.restoreCallingIdentity(ident);
13096        }
13097    }
13098
13099    @Override
13100    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13101            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13102        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13103                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13104                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13105    }
13106
13107    @Override
13108    public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13109            IBinder activityToken, int flags) {
13110        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13111                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13112                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13113    }
13114
13115    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13116            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13117            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13118            int flags) {
13119        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13120                "enqueueAssistContext()");
13121
13122        synchronized (this) {
13123            ActivityRecord activity = getFocusedStack().topActivity();
13124            if (activity == null) {
13125                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13126                return null;
13127            }
13128            if (activity.app == null || activity.app.thread == null) {
13129                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13130                return null;
13131            }
13132            if (focused) {
13133                if (activityToken != null) {
13134                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13135                    if (activity != caller) {
13136                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13137                                + " is not current top " + activity);
13138                        return null;
13139                    }
13140                }
13141            } else {
13142                activity = ActivityRecord.forTokenLocked(activityToken);
13143                if (activity == null) {
13144                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13145                            + " couldn't be found");
13146                    return null;
13147                }
13148                if (activity.app == null || activity.app.thread == null) {
13149                    Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13150                    return null;
13151                }
13152            }
13153
13154            PendingAssistExtras pae;
13155            Bundle extras = new Bundle();
13156            if (args != null) {
13157                extras.putAll(args);
13158            }
13159            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13160            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13161
13162            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13163                    userHandle);
13164            pae.isHome = activity.isHomeActivity();
13165
13166            // Increment the sessionId if necessary
13167            if (newSessionId) {
13168                mViSessionId++;
13169            }
13170            try {
13171                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13172                        mViSessionId, flags);
13173                mPendingAssistExtras.add(pae);
13174                mUiHandler.postDelayed(pae, timeout);
13175            } catch (RemoteException e) {
13176                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13177                return null;
13178            }
13179            return pae;
13180        }
13181    }
13182
13183    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13184        IResultReceiver receiver;
13185        synchronized (this) {
13186            mPendingAssistExtras.remove(pae);
13187            receiver = pae.receiver;
13188        }
13189        if (receiver != null) {
13190            // Caller wants result sent back to them.
13191            Bundle sendBundle = new Bundle();
13192            // At least return the receiver extras
13193            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13194                    pae.receiverExtras);
13195            try {
13196                pae.receiver.send(0, sendBundle);
13197            } catch (RemoteException e) {
13198            }
13199        }
13200    }
13201
13202    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13203        if (result != null) {
13204            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13205        }
13206        if (pae.hint != null) {
13207            pae.extras.putBoolean(pae.hint, true);
13208        }
13209    }
13210
13211    /** Called from an app when assist data is ready. */
13212    @Override
13213    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13214            AssistContent content, Uri referrer) {
13215        PendingAssistExtras pae = (PendingAssistExtras)token;
13216        synchronized (pae) {
13217            pae.result = extras;
13218            pae.structure = structure;
13219            pae.content = content;
13220            if (referrer != null) {
13221                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13222            }
13223            if (structure != null) {
13224                structure.setHomeActivity(pae.isHome);
13225            }
13226            pae.haveResult = true;
13227            pae.notifyAll();
13228            if (pae.intent == null && pae.receiver == null) {
13229                // Caller is just waiting for the result.
13230                return;
13231            }
13232        }
13233        // We are now ready to launch the assist activity.
13234        IResultReceiver sendReceiver = null;
13235        Bundle sendBundle = null;
13236        synchronized (this) {
13237            buildAssistBundleLocked(pae, extras);
13238            boolean exists = mPendingAssistExtras.remove(pae);
13239            mUiHandler.removeCallbacks(pae);
13240            if (!exists) {
13241                // Timed out.
13242                return;
13243            }
13244            if ((sendReceiver=pae.receiver) != null) {
13245                // Caller wants result sent back to them.
13246                sendBundle = new Bundle();
13247                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13248                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13249                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13250                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13251                        pae.receiverExtras);
13252            }
13253        }
13254        if (sendReceiver != null) {
13255            try {
13256                sendReceiver.send(0, sendBundle);
13257            } catch (RemoteException e) {
13258            }
13259            return;
13260        }
13261
13262        final long ident = Binder.clearCallingIdentity();
13263        try {
13264            if (TextUtils.equals(pae.intent.getAction(),
13265                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13266                pae.intent.putExtras(pae.extras);
13267                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13268            } else {
13269                pae.intent.replaceExtras(pae.extras);
13270                pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13271                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
13272                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13273                closeSystemDialogs("assist");
13274
13275                try {
13276                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13277                } catch (ActivityNotFoundException e) {
13278                    Slog.w(TAG, "No activity to handle assist action.", e);
13279                }
13280            }
13281        } finally {
13282            Binder.restoreCallingIdentity(ident);
13283        }
13284    }
13285
13286    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13287            Bundle args) {
13288        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13289                true /* focused */, true /* newSessionId */, userHandle, args,
13290                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13291    }
13292
13293    public void registerProcessObserver(IProcessObserver observer) {
13294        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13295                "registerProcessObserver()");
13296        synchronized (this) {
13297            mProcessObservers.register(observer);
13298        }
13299    }
13300
13301    @Override
13302    public void unregisterProcessObserver(IProcessObserver observer) {
13303        synchronized (this) {
13304            mProcessObservers.unregister(observer);
13305        }
13306    }
13307
13308    @Override
13309    public int getUidProcessState(int uid, String callingPackage) {
13310        if (!hasUsageStatsPermission(callingPackage)) {
13311            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13312                    "getUidProcessState");
13313        }
13314
13315        synchronized (this) {
13316            UidRecord uidRec = mActiveUids.get(uid);
13317            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13318        }
13319    }
13320
13321    @Override
13322    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13323            String callingPackage) {
13324        if (!hasUsageStatsPermission(callingPackage)) {
13325            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13326                    "registerUidObserver");
13327        }
13328        synchronized (this) {
13329            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13330                    callingPackage, which, cutpoint));
13331        }
13332    }
13333
13334    @Override
13335    public void unregisterUidObserver(IUidObserver observer) {
13336        synchronized (this) {
13337            mUidObservers.unregister(observer);
13338        }
13339    }
13340
13341    @Override
13342    public boolean convertFromTranslucent(IBinder token) {
13343        final long origId = Binder.clearCallingIdentity();
13344        try {
13345            synchronized (this) {
13346                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13347                if (r == null) {
13348                    return false;
13349                }
13350                final boolean translucentChanged = r.changeWindowTranslucency(true);
13351                if (translucentChanged) {
13352                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13353                }
13354                mWindowManager.setAppFullscreen(token, true);
13355                return translucentChanged;
13356            }
13357        } finally {
13358            Binder.restoreCallingIdentity(origId);
13359        }
13360    }
13361
13362    @Override
13363    public boolean convertToTranslucent(IBinder token, Bundle options) {
13364        final long origId = Binder.clearCallingIdentity();
13365        try {
13366            synchronized (this) {
13367                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13368                if (r == null) {
13369                    return false;
13370                }
13371                final TaskRecord task = r.getTask();
13372                int index = task.mActivities.lastIndexOf(r);
13373                if (index > 0) {
13374                    ActivityRecord under = task.mActivities.get(index - 1);
13375                    under.returningOptions = ActivityOptions.fromBundle(options);
13376                }
13377                final boolean translucentChanged = r.changeWindowTranslucency(false);
13378                if (translucentChanged) {
13379                    r.getStack().convertActivityToTranslucent(r);
13380                }
13381                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13382                mWindowManager.setAppFullscreen(token, false);
13383                return translucentChanged;
13384            }
13385        } finally {
13386            Binder.restoreCallingIdentity(origId);
13387        }
13388    }
13389
13390    @Override
13391    public Bundle getActivityOptions(IBinder token) {
13392        final long origId = Binder.clearCallingIdentity();
13393        try {
13394            synchronized (this) {
13395                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13396                if (r != null) {
13397                    final ActivityOptions activityOptions = r.takeOptionsLocked();
13398                    return activityOptions == null ? null : activityOptions.toBundle();
13399                }
13400                return null;
13401            }
13402        } finally {
13403            Binder.restoreCallingIdentity(origId);
13404        }
13405    }
13406
13407    @Override
13408    public void setImmersive(IBinder token, boolean immersive) {
13409        synchronized(this) {
13410            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13411            if (r == null) {
13412                throw new IllegalArgumentException();
13413            }
13414            r.immersive = immersive;
13415
13416            // update associated state if we're frontmost
13417            if (r == mStackSupervisor.getResumedActivityLocked()) {
13418                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13419                applyUpdateLockStateLocked(r);
13420            }
13421        }
13422    }
13423
13424    @Override
13425    public boolean isImmersive(IBinder token) {
13426        synchronized (this) {
13427            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13428            if (r == null) {
13429                throw new IllegalArgumentException();
13430            }
13431            return r.immersive;
13432        }
13433    }
13434
13435    @Override
13436    public void setVrThread(int tid) {
13437        enforceSystemHasVrFeature();
13438        synchronized (this) {
13439            synchronized (mPidsSelfLocked) {
13440                final int pid = Binder.getCallingPid();
13441                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13442                mVrController.setVrThreadLocked(tid, pid, proc);
13443            }
13444        }
13445    }
13446
13447    @Override
13448    public void setPersistentVrThread(int tid) {
13449        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13450            final String msg = "Permission Denial: setPersistentVrThread() from pid="
13451                    + Binder.getCallingPid()
13452                    + ", uid=" + Binder.getCallingUid()
13453                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13454            Slog.w(TAG, msg);
13455            throw new SecurityException(msg);
13456        }
13457        enforceSystemHasVrFeature();
13458        synchronized (this) {
13459            synchronized (mPidsSelfLocked) {
13460                final int pid = Binder.getCallingPid();
13461                final ProcessRecord proc = mPidsSelfLocked.get(pid);
13462                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13463            }
13464        }
13465    }
13466
13467    /**
13468     * Schedule the given thread a normal scheduling priority.
13469     *
13470     * @param tid the tid of the thread to adjust the scheduling of.
13471     * @param suppressLogs {@code true} if any error logging should be disabled.
13472     *
13473     * @return {@code true} if this succeeded.
13474     */
13475    static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13476        try {
13477            Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13478            return true;
13479        } catch (IllegalArgumentException e) {
13480            if (!suppressLogs) {
13481                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13482            }
13483        } catch (SecurityException e) {
13484            if (!suppressLogs) {
13485                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13486            }
13487        }
13488        return false;
13489    }
13490
13491    /**
13492     * Schedule the given thread an FIFO scheduling priority.
13493     *
13494     * @param tid the tid of the thread to adjust the scheduling of.
13495     * @param suppressLogs {@code true} if any error logging should be disabled.
13496     *
13497     * @return {@code true} if this succeeded.
13498     */
13499    static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13500        try {
13501            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13502            return true;
13503        } catch (IllegalArgumentException e) {
13504            if (!suppressLogs) {
13505                Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13506            }
13507        } catch (SecurityException e) {
13508            if (!suppressLogs) {
13509                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13510            }
13511        }
13512        return false;
13513    }
13514
13515    /**
13516     * Check that we have the features required for VR-related API calls, and throw an exception if
13517     * not.
13518     */
13519    private void enforceSystemHasVrFeature() {
13520        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13521            throw new UnsupportedOperationException("VR mode not supported on this device!");
13522        }
13523    }
13524
13525    @Override
13526    public void setRenderThread(int tid) {
13527        synchronized (this) {
13528            ProcessRecord proc;
13529            int pid = Binder.getCallingPid();
13530            if (pid == Process.myPid()) {
13531                demoteSystemServerRenderThread(tid);
13532                return;
13533            }
13534            synchronized (mPidsSelfLocked) {
13535                proc = mPidsSelfLocked.get(pid);
13536                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13537                    // ensure the tid belongs to the process
13538                    if (!isThreadInProcess(pid, tid)) {
13539                        throw new IllegalArgumentException(
13540                            "Render thread does not belong to process");
13541                    }
13542                    proc.renderThreadTid = tid;
13543                    if (DEBUG_OOM_ADJ) {
13544                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13545                    }
13546                    // promote to FIFO now
13547                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13548                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13549                        if (mUseFifoUiScheduling) {
13550                            setThreadScheduler(proc.renderThreadTid,
13551                                SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13552                        } else {
13553                            setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13554                        }
13555                    }
13556                } else {
13557                    if (DEBUG_OOM_ADJ) {
13558                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13559                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13560                               mUseFifoUiScheduling);
13561                    }
13562                }
13563            }
13564        }
13565    }
13566
13567    /**
13568     * We only use RenderThread in system_server to store task snapshots to the disk, which should
13569     * happen in the background. Thus, demote render thread from system_server to a lower priority.
13570     *
13571     * @param tid the tid of the RenderThread
13572     */
13573    private void demoteSystemServerRenderThread(int tid) {
13574        setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13575    }
13576
13577    @Override
13578    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13579        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13580            throw new UnsupportedOperationException("VR mode not supported on this device!");
13581        }
13582
13583        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13584
13585        ActivityRecord r;
13586        synchronized (this) {
13587            r = ActivityRecord.isInStackLocked(token);
13588        }
13589
13590        if (r == null) {
13591            throw new IllegalArgumentException();
13592        }
13593
13594        int err;
13595        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13596                VrManagerInternal.NO_ERROR) {
13597            return err;
13598        }
13599
13600        synchronized(this) {
13601            r.requestedVrComponent = (enabled) ? packageName : null;
13602
13603            // Update associated state if this activity is currently focused
13604            if (r == mStackSupervisor.getResumedActivityLocked()) {
13605                applyUpdateVrModeLocked(r);
13606            }
13607            return 0;
13608        }
13609    }
13610
13611    @Override
13612    public boolean isVrModePackageEnabled(ComponentName packageName) {
13613        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13614            throw new UnsupportedOperationException("VR mode not supported on this device!");
13615        }
13616
13617        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13618
13619        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13620                VrManagerInternal.NO_ERROR;
13621    }
13622
13623    public boolean isTopActivityImmersive() {
13624        enforceNotIsolatedCaller("startActivity");
13625        synchronized (this) {
13626            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13627            return (r != null) ? r.immersive : false;
13628        }
13629    }
13630
13631    /**
13632     * @return whether the system should disable UI modes incompatible with VR mode.
13633     */
13634    boolean shouldDisableNonVrUiLocked() {
13635        return mVrController.shouldDisableNonVrUiLocked();
13636    }
13637
13638    @Override
13639    public boolean isTopOfTask(IBinder token) {
13640        synchronized (this) {
13641            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13642            if (r == null) {
13643                throw new IllegalArgumentException();
13644            }
13645            return r.getTask().getTopActivity() == r;
13646        }
13647    }
13648
13649    @Override
13650    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13651        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13652            String msg = "Permission Denial: setHasTopUi() from pid="
13653                    + Binder.getCallingPid()
13654                    + ", uid=" + Binder.getCallingUid()
13655                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13656            Slog.w(TAG, msg);
13657            throw new SecurityException(msg);
13658        }
13659        final int pid = Binder.getCallingPid();
13660        final long origId = Binder.clearCallingIdentity();
13661        try {
13662            synchronized (this) {
13663                boolean changed = false;
13664                ProcessRecord pr;
13665                synchronized (mPidsSelfLocked) {
13666                    pr = mPidsSelfLocked.get(pid);
13667                    if (pr == null) {
13668                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13669                        return;
13670                    }
13671                    if (pr.hasTopUi != hasTopUi) {
13672                        if (DEBUG_OOM_ADJ) {
13673                            Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13674                        }
13675                        pr.hasTopUi = hasTopUi;
13676                        changed = true;
13677                    }
13678                }
13679                if (changed) {
13680                    updateOomAdjLocked(pr, true);
13681                }
13682            }
13683        } finally {
13684            Binder.restoreCallingIdentity(origId);
13685        }
13686    }
13687
13688    public final void enterSafeMode() {
13689        synchronized(this) {
13690            // It only makes sense to do this before the system is ready
13691            // and started launching other packages.
13692            if (!mSystemReady) {
13693                try {
13694                    AppGlobals.getPackageManager().enterSafeMode();
13695                } catch (RemoteException e) {
13696                }
13697            }
13698
13699            mSafeMode = true;
13700        }
13701    }
13702
13703    public final void showSafeModeOverlay() {
13704        View v = LayoutInflater.from(mContext).inflate(
13705                com.android.internal.R.layout.safe_mode, null);
13706        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13707        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13708        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13709        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13710        lp.gravity = Gravity.BOTTOM | Gravity.START;
13711        lp.format = v.getBackground().getOpacity();
13712        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13713                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13714        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13715        ((WindowManager)mContext.getSystemService(
13716                Context.WINDOW_SERVICE)).addView(v, lp);
13717    }
13718
13719    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13720        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13721            return;
13722        }
13723        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13724        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13725        synchronized (stats) {
13726            if (mBatteryStatsService.isOnBattery()) {
13727                mBatteryStatsService.enforceCallingPermission();
13728                int MY_UID = Binder.getCallingUid();
13729                final int uid;
13730                if (sender == null) {
13731                    uid = sourceUid;
13732                } else {
13733                    uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13734                }
13735                BatteryStatsImpl.Uid.Pkg pkg =
13736                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13737                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13738                pkg.noteWakeupAlarmLocked(tag);
13739            }
13740        }
13741    }
13742
13743    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13744        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13745            return;
13746        }
13747        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13748        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13749        synchronized (stats) {
13750            mBatteryStatsService.enforceCallingPermission();
13751            int MY_UID = Binder.getCallingUid();
13752            final int uid;
13753            if (sender == null) {
13754                uid = sourceUid;
13755            } else {
13756                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13757            }
13758            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13759        }
13760    }
13761
13762    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13763        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13764            return;
13765        }
13766        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13767        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13768        synchronized (stats) {
13769            mBatteryStatsService.enforceCallingPermission();
13770            int MY_UID = Binder.getCallingUid();
13771            final int uid;
13772            if (sender == null) {
13773                uid = sourceUid;
13774            } else {
13775                uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13776            }
13777            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13778        }
13779    }
13780
13781    public boolean killPids(int[] pids, String pReason, boolean secure) {
13782        if (Binder.getCallingUid() != SYSTEM_UID) {
13783            throw new SecurityException("killPids only available to the system");
13784        }
13785        String reason = (pReason == null) ? "Unknown" : pReason;
13786        // XXX Note: don't acquire main activity lock here, because the window
13787        // manager calls in with its locks held.
13788
13789        boolean killed = false;
13790        synchronized (mPidsSelfLocked) {
13791            int worstType = 0;
13792            for (int i=0; i<pids.length; i++) {
13793                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13794                if (proc != null) {
13795                    int type = proc.setAdj;
13796                    if (type > worstType) {
13797                        worstType = type;
13798                    }
13799                }
13800            }
13801
13802            // If the worst oom_adj is somewhere in the cached proc LRU range,
13803            // then constrain it so we will kill all cached procs.
13804            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13805                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13806                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13807            }
13808
13809            // If this is not a secure call, don't let it kill processes that
13810            // are important.
13811            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13812                worstType = ProcessList.SERVICE_ADJ;
13813            }
13814
13815            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13816            for (int i=0; i<pids.length; i++) {
13817                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13818                if (proc == null) {
13819                    continue;
13820                }
13821                int adj = proc.setAdj;
13822                if (adj >= worstType && !proc.killedByAm) {
13823                    proc.kill(reason, true);
13824                    killed = true;
13825                }
13826            }
13827        }
13828        return killed;
13829    }
13830
13831    @Override
13832    public void killUid(int appId, int userId, String reason) {
13833        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13834        synchronized (this) {
13835            final long identity = Binder.clearCallingIdentity();
13836            try {
13837                killPackageProcessesLocked(null, appId, userId,
13838                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13839                        reason != null ? reason : "kill uid");
13840            } finally {
13841                Binder.restoreCallingIdentity(identity);
13842            }
13843        }
13844    }
13845
13846    @Override
13847    public boolean killProcessesBelowForeground(String reason) {
13848        if (Binder.getCallingUid() != SYSTEM_UID) {
13849            throw new SecurityException("killProcessesBelowForeground() only available to system");
13850        }
13851
13852        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13853    }
13854
13855    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13856        if (Binder.getCallingUid() != SYSTEM_UID) {
13857            throw new SecurityException("killProcessesBelowAdj() only available to system");
13858        }
13859
13860        boolean killed = false;
13861        synchronized (mPidsSelfLocked) {
13862            final int size = mPidsSelfLocked.size();
13863            for (int i = 0; i < size; i++) {
13864                final int pid = mPidsSelfLocked.keyAt(i);
13865                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13866                if (proc == null) continue;
13867
13868                final int adj = proc.setAdj;
13869                if (adj > belowAdj && !proc.killedByAm) {
13870                    proc.kill(reason, true);
13871                    killed = true;
13872                }
13873            }
13874        }
13875        return killed;
13876    }
13877
13878    @Override
13879    public void hang(final IBinder who, boolean allowRestart) {
13880        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13881                != PackageManager.PERMISSION_GRANTED) {
13882            throw new SecurityException("Requires permission "
13883                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13884        }
13885
13886        final IBinder.DeathRecipient death = new DeathRecipient() {
13887            @Override
13888            public void binderDied() {
13889                synchronized (this) {
13890                    notifyAll();
13891                }
13892            }
13893        };
13894
13895        try {
13896            who.linkToDeath(death, 0);
13897        } catch (RemoteException e) {
13898            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13899            return;
13900        }
13901
13902        synchronized (this) {
13903            Watchdog.getInstance().setAllowRestart(allowRestart);
13904            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13905            synchronized (death) {
13906                while (who.isBinderAlive()) {
13907                    try {
13908                        death.wait();
13909                    } catch (InterruptedException e) {
13910                    }
13911                }
13912            }
13913            Watchdog.getInstance().setAllowRestart(true);
13914        }
13915    }
13916
13917    @Override
13918    public void restart() {
13919        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13920                != PackageManager.PERMISSION_GRANTED) {
13921            throw new SecurityException("Requires permission "
13922                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13923        }
13924
13925        Log.i(TAG, "Sending shutdown broadcast...");
13926
13927        BroadcastReceiver br = new BroadcastReceiver() {
13928            @Override public void onReceive(Context context, Intent intent) {
13929                // Now the broadcast is done, finish up the low-level shutdown.
13930                Log.i(TAG, "Shutting down activity manager...");
13931                shutdown(10000);
13932                Log.i(TAG, "Shutdown complete, restarting!");
13933                killProcess(myPid());
13934                System.exit(10);
13935            }
13936        };
13937
13938        // First send the high-level shut down broadcast.
13939        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13940        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13941        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13942        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13943        mContext.sendOrderedBroadcastAsUser(intent,
13944                UserHandle.ALL, null, br, mHandler, 0, null, null);
13945        */
13946        br.onReceive(mContext, intent);
13947    }
13948
13949    private long getLowRamTimeSinceIdle(long now) {
13950        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13951    }
13952
13953    @Override
13954    public void performIdleMaintenance() {
13955        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13956                != PackageManager.PERMISSION_GRANTED) {
13957            throw new SecurityException("Requires permission "
13958                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13959        }
13960
13961        synchronized (this) {
13962            final long now = SystemClock.uptimeMillis();
13963            final long timeSinceLastIdle = now - mLastIdleTime;
13964            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13965            mLastIdleTime = now;
13966            mLowRamTimeSinceLastIdle = 0;
13967            if (mLowRamStartTime != 0) {
13968                mLowRamStartTime = now;
13969            }
13970
13971            StringBuilder sb = new StringBuilder(128);
13972            sb.append("Idle maintenance over ");
13973            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13974            sb.append(" low RAM for ");
13975            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13976            Slog.i(TAG, sb.toString());
13977
13978            // If at least 1/3 of our time since the last idle period has been spent
13979            // with RAM low, then we want to kill processes.
13980            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13981
13982            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13983                ProcessRecord proc = mLruProcesses.get(i);
13984                if (proc.notCachedSinceIdle) {
13985                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13986                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13987                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13988                        if (doKilling && proc.initialIdlePss != 0
13989                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13990                            sb = new StringBuilder(128);
13991                            sb.append("Kill");
13992                            sb.append(proc.processName);
13993                            sb.append(" in idle maint: pss=");
13994                            sb.append(proc.lastPss);
13995                            sb.append(", swapPss=");
13996                            sb.append(proc.lastSwapPss);
13997                            sb.append(", initialPss=");
13998                            sb.append(proc.initialIdlePss);
13999                            sb.append(", period=");
14000                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
14001                            sb.append(", lowRamPeriod=");
14002                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14003                            Slog.wtfQuiet(TAG, sb.toString());
14004                            proc.kill("idle maint (pss " + proc.lastPss
14005                                    + " from " + proc.initialIdlePss + ")", true);
14006                        }
14007                    }
14008                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14009                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14010                    proc.notCachedSinceIdle = true;
14011                    proc.initialIdlePss = 0;
14012                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14013                            mTestPssMode, isSleepingLocked(), now);
14014                }
14015            }
14016
14017            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14018            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14019        }
14020    }
14021
14022    @Override
14023    public void sendIdleJobTrigger() {
14024        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14025                != PackageManager.PERMISSION_GRANTED) {
14026            throw new SecurityException("Requires permission "
14027                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14028        }
14029
14030        final long ident = Binder.clearCallingIdentity();
14031        try {
14032            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14033                    .setPackage("android")
14034                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14035            broadcastIntent(null, intent, null, null, 0, null, null, null,
14036                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14037        } finally {
14038            Binder.restoreCallingIdentity(ident);
14039        }
14040    }
14041
14042    private void retrieveSettings() {
14043        final ContentResolver resolver = mContext.getContentResolver();
14044        final boolean freeformWindowManagement =
14045                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14046                        || Settings.Global.getInt(
14047                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14048
14049        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14050        final boolean supportsPictureInPicture = supportsMultiWindow &&
14051                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14052        final boolean supportsSplitScreenMultiWindow =
14053                ActivityManager.supportsSplitScreenMultiWindow(mContext);
14054        final boolean supportsMultiDisplay = mContext.getPackageManager()
14055                .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14056        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14057        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14058        final boolean alwaysFinishActivities =
14059                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14060        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14061        final boolean forceResizable = Settings.Global.getInt(
14062                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14063        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14064                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14065        final boolean supportsLeanbackOnly =
14066                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14067
14068        // Transfer any global setting for forcing RTL layout, into a System Property
14069        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14070
14071        final Configuration configuration = new Configuration();
14072        Settings.System.getConfiguration(resolver, configuration);
14073        if (forceRtl) {
14074            // This will take care of setting the correct layout direction flags
14075            configuration.setLayoutDirection(configuration.locale);
14076        }
14077
14078        synchronized (this) {
14079            mDebugApp = mOrigDebugApp = debugApp;
14080            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14081            mAlwaysFinishActivities = alwaysFinishActivities;
14082            mSupportsLeanbackOnly = supportsLeanbackOnly;
14083            mForceResizableActivities = forceResizable;
14084            final boolean multiWindowFormEnabled = freeformWindowManagement
14085                    || supportsSplitScreenMultiWindow
14086                    || supportsPictureInPicture
14087                    || supportsMultiDisplay;
14088            if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14089                mSupportsMultiWindow = true;
14090                mSupportsFreeformWindowManagement = freeformWindowManagement;
14091                mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14092                mSupportsPictureInPicture = supportsPictureInPicture;
14093                mSupportsMultiDisplay = supportsMultiDisplay;
14094            } else {
14095                mSupportsMultiWindow = false;
14096                mSupportsFreeformWindowManagement = false;
14097                mSupportsSplitScreenMultiWindow = false;
14098                mSupportsPictureInPicture = false;
14099                mSupportsMultiDisplay = false;
14100            }
14101            mWindowManager.setForceResizableTasks(mForceResizableActivities);
14102            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14103            // This happens before any activities are started, so we can change global configuration
14104            // in-place.
14105            updateConfigurationLocked(configuration, null, true);
14106            final Configuration globalConfig = getGlobalConfiguration();
14107            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14108
14109            // Load resources only after the current configuration has been set.
14110            final Resources res = mContext.getResources();
14111            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14112            mThumbnailWidth = res.getDimensionPixelSize(
14113                    com.android.internal.R.dimen.thumbnail_width);
14114            mThumbnailHeight = res.getDimensionPixelSize(
14115                    com.android.internal.R.dimen.thumbnail_height);
14116            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14117                    com.android.internal.R.string.config_appsNotReportingCrashes));
14118            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14119                    com.android.internal.R.bool.config_customUserSwitchUi);
14120            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14121                mFullscreenThumbnailScale = (float) res
14122                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14123                    (float) globalConfig.screenWidthDp;
14124            } else {
14125                mFullscreenThumbnailScale = res.getFraction(
14126                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14127            }
14128            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14129        }
14130    }
14131
14132    public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14133        traceLog.traceBegin("PhaseActivityManagerReady");
14134        synchronized(this) {
14135            if (mSystemReady) {
14136                // If we're done calling all the receivers, run the next "boot phase" passed in
14137                // by the SystemServer
14138                if (goingCallback != null) {
14139                    goingCallback.run();
14140                }
14141                return;
14142            }
14143
14144            mLocalDeviceIdleController
14145                    = LocalServices.getService(DeviceIdleController.LocalService.class);
14146            mAssistUtils = new AssistUtils(mContext);
14147            mVrController.onSystemReady();
14148            // Make sure we have the current profile info, since it is needed for security checks.
14149            mUserController.onSystemReady();
14150            mRecentTasks.onSystemReadyLocked();
14151            mAppOpsService.systemReady();
14152            mSystemReady = true;
14153        }
14154
14155        try {
14156            sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14157                    ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14158                    .getSerial();
14159        } catch (RemoteException e) {}
14160
14161        ArrayList<ProcessRecord> procsToKill = null;
14162        synchronized(mPidsSelfLocked) {
14163            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14164                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14165                if (!isAllowedWhileBooting(proc.info)){
14166                    if (procsToKill == null) {
14167                        procsToKill = new ArrayList<ProcessRecord>();
14168                    }
14169                    procsToKill.add(proc);
14170                }
14171            }
14172        }
14173
14174        synchronized(this) {
14175            if (procsToKill != null) {
14176                for (int i=procsToKill.size()-1; i>=0; i--) {
14177                    ProcessRecord proc = procsToKill.get(i);
14178                    Slog.i(TAG, "Removing system update proc: " + proc);
14179                    removeProcessLocked(proc, true, false, "system update done");
14180                }
14181            }
14182
14183            // Now that we have cleaned up any update processes, we
14184            // are ready to start launching real processes and know that
14185            // we won't trample on them any more.
14186            mProcessesReady = true;
14187        }
14188
14189        Slog.i(TAG, "System now ready");
14190        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14191            SystemClock.uptimeMillis());
14192
14193        synchronized(this) {
14194            // Make sure we have no pre-ready processes sitting around.
14195
14196            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14197                ResolveInfo ri = mContext.getPackageManager()
14198                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14199                                STOCK_PM_FLAGS);
14200                CharSequence errorMsg = null;
14201                if (ri != null) {
14202                    ActivityInfo ai = ri.activityInfo;
14203                    ApplicationInfo app = ai.applicationInfo;
14204                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14205                        mTopAction = Intent.ACTION_FACTORY_TEST;
14206                        mTopData = null;
14207                        mTopComponent = new ComponentName(app.packageName,
14208                                ai.name);
14209                    } else {
14210                        errorMsg = mContext.getResources().getText(
14211                                com.android.internal.R.string.factorytest_not_system);
14212                    }
14213                } else {
14214                    errorMsg = mContext.getResources().getText(
14215                            com.android.internal.R.string.factorytest_no_action);
14216                }
14217                if (errorMsg != null) {
14218                    mTopAction = null;
14219                    mTopData = null;
14220                    mTopComponent = null;
14221                    Message msg = Message.obtain();
14222                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14223                    msg.getData().putCharSequence("msg", errorMsg);
14224                    mUiHandler.sendMessage(msg);
14225                }
14226            }
14227        }
14228
14229        retrieveSettings();
14230        final int currentUserId;
14231        synchronized (this) {
14232            currentUserId = mUserController.getCurrentUserIdLocked();
14233            readGrantedUriPermissionsLocked();
14234        }
14235
14236        if (goingCallback != null) goingCallback.run();
14237        traceLog.traceBegin("ActivityManagerStartApps");
14238        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14239                Integer.toString(currentUserId), currentUserId);
14240        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14241                Integer.toString(currentUserId), currentUserId);
14242        mSystemServiceManager.startUser(currentUserId);
14243
14244        synchronized (this) {
14245            // Only start up encryption-aware persistent apps; once user is
14246            // unlocked we'll come back around and start unaware apps
14247            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14248
14249            // Start up initial activity.
14250            mBooting = true;
14251            // Enable home activity for system user, so that the system can always boot. We don't
14252            // do this when the system user is not setup since the setup wizard should be the one
14253            // to handle home activity in this case.
14254            if (UserManager.isSplitSystemUser() &&
14255                    Settings.Secure.getInt(mContext.getContentResolver(),
14256                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14257                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14258                try {
14259                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14260                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14261                            UserHandle.USER_SYSTEM);
14262                } catch (RemoteException e) {
14263                    throw e.rethrowAsRuntimeException();
14264                }
14265            }
14266            startHomeActivityLocked(currentUserId, "systemReady");
14267
14268            try {
14269                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14270                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14271                            + " data partition or your device will be unstable.");
14272                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14273                }
14274            } catch (RemoteException e) {
14275            }
14276
14277            if (!Build.isBuildConsistent()) {
14278                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14279                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14280            }
14281
14282            long ident = Binder.clearCallingIdentity();
14283            try {
14284                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14285                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14286                        | Intent.FLAG_RECEIVER_FOREGROUND);
14287                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14288                broadcastIntentLocked(null, null, intent,
14289                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14290                        null, false, false, MY_PID, SYSTEM_UID,
14291                        currentUserId);
14292                intent = new Intent(Intent.ACTION_USER_STARTING);
14293                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14294                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14295                broadcastIntentLocked(null, null, intent,
14296                        null, new IIntentReceiver.Stub() {
14297                            @Override
14298                            public void performReceive(Intent intent, int resultCode, String data,
14299                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14300                                    throws RemoteException {
14301                            }
14302                        }, 0, null, null,
14303                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14304                        null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14305            } catch (Throwable t) {
14306                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14307            } finally {
14308                Binder.restoreCallingIdentity(ident);
14309            }
14310            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14311            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14312            traceLog.traceEnd(); // ActivityManagerStartApps
14313            traceLog.traceEnd(); // PhaseActivityManagerReady
14314        }
14315    }
14316
14317    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14318        synchronized (this) {
14319            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14320        }
14321    }
14322
14323    void skipCurrentReceiverLocked(ProcessRecord app) {
14324        for (BroadcastQueue queue : mBroadcastQueues) {
14325            queue.skipCurrentReceiverLocked(app);
14326        }
14327    }
14328
14329    /**
14330     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14331     * The application process will exit immediately after this call returns.
14332     * @param app object of the crashing app, null for the system server
14333     * @param crashInfo describing the exception
14334     */
14335    public void handleApplicationCrash(IBinder app,
14336            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14337        ProcessRecord r = findAppProcess(app, "Crash");
14338        final String processName = app == null ? "system_server"
14339                : (r == null ? "unknown" : r.processName);
14340
14341        handleApplicationCrashInner("crash", r, processName, crashInfo);
14342    }
14343
14344    /* Native crash reporting uses this inner version because it needs to be somewhat
14345     * decoupled from the AM-managed cleanup lifecycle
14346     */
14347    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14348            ApplicationErrorReport.CrashInfo crashInfo) {
14349        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14350                UserHandle.getUserId(Binder.getCallingUid()), processName,
14351                r == null ? -1 : r.info.flags,
14352                crashInfo.exceptionClassName,
14353                crashInfo.exceptionMessage,
14354                crashInfo.throwFileName,
14355                crashInfo.throwLineNumber);
14356
14357        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14358
14359        mAppErrors.crashApplication(r, crashInfo);
14360    }
14361
14362    public void handleApplicationStrictModeViolation(
14363            IBinder app,
14364            int violationMask,
14365            StrictMode.ViolationInfo info) {
14366        ProcessRecord r = findAppProcess(app, "StrictMode");
14367        if (r == null) {
14368            return;
14369        }
14370
14371        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14372            Integer stackFingerprint = info.hashCode();
14373            boolean logIt = true;
14374            synchronized (mAlreadyLoggedViolatedStacks) {
14375                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14376                    logIt = false;
14377                    // TODO: sub-sample into EventLog for these, with
14378                    // the info.durationMillis?  Then we'd get
14379                    // the relative pain numbers, without logging all
14380                    // the stack traces repeatedly.  We'd want to do
14381                    // likewise in the client code, which also does
14382                    // dup suppression, before the Binder call.
14383                } else {
14384                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14385                        mAlreadyLoggedViolatedStacks.clear();
14386                    }
14387                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14388                }
14389            }
14390            if (logIt) {
14391                logStrictModeViolationToDropBox(r, info);
14392            }
14393        }
14394
14395        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14396            AppErrorResult result = new AppErrorResult();
14397            synchronized (this) {
14398                final long origId = Binder.clearCallingIdentity();
14399
14400                Message msg = Message.obtain();
14401                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14402                HashMap<String, Object> data = new HashMap<String, Object>();
14403                data.put("result", result);
14404                data.put("app", r);
14405                data.put("violationMask", violationMask);
14406                data.put("info", info);
14407                msg.obj = data;
14408                mUiHandler.sendMessage(msg);
14409
14410                Binder.restoreCallingIdentity(origId);
14411            }
14412            int res = result.get();
14413            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14414        }
14415    }
14416
14417    // Depending on the policy in effect, there could be a bunch of
14418    // these in quick succession so we try to batch these together to
14419    // minimize disk writes, number of dropbox entries, and maximize
14420    // compression, by having more fewer, larger records.
14421    private void logStrictModeViolationToDropBox(
14422            ProcessRecord process,
14423            StrictMode.ViolationInfo info) {
14424        if (info == null) {
14425            return;
14426        }
14427        final boolean isSystemApp = process == null ||
14428                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14429                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14430        final String processName = process == null ? "unknown" : process.processName;
14431        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14432        final DropBoxManager dbox = (DropBoxManager)
14433                mContext.getSystemService(Context.DROPBOX_SERVICE);
14434
14435        // Exit early if the dropbox isn't configured to accept this report type.
14436        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14437
14438        boolean bufferWasEmpty;
14439        boolean needsFlush;
14440        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14441        synchronized (sb) {
14442            bufferWasEmpty = sb.length() == 0;
14443            appendDropBoxProcessHeaders(process, processName, sb);
14444            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14445            sb.append("System-App: ").append(isSystemApp).append("\n");
14446            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14447            if (info.violationNumThisLoop != 0) {
14448                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14449            }
14450            if (info.numAnimationsRunning != 0) {
14451                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14452            }
14453            if (info.broadcastIntentAction != null) {
14454                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14455            }
14456            if (info.durationMillis != -1) {
14457                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14458            }
14459            if (info.numInstances != -1) {
14460                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14461            }
14462            if (info.tags != null) {
14463                for (String tag : info.tags) {
14464                    sb.append("Span-Tag: ").append(tag).append("\n");
14465                }
14466            }
14467            sb.append("\n");
14468            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14469                sb.append(info.crashInfo.stackTrace);
14470                sb.append("\n");
14471            }
14472            if (info.message != null) {
14473                sb.append(info.message);
14474                sb.append("\n");
14475            }
14476
14477            // Only buffer up to ~64k.  Various logging bits truncate
14478            // things at 128k.
14479            needsFlush = (sb.length() > 64 * 1024);
14480        }
14481
14482        // Flush immediately if the buffer's grown too large, or this
14483        // is a non-system app.  Non-system apps are isolated with a
14484        // different tag & policy and not batched.
14485        //
14486        // Batching is useful during internal testing with
14487        // StrictMode settings turned up high.  Without batching,
14488        // thousands of separate files could be created on boot.
14489        if (!isSystemApp || needsFlush) {
14490            new Thread("Error dump: " + dropboxTag) {
14491                @Override
14492                public void run() {
14493                    String report;
14494                    synchronized (sb) {
14495                        report = sb.toString();
14496                        sb.delete(0, sb.length());
14497                        sb.trimToSize();
14498                    }
14499                    if (report.length() != 0) {
14500                        dbox.addText(dropboxTag, report);
14501                    }
14502                }
14503            }.start();
14504            return;
14505        }
14506
14507        // System app batching:
14508        if (!bufferWasEmpty) {
14509            // An existing dropbox-writing thread is outstanding, so
14510            // we don't need to start it up.  The existing thread will
14511            // catch the buffer appends we just did.
14512            return;
14513        }
14514
14515        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14516        // (After this point, we shouldn't access AMS internal data structures.)
14517        new Thread("Error dump: " + dropboxTag) {
14518            @Override
14519            public void run() {
14520                // 5 second sleep to let stacks arrive and be batched together
14521                try {
14522                    Thread.sleep(5000);  // 5 seconds
14523                } catch (InterruptedException e) {}
14524
14525                String errorReport;
14526                synchronized (mStrictModeBuffer) {
14527                    errorReport = mStrictModeBuffer.toString();
14528                    if (errorReport.length() == 0) {
14529                        return;
14530                    }
14531                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14532                    mStrictModeBuffer.trimToSize();
14533                }
14534                dbox.addText(dropboxTag, errorReport);
14535            }
14536        }.start();
14537    }
14538
14539    /**
14540     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14541     * @param app object of the crashing app, null for the system server
14542     * @param tag reported by the caller
14543     * @param system whether this wtf is coming from the system
14544     * @param crashInfo describing the context of the error
14545     * @return true if the process should exit immediately (WTF is fatal)
14546     */
14547    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14548            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14549        final int callingUid = Binder.getCallingUid();
14550        final int callingPid = Binder.getCallingPid();
14551
14552        if (system) {
14553            // If this is coming from the system, we could very well have low-level
14554            // system locks held, so we want to do this all asynchronously.  And we
14555            // never want this to become fatal, so there is that too.
14556            mHandler.post(new Runnable() {
14557                @Override public void run() {
14558                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14559                }
14560            });
14561            return false;
14562        }
14563
14564        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14565                crashInfo);
14566
14567        final boolean isFatal = Build.IS_ENG || Settings.Global
14568                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14569        final boolean isSystem = (r == null) || r.persistent;
14570
14571        if (isFatal && !isSystem) {
14572            mAppErrors.crashApplication(r, crashInfo);
14573            return true;
14574        } else {
14575            return false;
14576        }
14577    }
14578
14579    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14580            final ApplicationErrorReport.CrashInfo crashInfo) {
14581        final ProcessRecord r = findAppProcess(app, "WTF");
14582        final String processName = app == null ? "system_server"
14583                : (r == null ? "unknown" : r.processName);
14584
14585        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14586                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14587
14588        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14589
14590        return r;
14591    }
14592
14593    /**
14594     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14595     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14596     */
14597    private ProcessRecord findAppProcess(IBinder app, String reason) {
14598        if (app == null) {
14599            return null;
14600        }
14601
14602        synchronized (this) {
14603            final int NP = mProcessNames.getMap().size();
14604            for (int ip=0; ip<NP; ip++) {
14605                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14606                final int NA = apps.size();
14607                for (int ia=0; ia<NA; ia++) {
14608                    ProcessRecord p = apps.valueAt(ia);
14609                    if (p.thread != null && p.thread.asBinder() == app) {
14610                        return p;
14611                    }
14612                }
14613            }
14614
14615            Slog.w(TAG, "Can't find mystery application for " + reason
14616                    + " from pid=" + Binder.getCallingPid()
14617                    + " uid=" + Binder.getCallingUid() + ": " + app);
14618            return null;
14619        }
14620    }
14621
14622    /**
14623     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14624     * to append various headers to the dropbox log text.
14625     */
14626    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14627            StringBuilder sb) {
14628        // Watchdog thread ends up invoking this function (with
14629        // a null ProcessRecord) to add the stack file to dropbox.
14630        // Do not acquire a lock on this (am) in such cases, as it
14631        // could cause a potential deadlock, if and when watchdog
14632        // is invoked due to unavailability of lock on am and it
14633        // would prevent watchdog from killing system_server.
14634        if (process == null) {
14635            sb.append("Process: ").append(processName).append("\n");
14636            return;
14637        }
14638        // Note: ProcessRecord 'process' is guarded by the service
14639        // instance.  (notably process.pkgList, which could otherwise change
14640        // concurrently during execution of this method)
14641        synchronized (this) {
14642            sb.append("Process: ").append(processName).append("\n");
14643            sb.append("PID: ").append(process.pid).append("\n");
14644            int flags = process.info.flags;
14645            IPackageManager pm = AppGlobals.getPackageManager();
14646            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14647            for (int ip=0; ip<process.pkgList.size(); ip++) {
14648                String pkg = process.pkgList.keyAt(ip);
14649                sb.append("Package: ").append(pkg);
14650                try {
14651                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14652                    if (pi != null) {
14653                        sb.append(" v").append(pi.versionCode);
14654                        if (pi.versionName != null) {
14655                            sb.append(" (").append(pi.versionName).append(")");
14656                        }
14657                    }
14658                } catch (RemoteException e) {
14659                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14660                }
14661                sb.append("\n");
14662            }
14663        }
14664    }
14665
14666    private static String processClass(ProcessRecord process) {
14667        if (process == null || process.pid == MY_PID) {
14668            return "system_server";
14669        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14670            return "system_app";
14671        } else {
14672            return "data_app";
14673        }
14674    }
14675
14676    private volatile long mWtfClusterStart;
14677    private volatile int mWtfClusterCount;
14678
14679    /**
14680     * Write a description of an error (crash, WTF, ANR) to the drop box.
14681     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14682     * @param process which caused the error, null means the system server
14683     * @param activity which triggered the error, null if unknown
14684     * @param parent activity related to the error, null if unknown
14685     * @param subject line related to the error, null if absent
14686     * @param report in long form describing the error, null if absent
14687     * @param dataFile text file to include in the report, null if none
14688     * @param crashInfo giving an application stack trace, null if absent
14689     */
14690    public void addErrorToDropBox(String eventType,
14691            ProcessRecord process, String processName, ActivityRecord activity,
14692            ActivityRecord parent, String subject,
14693            final String report, final File dataFile,
14694            final ApplicationErrorReport.CrashInfo crashInfo) {
14695        // NOTE -- this must never acquire the ActivityManagerService lock,
14696        // otherwise the watchdog may be prevented from resetting the system.
14697
14698        // Bail early if not published yet
14699        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14700        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14701
14702        // Exit early if the dropbox isn't configured to accept this report type.
14703        final String dropboxTag = processClass(process) + "_" + eventType;
14704        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14705
14706        // Rate-limit how often we're willing to do the heavy lifting below to
14707        // collect and record logs; currently 5 logs per 10 second period.
14708        final long now = SystemClock.elapsedRealtime();
14709        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14710            mWtfClusterStart = now;
14711            mWtfClusterCount = 1;
14712        } else {
14713            if (mWtfClusterCount++ >= 5) return;
14714        }
14715
14716        final StringBuilder sb = new StringBuilder(1024);
14717        appendDropBoxProcessHeaders(process, processName, sb);
14718        if (process != null) {
14719            sb.append("Foreground: ")
14720                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14721                    .append("\n");
14722        }
14723        if (activity != null) {
14724            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14725        }
14726        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14727            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14728        }
14729        if (parent != null && parent != activity) {
14730            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14731        }
14732        if (subject != null) {
14733            sb.append("Subject: ").append(subject).append("\n");
14734        }
14735        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14736        if (Debug.isDebuggerConnected()) {
14737            sb.append("Debugger: Connected\n");
14738        }
14739        sb.append("\n");
14740
14741        // Do the rest in a worker thread to avoid blocking the caller on I/O
14742        // (After this point, we shouldn't access AMS internal data structures.)
14743        Thread worker = new Thread("Error dump: " + dropboxTag) {
14744            @Override
14745            public void run() {
14746                if (report != null) {
14747                    sb.append(report);
14748                }
14749
14750                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14751                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14752                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14753                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14754
14755                if (dataFile != null && maxDataFileSize > 0) {
14756                    try {
14757                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14758                                    "\n\n[[TRUNCATED]]"));
14759                    } catch (IOException e) {
14760                        Slog.e(TAG, "Error reading " + dataFile, e);
14761                    }
14762                }
14763                if (crashInfo != null && crashInfo.stackTrace != null) {
14764                    sb.append(crashInfo.stackTrace);
14765                }
14766
14767                if (lines > 0) {
14768                    sb.append("\n");
14769
14770                    // Merge several logcat streams, and take the last N lines
14771                    InputStreamReader input = null;
14772                    try {
14773                        java.lang.Process logcat = new ProcessBuilder(
14774                                "/system/bin/timeout", "-k", "15s", "10s",
14775                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14776                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14777                                        .redirectErrorStream(true).start();
14778
14779                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14780                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14781                        input = new InputStreamReader(logcat.getInputStream());
14782
14783                        int num;
14784                        char[] buf = new char[8192];
14785                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14786                    } catch (IOException e) {
14787                        Slog.e(TAG, "Error running logcat", e);
14788                    } finally {
14789                        if (input != null) try { input.close(); } catch (IOException e) {}
14790                    }
14791                }
14792
14793                dbox.addText(dropboxTag, sb.toString());
14794            }
14795        };
14796
14797        if (process == null) {
14798            // If process is null, we are being called from some internal code
14799            // and may be about to die -- run this synchronously.
14800            worker.run();
14801        } else {
14802            worker.start();
14803        }
14804    }
14805
14806    @Override
14807    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14808        enforceNotIsolatedCaller("getProcessesInErrorState");
14809        // assume our apps are happy - lazy create the list
14810        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14811
14812        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14813                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14814        int userId = UserHandle.getUserId(Binder.getCallingUid());
14815
14816        synchronized (this) {
14817
14818            // iterate across all processes
14819            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14820                ProcessRecord app = mLruProcesses.get(i);
14821                if (!allUsers && app.userId != userId) {
14822                    continue;
14823                }
14824                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14825                    // This one's in trouble, so we'll generate a report for it
14826                    // crashes are higher priority (in case there's a crash *and* an anr)
14827                    ActivityManager.ProcessErrorStateInfo report = null;
14828                    if (app.crashing) {
14829                        report = app.crashingReport;
14830                    } else if (app.notResponding) {
14831                        report = app.notRespondingReport;
14832                    }
14833
14834                    if (report != null) {
14835                        if (errList == null) {
14836                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14837                        }
14838                        errList.add(report);
14839                    } else {
14840                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14841                                " crashing = " + app.crashing +
14842                                " notResponding = " + app.notResponding);
14843                    }
14844                }
14845            }
14846        }
14847
14848        return errList;
14849    }
14850
14851    static int procStateToImportance(int procState, int memAdj,
14852            ActivityManager.RunningAppProcessInfo currApp,
14853            int clientTargetSdk) {
14854        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14855                procState, clientTargetSdk);
14856        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14857            currApp.lru = memAdj;
14858        } else {
14859            currApp.lru = 0;
14860        }
14861        return imp;
14862    }
14863
14864    private void fillInProcMemInfo(ProcessRecord app,
14865            ActivityManager.RunningAppProcessInfo outInfo,
14866            int clientTargetSdk) {
14867        outInfo.pid = app.pid;
14868        outInfo.uid = app.info.uid;
14869        if (mHeavyWeightProcess == app) {
14870            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14871        }
14872        if (app.persistent) {
14873            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14874        }
14875        if (app.activities.size() > 0) {
14876            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14877        }
14878        outInfo.lastTrimLevel = app.trimMemoryLevel;
14879        int adj = app.curAdj;
14880        int procState = app.curProcState;
14881        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14882        outInfo.importanceReasonCode = app.adjTypeCode;
14883        outInfo.processState = app.curProcState;
14884    }
14885
14886    @Override
14887    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14888        enforceNotIsolatedCaller("getRunningAppProcesses");
14889
14890        final int callingUid = Binder.getCallingUid();
14891        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14892
14893        // Lazy instantiation of list
14894        List<ActivityManager.RunningAppProcessInfo> runList = null;
14895        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14896                callingUid) == PackageManager.PERMISSION_GRANTED;
14897        final int userId = UserHandle.getUserId(callingUid);
14898        final boolean allUids = isGetTasksAllowed(
14899                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14900
14901        synchronized (this) {
14902            // Iterate across all processes
14903            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14904                ProcessRecord app = mLruProcesses.get(i);
14905                if ((!allUsers && app.userId != userId)
14906                        || (!allUids && app.uid != callingUid)) {
14907                    continue;
14908                }
14909                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14910                    // Generate process state info for running application
14911                    ActivityManager.RunningAppProcessInfo currApp =
14912                        new ActivityManager.RunningAppProcessInfo(app.processName,
14913                                app.pid, app.getPackageList());
14914                    fillInProcMemInfo(app, currApp, clientTargetSdk);
14915                    if (app.adjSource instanceof ProcessRecord) {
14916                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14917                        currApp.importanceReasonImportance =
14918                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14919                                        app.adjSourceProcState);
14920                    } else if (app.adjSource instanceof ActivityRecord) {
14921                        ActivityRecord r = (ActivityRecord)app.adjSource;
14922                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14923                    }
14924                    if (app.adjTarget instanceof ComponentName) {
14925                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14926                    }
14927                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14928                    //        + " lru=" + currApp.lru);
14929                    if (runList == null) {
14930                        runList = new ArrayList<>();
14931                    }
14932                    runList.add(currApp);
14933                }
14934            }
14935        }
14936        return runList;
14937    }
14938
14939    @Override
14940    public List<ApplicationInfo> getRunningExternalApplications() {
14941        enforceNotIsolatedCaller("getRunningExternalApplications");
14942        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14943        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14944        if (runningApps != null && runningApps.size() > 0) {
14945            Set<String> extList = new HashSet<String>();
14946            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14947                if (app.pkgList != null) {
14948                    for (String pkg : app.pkgList) {
14949                        extList.add(pkg);
14950                    }
14951                }
14952            }
14953            IPackageManager pm = AppGlobals.getPackageManager();
14954            for (String pkg : extList) {
14955                try {
14956                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14957                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14958                        retList.add(info);
14959                    }
14960                } catch (RemoteException e) {
14961                }
14962            }
14963        }
14964        return retList;
14965    }
14966
14967    @Override
14968    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14969        enforceNotIsolatedCaller("getMyMemoryState");
14970
14971        final int callingUid = Binder.getCallingUid();
14972        final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14973
14974        synchronized (this) {
14975            ProcessRecord proc;
14976            synchronized (mPidsSelfLocked) {
14977                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14978            }
14979            fillInProcMemInfo(proc, outInfo, clientTargetSdk);
14980        }
14981    }
14982
14983    @Override
14984    public int getMemoryTrimLevel() {
14985        enforceNotIsolatedCaller("getMyMemoryState");
14986        synchronized (this) {
14987            return mLastMemoryLevel;
14988        }
14989    }
14990
14991    @Override
14992    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14993            FileDescriptor err, String[] args, ShellCallback callback,
14994            ResultReceiver resultReceiver) {
14995        (new ActivityManagerShellCommand(this, false)).exec(
14996                this, in, out, err, args, callback, resultReceiver);
14997    }
14998
14999    SleepToken acquireSleepToken(String tag, int displayId) {
15000        synchronized (this) {
15001            final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15002            updateSleepIfNeededLocked();
15003            return token;
15004        }
15005    }
15006
15007    @Override
15008    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15009        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15010
15011        boolean dumpAll = false;
15012        boolean dumpClient = false;
15013        boolean dumpCheckin = false;
15014        boolean dumpCheckinFormat = false;
15015        boolean dumpVisibleStacksOnly = false;
15016        boolean dumpFocusedStackOnly = false;
15017        String dumpPackage = null;
15018
15019        int opti = 0;
15020        while (opti < args.length) {
15021            String opt = args[opti];
15022            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15023                break;
15024            }
15025            opti++;
15026            if ("-a".equals(opt)) {
15027                dumpAll = true;
15028            } else if ("-c".equals(opt)) {
15029                dumpClient = true;
15030            } else if ("-v".equals(opt)) {
15031                dumpVisibleStacksOnly = true;
15032            } else if ("-f".equals(opt)) {
15033                dumpFocusedStackOnly = true;
15034            } else if ("-p".equals(opt)) {
15035                if (opti < args.length) {
15036                    dumpPackage = args[opti];
15037                    opti++;
15038                } else {
15039                    pw.println("Error: -p option requires package argument");
15040                    return;
15041                }
15042                dumpClient = true;
15043            } else if ("--checkin".equals(opt)) {
15044                dumpCheckin = dumpCheckinFormat = true;
15045            } else if ("-C".equals(opt)) {
15046                dumpCheckinFormat = true;
15047            } else if ("-h".equals(opt)) {
15048                ActivityManagerShellCommand.dumpHelp(pw, true);
15049                return;
15050            } else {
15051                pw.println("Unknown argument: " + opt + "; use -h for help");
15052            }
15053        }
15054
15055        long origId = Binder.clearCallingIdentity();
15056        boolean more = false;
15057        // Is the caller requesting to dump a particular piece of data?
15058        if (opti < args.length) {
15059            String cmd = args[opti];
15060            opti++;
15061            if ("activities".equals(cmd) || "a".equals(cmd)) {
15062                synchronized (this) {
15063                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15064                }
15065            } else if ("lastanr".equals(cmd)) {
15066                synchronized (this) {
15067                    dumpLastANRLocked(pw);
15068                }
15069            } else if ("starter".equals(cmd)) {
15070                synchronized (this) {
15071                    dumpActivityStarterLocked(pw, dumpPackage);
15072                }
15073            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15074                synchronized (this) {
15075                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15076                }
15077            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15078                String[] newArgs;
15079                String name;
15080                if (opti >= args.length) {
15081                    name = null;
15082                    newArgs = EMPTY_STRING_ARRAY;
15083                } else {
15084                    dumpPackage = args[opti];
15085                    opti++;
15086                    newArgs = new String[args.length - opti];
15087                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15088                            args.length - opti);
15089                }
15090                synchronized (this) {
15091                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15092                }
15093            } else if ("broadcast-stats".equals(cmd)) {
15094                String[] newArgs;
15095                String name;
15096                if (opti >= args.length) {
15097                    name = null;
15098                    newArgs = EMPTY_STRING_ARRAY;
15099                } else {
15100                    dumpPackage = args[opti];
15101                    opti++;
15102                    newArgs = new String[args.length - opti];
15103                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15104                            args.length - opti);
15105                }
15106                synchronized (this) {
15107                    if (dumpCheckinFormat) {
15108                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15109                                dumpPackage);
15110                    } else {
15111                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15112                    }
15113                }
15114            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15115                String[] newArgs;
15116                String name;
15117                if (opti >= args.length) {
15118                    name = null;
15119                    newArgs = EMPTY_STRING_ARRAY;
15120                } else {
15121                    dumpPackage = args[opti];
15122                    opti++;
15123                    newArgs = new String[args.length - opti];
15124                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15125                            args.length - opti);
15126                }
15127                synchronized (this) {
15128                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15129                }
15130            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15131                String[] newArgs;
15132                String name;
15133                if (opti >= args.length) {
15134                    name = null;
15135                    newArgs = EMPTY_STRING_ARRAY;
15136                } else {
15137                    dumpPackage = args[opti];
15138                    opti++;
15139                    newArgs = new String[args.length - opti];
15140                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15141                            args.length - opti);
15142                }
15143                synchronized (this) {
15144                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15145                }
15146            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15147                synchronized (this) {
15148                    dumpOomLocked(fd, pw, args, opti, true);
15149                }
15150            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15151                synchronized (this) {
15152                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
15153                }
15154            } else if ("provider".equals(cmd)) {
15155                String[] newArgs;
15156                String name;
15157                if (opti >= args.length) {
15158                    name = null;
15159                    newArgs = EMPTY_STRING_ARRAY;
15160                } else {
15161                    name = args[opti];
15162                    opti++;
15163                    newArgs = new String[args.length - opti];
15164                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15165                }
15166                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15167                    pw.println("No providers match: " + name);
15168                    pw.println("Use -h for help.");
15169                }
15170            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15171                synchronized (this) {
15172                    dumpProvidersLocked(fd, pw, args, opti, true, null);
15173                }
15174            } else if ("service".equals(cmd)) {
15175                String[] newArgs;
15176                String name;
15177                if (opti >= args.length) {
15178                    name = null;
15179                    newArgs = EMPTY_STRING_ARRAY;
15180                } else {
15181                    name = args[opti];
15182                    opti++;
15183                    newArgs = new String[args.length - opti];
15184                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15185                            args.length - opti);
15186                }
15187                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15188                    pw.println("No services match: " + name);
15189                    pw.println("Use -h for help.");
15190                }
15191            } else if ("package".equals(cmd)) {
15192                String[] newArgs;
15193                if (opti >= args.length) {
15194                    pw.println("package: no package name specified");
15195                    pw.println("Use -h for help.");
15196                } else {
15197                    dumpPackage = args[opti];
15198                    opti++;
15199                    newArgs = new String[args.length - opti];
15200                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15201                            args.length - opti);
15202                    args = newArgs;
15203                    opti = 0;
15204                    more = true;
15205                }
15206            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15207                synchronized (this) {
15208                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15209                }
15210            } else if ("settings".equals(cmd)) {
15211                synchronized (this) {
15212                    mConstants.dump(pw);
15213                }
15214            } else if ("services".equals(cmd) || "s".equals(cmd)) {
15215                if (dumpClient) {
15216                    ActiveServices.ServiceDumper dumper;
15217                    synchronized (this) {
15218                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15219                                dumpPackage);
15220                    }
15221                    dumper.dumpWithClient();
15222                } else {
15223                    synchronized (this) {
15224                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15225                                dumpPackage).dumpLocked();
15226                    }
15227                }
15228            } else if ("locks".equals(cmd)) {
15229                LockGuard.dump(fd, pw, args);
15230            } else {
15231                // Dumping a single activity?
15232                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15233                        dumpFocusedStackOnly)) {
15234                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15235                    int res = shell.exec(this, null, fd, null, args, null,
15236                            new ResultReceiver(null));
15237                    if (res < 0) {
15238                        pw.println("Bad activity command, or no activities match: " + cmd);
15239                        pw.println("Use -h for help.");
15240                    }
15241                }
15242            }
15243            if (!more) {
15244                Binder.restoreCallingIdentity(origId);
15245                return;
15246            }
15247        }
15248
15249        // No piece of data specified, dump everything.
15250        if (dumpCheckinFormat) {
15251            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15252        } else if (dumpClient) {
15253            ActiveServices.ServiceDumper sdumper;
15254            synchronized (this) {
15255                mConstants.dump(pw);
15256                pw.println();
15257                if (dumpAll) {
15258                    pw.println("-------------------------------------------------------------------------------");
15259                }
15260                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15261                pw.println();
15262                if (dumpAll) {
15263                    pw.println("-------------------------------------------------------------------------------");
15264                }
15265                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15266                pw.println();
15267                if (dumpAll) {
15268                    pw.println("-------------------------------------------------------------------------------");
15269                }
15270                if (dumpAll || dumpPackage != null) {
15271                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15272                    pw.println();
15273                    if (dumpAll) {
15274                        pw.println("-------------------------------------------------------------------------------");
15275                    }
15276                }
15277                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15278                pw.println();
15279                if (dumpAll) {
15280                    pw.println("-------------------------------------------------------------------------------");
15281                }
15282                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15283                pw.println();
15284                if (dumpAll) {
15285                    pw.println("-------------------------------------------------------------------------------");
15286                }
15287                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15288                        dumpPackage);
15289            }
15290            sdumper.dumpWithClient();
15291            pw.println();
15292            synchronized (this) {
15293                if (dumpAll) {
15294                    pw.println("-------------------------------------------------------------------------------");
15295                }
15296                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15297                pw.println();
15298                if (dumpAll) {
15299                    pw.println("-------------------------------------------------------------------------------");
15300                }
15301                dumpLastANRLocked(pw);
15302                pw.println();
15303                if (dumpAll) {
15304                    pw.println("-------------------------------------------------------------------------------");
15305                }
15306                dumpActivityStarterLocked(pw, dumpPackage);
15307                pw.println();
15308                if (dumpAll) {
15309                    pw.println("-------------------------------------------------------------------------------");
15310                }
15311                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15312                if (mAssociations.size() > 0) {
15313                    pw.println();
15314                    if (dumpAll) {
15315                        pw.println("-------------------------------------------------------------------------------");
15316                    }
15317                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15318                }
15319                pw.println();
15320                if (dumpAll) {
15321                    pw.println("-------------------------------------------------------------------------------");
15322                }
15323                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15324            }
15325
15326        } else {
15327            synchronized (this) {
15328                mConstants.dump(pw);
15329                pw.println();
15330                if (dumpAll) {
15331                    pw.println("-------------------------------------------------------------------------------");
15332                }
15333                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15334                pw.println();
15335                if (dumpAll) {
15336                    pw.println("-------------------------------------------------------------------------------");
15337                }
15338                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15339                pw.println();
15340                if (dumpAll) {
15341                    pw.println("-------------------------------------------------------------------------------");
15342                }
15343                if (dumpAll || dumpPackage != null) {
15344                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15345                    pw.println();
15346                    if (dumpAll) {
15347                        pw.println("-------------------------------------------------------------------------------");
15348                    }
15349                }
15350                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15351                pw.println();
15352                if (dumpAll) {
15353                    pw.println("-------------------------------------------------------------------------------");
15354                }
15355                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15356                pw.println();
15357                if (dumpAll) {
15358                    pw.println("-------------------------------------------------------------------------------");
15359                }
15360                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15361                        .dumpLocked();
15362                pw.println();
15363                if (dumpAll) {
15364                    pw.println("-------------------------------------------------------------------------------");
15365                }
15366                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15367                pw.println();
15368                if (dumpAll) {
15369                    pw.println("-------------------------------------------------------------------------------");
15370                }
15371                dumpLastANRLocked(pw);
15372                pw.println();
15373                if (dumpAll) {
15374                    pw.println("-------------------------------------------------------------------------------");
15375                }
15376                dumpActivityStarterLocked(pw, dumpPackage);
15377                pw.println();
15378                if (dumpAll) {
15379                    pw.println("-------------------------------------------------------------------------------");
15380                }
15381                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15382                if (mAssociations.size() > 0) {
15383                    pw.println();
15384                    if (dumpAll) {
15385                        pw.println("-------------------------------------------------------------------------------");
15386                    }
15387                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15388                }
15389                pw.println();
15390                if (dumpAll) {
15391                    pw.println("-------------------------------------------------------------------------------");
15392                }
15393                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15394            }
15395        }
15396        Binder.restoreCallingIdentity(origId);
15397    }
15398
15399    private void dumpLastANRLocked(PrintWriter pw) {
15400        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15401        if (mLastANRState == null) {
15402            pw.println("  <no ANR has occurred since boot>");
15403        } else {
15404            pw.println(mLastANRState);
15405        }
15406    }
15407
15408    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15409        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15410        mActivityStarter.dump(pw, "", dumpPackage);
15411    }
15412
15413    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15414            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15415        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15416                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15417    }
15418
15419    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15420            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15421        pw.println(header);
15422
15423        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15424                dumpPackage);
15425        boolean needSep = printedAnything;
15426
15427        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15428                mStackSupervisor.getResumedActivityLocked(),
15429                dumpPackage, needSep, "  ResumedActivity: ");
15430        if (printed) {
15431            printedAnything = true;
15432            needSep = false;
15433        }
15434
15435        if (dumpPackage == null) {
15436            if (needSep) {
15437                pw.println();
15438            }
15439            printedAnything = true;
15440            mStackSupervisor.dump(pw, "  ");
15441        }
15442
15443        if (!printedAnything) {
15444            pw.println("  (nothing)");
15445        }
15446    }
15447
15448    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15449            int opti, boolean dumpAll, String dumpPackage) {
15450        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15451
15452        boolean printedAnything = false;
15453
15454        if (mRecentTasks != null && mRecentTasks.size() > 0) {
15455            boolean printedHeader = false;
15456
15457            final int N = mRecentTasks.size();
15458            for (int i=0; i<N; i++) {
15459                TaskRecord tr = mRecentTasks.get(i);
15460                if (dumpPackage != null) {
15461                    if (tr.realActivity == null ||
15462                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
15463                        continue;
15464                    }
15465                }
15466                if (!printedHeader) {
15467                    pw.println("  Recent tasks:");
15468                    printedHeader = true;
15469                    printedAnything = true;
15470                }
15471                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15472                        pw.println(tr);
15473                if (dumpAll) {
15474                    mRecentTasks.get(i).dump(pw, "    ");
15475                }
15476            }
15477        }
15478
15479        if (!printedAnything) {
15480            pw.println("  (nothing)");
15481        }
15482    }
15483
15484    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15485            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15486        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15487
15488        int dumpUid = 0;
15489        if (dumpPackage != null) {
15490            IPackageManager pm = AppGlobals.getPackageManager();
15491            try {
15492                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15493            } catch (RemoteException e) {
15494            }
15495        }
15496
15497        boolean printedAnything = false;
15498
15499        final long now = SystemClock.uptimeMillis();
15500
15501        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15502            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15503                    = mAssociations.valueAt(i1);
15504            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15505                SparseArray<ArrayMap<String, Association>> sourceUids
15506                        = targetComponents.valueAt(i2);
15507                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15508                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15509                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15510                        Association ass = sourceProcesses.valueAt(i4);
15511                        if (dumpPackage != null) {
15512                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15513                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15514                                continue;
15515                            }
15516                        }
15517                        printedAnything = true;
15518                        pw.print("  ");
15519                        pw.print(ass.mTargetProcess);
15520                        pw.print("/");
15521                        UserHandle.formatUid(pw, ass.mTargetUid);
15522                        pw.print(" <- ");
15523                        pw.print(ass.mSourceProcess);
15524                        pw.print("/");
15525                        UserHandle.formatUid(pw, ass.mSourceUid);
15526                        pw.println();
15527                        pw.print("    via ");
15528                        pw.print(ass.mTargetComponent.flattenToShortString());
15529                        pw.println();
15530                        pw.print("    ");
15531                        long dur = ass.mTime;
15532                        if (ass.mNesting > 0) {
15533                            dur += now - ass.mStartTime;
15534                        }
15535                        TimeUtils.formatDuration(dur, pw);
15536                        pw.print(" (");
15537                        pw.print(ass.mCount);
15538                        pw.print(" times)");
15539                        pw.print("  ");
15540                        for (int i=0; i<ass.mStateTimes.length; i++) {
15541                            long amt = ass.mStateTimes[i];
15542                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15543                                amt += now - ass.mLastStateUptime;
15544                            }
15545                            if (amt != 0) {
15546                                pw.print(" ");
15547                                pw.print(ProcessList.makeProcStateString(
15548                                            i + ActivityManager.MIN_PROCESS_STATE));
15549                                pw.print("=");
15550                                TimeUtils.formatDuration(amt, pw);
15551                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15552                                    pw.print("*");
15553                                }
15554                            }
15555                        }
15556                        pw.println();
15557                        if (ass.mNesting > 0) {
15558                            pw.print("    Currently active: ");
15559                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15560                            pw.println();
15561                        }
15562                    }
15563                }
15564            }
15565
15566        }
15567
15568        if (!printedAnything) {
15569            pw.println("  (nothing)");
15570        }
15571    }
15572
15573    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15574            String header, boolean needSep) {
15575        boolean printed = false;
15576        int whichAppId = -1;
15577        if (dumpPackage != null) {
15578            try {
15579                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15580                        dumpPackage, 0);
15581                whichAppId = UserHandle.getAppId(info.uid);
15582            } catch (NameNotFoundException e) {
15583                e.printStackTrace();
15584            }
15585        }
15586        for (int i=0; i<uids.size(); i++) {
15587            UidRecord uidRec = uids.valueAt(i);
15588            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15589                continue;
15590            }
15591            if (!printed) {
15592                printed = true;
15593                if (needSep) {
15594                    pw.println();
15595                }
15596                pw.print("  ");
15597                pw.println(header);
15598                needSep = true;
15599            }
15600            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15601            pw.print(": "); pw.println(uidRec);
15602        }
15603        return printed;
15604    }
15605
15606    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15607            int opti, boolean dumpAll, String dumpPackage) {
15608        boolean needSep = false;
15609        boolean printedAnything = false;
15610        int numPers = 0;
15611
15612        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15613
15614        if (dumpAll) {
15615            final int NP = mProcessNames.getMap().size();
15616            for (int ip=0; ip<NP; ip++) {
15617                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15618                final int NA = procs.size();
15619                for (int ia=0; ia<NA; ia++) {
15620                    ProcessRecord r = procs.valueAt(ia);
15621                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15622                        continue;
15623                    }
15624                    if (!needSep) {
15625                        pw.println("  All known processes:");
15626                        needSep = true;
15627                        printedAnything = true;
15628                    }
15629                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15630                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15631                        pw.print(" "); pw.println(r);
15632                    r.dump(pw, "    ");
15633                    if (r.persistent) {
15634                        numPers++;
15635                    }
15636                }
15637            }
15638        }
15639
15640        if (mIsolatedProcesses.size() > 0) {
15641            boolean printed = false;
15642            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15643                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15644                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15645                    continue;
15646                }
15647                if (!printed) {
15648                    if (needSep) {
15649                        pw.println();
15650                    }
15651                    pw.println("  Isolated process list (sorted by uid):");
15652                    printedAnything = true;
15653                    printed = true;
15654                    needSep = true;
15655                }
15656                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15657                pw.println(r);
15658            }
15659        }
15660
15661        if (mActiveInstrumentation.size() > 0) {
15662            boolean printed = false;
15663            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15664                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15665                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15666                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15667                    continue;
15668                }
15669                if (!printed) {
15670                    if (needSep) {
15671                        pw.println();
15672                    }
15673                    pw.println("  Active instrumentation:");
15674                    printedAnything = true;
15675                    printed = true;
15676                    needSep = true;
15677                }
15678                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15679                pw.println(ai);
15680                ai.dump(pw, "      ");
15681            }
15682        }
15683
15684        if (mActiveUids.size() > 0) {
15685            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15686                printedAnything = needSep = true;
15687            }
15688        }
15689        if (dumpAll) {
15690            if (mValidateUids.size() > 0) {
15691                if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15692                    printedAnything = needSep = true;
15693                }
15694            }
15695        }
15696
15697        if (mLruProcesses.size() > 0) {
15698            if (needSep) {
15699                pw.println();
15700            }
15701            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15702                    pw.print(" total, non-act at ");
15703                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15704                    pw.print(", non-svc at ");
15705                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15706                    pw.println("):");
15707            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15708            needSep = true;
15709            printedAnything = true;
15710        }
15711
15712        if (dumpAll || dumpPackage != null) {
15713            synchronized (mPidsSelfLocked) {
15714                boolean printed = false;
15715                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15716                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15717                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15718                        continue;
15719                    }
15720                    if (!printed) {
15721                        if (needSep) pw.println();
15722                        needSep = true;
15723                        pw.println("  PID mappings:");
15724                        printed = true;
15725                        printedAnything = true;
15726                    }
15727                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15728                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15729                }
15730            }
15731        }
15732
15733        if (mImportantProcesses.size() > 0) {
15734            synchronized (mPidsSelfLocked) {
15735                boolean printed = false;
15736                for (int i = 0; i< mImportantProcesses.size(); i++) {
15737                    ProcessRecord r = mPidsSelfLocked.get(
15738                            mImportantProcesses.valueAt(i).pid);
15739                    if (dumpPackage != null && (r == null
15740                            || !r.pkgList.containsKey(dumpPackage))) {
15741                        continue;
15742                    }
15743                    if (!printed) {
15744                        if (needSep) pw.println();
15745                        needSep = true;
15746                        pw.println("  Foreground Processes:");
15747                        printed = true;
15748                        printedAnything = true;
15749                    }
15750                    pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15751                            pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15752                }
15753            }
15754        }
15755
15756        if (mPersistentStartingProcesses.size() > 0) {
15757            if (needSep) pw.println();
15758            needSep = true;
15759            printedAnything = true;
15760            pw.println("  Persisent processes that are starting:");
15761            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15762                    "Starting Norm", "Restarting PERS", dumpPackage);
15763        }
15764
15765        if (mRemovedProcesses.size() > 0) {
15766            if (needSep) pw.println();
15767            needSep = true;
15768            printedAnything = true;
15769            pw.println("  Processes that are being removed:");
15770            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15771                    "Removed Norm", "Removed PERS", dumpPackage);
15772        }
15773
15774        if (mProcessesOnHold.size() > 0) {
15775            if (needSep) pw.println();
15776            needSep = true;
15777            printedAnything = true;
15778            pw.println("  Processes that are on old until the system is ready:");
15779            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15780                    "OnHold Norm", "OnHold PERS", dumpPackage);
15781        }
15782
15783        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15784
15785        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15786        if (needSep) {
15787            printedAnything = true;
15788        }
15789
15790        if (dumpPackage == null) {
15791            pw.println();
15792            needSep = false;
15793            mUserController.dump(pw, dumpAll);
15794        }
15795        if (mHomeProcess != null && (dumpPackage == null
15796                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15797            if (needSep) {
15798                pw.println();
15799                needSep = false;
15800            }
15801            pw.println("  mHomeProcess: " + mHomeProcess);
15802        }
15803        if (mPreviousProcess != null && (dumpPackage == null
15804                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15805            if (needSep) {
15806                pw.println();
15807                needSep = false;
15808            }
15809            pw.println("  mPreviousProcess: " + mPreviousProcess);
15810        }
15811        if (dumpAll) {
15812            StringBuilder sb = new StringBuilder(128);
15813            sb.append("  mPreviousProcessVisibleTime: ");
15814            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15815            pw.println(sb);
15816        }
15817        if (mHeavyWeightProcess != null && (dumpPackage == null
15818                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15819            if (needSep) {
15820                pw.println();
15821                needSep = false;
15822            }
15823            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15824        }
15825        if (dumpPackage == null) {
15826            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15827            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15828        }
15829        if (dumpAll) {
15830            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15831            if (mCompatModePackages.getPackages().size() > 0) {
15832                boolean printed = false;
15833                for (Map.Entry<String, Integer> entry
15834                        : mCompatModePackages.getPackages().entrySet()) {
15835                    String pkg = entry.getKey();
15836                    int mode = entry.getValue();
15837                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15838                        continue;
15839                    }
15840                    if (!printed) {
15841                        pw.println("  mScreenCompatPackages:");
15842                        printed = true;
15843                    }
15844                    pw.print("    "); pw.print(pkg); pw.print(": ");
15845                            pw.print(mode); pw.println();
15846                }
15847            }
15848            final int NI = mUidObservers.getRegisteredCallbackCount();
15849            boolean printed = false;
15850            for (int i=0; i<NI; i++) {
15851                final UidObserverRegistration reg = (UidObserverRegistration)
15852                        mUidObservers.getRegisteredCallbackCookie(i);
15853                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15854                    if (!printed) {
15855                        pw.println("  mUidObservers:");
15856                        printed = true;
15857                    }
15858                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15859                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15860                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15861                        pw.print(" IDLE");
15862                    }
15863                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15864                        pw.print(" ACT" );
15865                    }
15866                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15867                        pw.print(" GONE");
15868                    }
15869                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15870                        pw.print(" STATE");
15871                        pw.print(" (cut="); pw.print(reg.cutpoint);
15872                        pw.print(")");
15873                    }
15874                    pw.println();
15875                    if (reg.lastProcStates != null) {
15876                        final int NJ = reg.lastProcStates.size();
15877                        for (int j=0; j<NJ; j++) {
15878                            pw.print("      Last ");
15879                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15880                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15881                        }
15882                    }
15883                }
15884            }
15885            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15886            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15887            if (mPendingTempWhitelist.size() > 0) {
15888                pw.println("  mPendingTempWhitelist:");
15889                for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15890                    PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15891                    pw.print("    ");
15892                    UserHandle.formatUid(pw, ptw.targetUid);
15893                    pw.print(": ");
15894                    TimeUtils.formatDuration(ptw.duration, pw);
15895                    pw.print(" ");
15896                    pw.println(ptw.tag);
15897                }
15898            }
15899        }
15900        if (dumpPackage == null) {
15901            pw.println("  mWakefulness="
15902                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15903            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
15904            pw.println("  mSleeping=" + mSleeping);
15905            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15906            if (mRunningVoice != null) {
15907                pw.println("  mRunningVoice=" + mRunningVoice);
15908                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15909            }
15910        }
15911        pw.println("  mVrController=" + mVrController);
15912        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15913                || mOrigWaitForDebugger) {
15914            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15915                    || dumpPackage.equals(mOrigDebugApp)) {
15916                if (needSep) {
15917                    pw.println();
15918                    needSep = false;
15919                }
15920                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15921                        + " mDebugTransient=" + mDebugTransient
15922                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15923            }
15924        }
15925        if (mCurAppTimeTracker != null) {
15926            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15927        }
15928        if (mMemWatchProcesses.getMap().size() > 0) {
15929            pw.println("  Mem watch processes:");
15930            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15931                    = mMemWatchProcesses.getMap();
15932            for (int i=0; i<procs.size(); i++) {
15933                final String proc = procs.keyAt(i);
15934                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15935                for (int j=0; j<uids.size(); j++) {
15936                    if (needSep) {
15937                        pw.println();
15938                        needSep = false;
15939                    }
15940                    StringBuilder sb = new StringBuilder();
15941                    sb.append("    ").append(proc).append('/');
15942                    UserHandle.formatUid(sb, uids.keyAt(j));
15943                    Pair<Long, String> val = uids.valueAt(j);
15944                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15945                    if (val.second != null) {
15946                        sb.append(", report to ").append(val.second);
15947                    }
15948                    pw.println(sb.toString());
15949                }
15950            }
15951            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15952            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15953            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15954                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15955        }
15956        if (mTrackAllocationApp != null) {
15957            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15958                if (needSep) {
15959                    pw.println();
15960                    needSep = false;
15961                }
15962                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15963            }
15964        }
15965        if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
15966                (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
15967            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15968                if (needSep) {
15969                    pw.println();
15970                    needSep = false;
15971                }
15972                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15973                if (mProfilerInfo != null) {
15974                    pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
15975                            mProfilerInfo.profileFd);
15976                    pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
15977                            " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
15978                            " mStreamingOutput=" + mProfilerInfo.streamingOutput);
15979                    pw.println("  mProfileType=" + mProfileType);
15980                }
15981            }
15982        }
15983        if (mNativeDebuggingApp != null) {
15984            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15985                if (needSep) {
15986                    pw.println();
15987                    needSep = false;
15988                }
15989                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15990            }
15991        }
15992        if (dumpPackage == null) {
15993            if (mAlwaysFinishActivities) {
15994                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15995            }
15996            if (mController != null) {
15997                pw.println("  mController=" + mController
15998                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15999            }
16000            if (dumpAll) {
16001                pw.println("  Total persistent processes: " + numPers);
16002                pw.println("  mProcessesReady=" + mProcessesReady
16003                        + " mSystemReady=" + mSystemReady
16004                        + " mBooted=" + mBooted
16005                        + " mFactoryTest=" + mFactoryTest);
16006                pw.println("  mBooting=" + mBooting
16007                        + " mCallFinishBooting=" + mCallFinishBooting
16008                        + " mBootAnimationComplete=" + mBootAnimationComplete);
16009                pw.print("  mLastPowerCheckUptime=");
16010                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16011                        pw.println("");
16012                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16013                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16014                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16015                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16016                        + " (" + mLruProcesses.size() + " total)"
16017                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16018                        + " mNumServiceProcs=" + mNumServiceProcs
16019                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16020                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16021                        + " mLastMemoryLevel=" + mLastMemoryLevel
16022                        + " mLastNumProcesses=" + mLastNumProcesses);
16023                long now = SystemClock.uptimeMillis();
16024                pw.print("  mLastIdleTime=");
16025                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
16026                        pw.print(" mLowRamSinceLastIdle=");
16027                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16028                        pw.println();
16029            }
16030        }
16031
16032        if (!printedAnything) {
16033            pw.println("  (nothing)");
16034        }
16035    }
16036
16037    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16038            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16039        if (mProcessesToGc.size() > 0) {
16040            boolean printed = false;
16041            long now = SystemClock.uptimeMillis();
16042            for (int i=0; i<mProcessesToGc.size(); i++) {
16043                ProcessRecord proc = mProcessesToGc.get(i);
16044                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16045                    continue;
16046                }
16047                if (!printed) {
16048                    if (needSep) pw.println();
16049                    needSep = true;
16050                    pw.println("  Processes that are waiting to GC:");
16051                    printed = true;
16052                }
16053                pw.print("    Process "); pw.println(proc);
16054                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16055                        pw.print(", last gced=");
16056                        pw.print(now-proc.lastRequestedGc);
16057                        pw.print(" ms ago, last lowMem=");
16058                        pw.print(now-proc.lastLowMemory);
16059                        pw.println(" ms ago");
16060
16061            }
16062        }
16063        return needSep;
16064    }
16065
16066    void printOomLevel(PrintWriter pw, String name, int adj) {
16067        pw.print("    ");
16068        if (adj >= 0) {
16069            pw.print(' ');
16070            if (adj < 10) pw.print(' ');
16071        } else {
16072            if (adj > -10) pw.print(' ');
16073        }
16074        pw.print(adj);
16075        pw.print(": ");
16076        pw.print(name);
16077        pw.print(" (");
16078        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16079        pw.println(")");
16080    }
16081
16082    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16083            int opti, boolean dumpAll) {
16084        boolean needSep = false;
16085
16086        if (mLruProcesses.size() > 0) {
16087            if (needSep) pw.println();
16088            needSep = true;
16089            pw.println("  OOM levels:");
16090            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16091            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16092            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16093            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16094            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16095            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16096            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16097            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16098            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16099            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16100            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16101            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16102            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16103            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16104
16105            if (needSep) pw.println();
16106            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16107                    pw.print(" total, non-act at ");
16108                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16109                    pw.print(", non-svc at ");
16110                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16111                    pw.println("):");
16112            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16113            needSep = true;
16114        }
16115
16116        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16117
16118        pw.println();
16119        pw.println("  mHomeProcess: " + mHomeProcess);
16120        pw.println("  mPreviousProcess: " + mPreviousProcess);
16121        if (mHeavyWeightProcess != null) {
16122            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16123        }
16124
16125        return true;
16126    }
16127
16128    /**
16129     * There are three ways to call this:
16130     *  - no provider specified: dump all the providers
16131     *  - a flattened component name that matched an existing provider was specified as the
16132     *    first arg: dump that one provider
16133     *  - the first arg isn't the flattened component name of an existing provider:
16134     *    dump all providers whose component contains the first arg as a substring
16135     */
16136    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16137            int opti, boolean dumpAll) {
16138        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16139    }
16140
16141    static class ItemMatcher {
16142        ArrayList<ComponentName> components;
16143        ArrayList<String> strings;
16144        ArrayList<Integer> objects;
16145        boolean all;
16146
16147        ItemMatcher() {
16148            all = true;
16149        }
16150
16151        void build(String name) {
16152            ComponentName componentName = ComponentName.unflattenFromString(name);
16153            if (componentName != null) {
16154                if (components == null) {
16155                    components = new ArrayList<ComponentName>();
16156                }
16157                components.add(componentName);
16158                all = false;
16159            } else {
16160                int objectId = 0;
16161                // Not a '/' separated full component name; maybe an object ID?
16162                try {
16163                    objectId = Integer.parseInt(name, 16);
16164                    if (objects == null) {
16165                        objects = new ArrayList<Integer>();
16166                    }
16167                    objects.add(objectId);
16168                    all = false;
16169                } catch (RuntimeException e) {
16170                    // Not an integer; just do string match.
16171                    if (strings == null) {
16172                        strings = new ArrayList<String>();
16173                    }
16174                    strings.add(name);
16175                    all = false;
16176                }
16177            }
16178        }
16179
16180        int build(String[] args, int opti) {
16181            for (; opti<args.length; opti++) {
16182                String name = args[opti];
16183                if ("--".equals(name)) {
16184                    return opti+1;
16185                }
16186                build(name);
16187            }
16188            return opti;
16189        }
16190
16191        boolean match(Object object, ComponentName comp) {
16192            if (all) {
16193                return true;
16194            }
16195            if (components != null) {
16196                for (int i=0; i<components.size(); i++) {
16197                    if (components.get(i).equals(comp)) {
16198                        return true;
16199                    }
16200                }
16201            }
16202            if (objects != null) {
16203                for (int i=0; i<objects.size(); i++) {
16204                    if (System.identityHashCode(object) == objects.get(i)) {
16205                        return true;
16206                    }
16207                }
16208            }
16209            if (strings != null) {
16210                String flat = comp.flattenToString();
16211                for (int i=0; i<strings.size(); i++) {
16212                    if (flat.contains(strings.get(i))) {
16213                        return true;
16214                    }
16215                }
16216            }
16217            return false;
16218        }
16219    }
16220
16221    /**
16222     * There are three things that cmd can be:
16223     *  - a flattened component name that matches an existing activity
16224     *  - the cmd arg isn't the flattened component name of an existing activity:
16225     *    dump all activity whose component contains the cmd as a substring
16226     *  - A hex number of the ActivityRecord object instance.
16227     *
16228     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16229     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16230     */
16231    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16232            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16233        ArrayList<ActivityRecord> activities;
16234
16235        synchronized (this) {
16236            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16237                    dumpFocusedStackOnly);
16238        }
16239
16240        if (activities.size() <= 0) {
16241            return false;
16242        }
16243
16244        String[] newArgs = new String[args.length - opti];
16245        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16246
16247        TaskRecord lastTask = null;
16248        boolean needSep = false;
16249        for (int i=activities.size()-1; i>=0; i--) {
16250            ActivityRecord r = activities.get(i);
16251            if (needSep) {
16252                pw.println();
16253            }
16254            needSep = true;
16255            synchronized (this) {
16256                final TaskRecord task = r.getTask();
16257                if (lastTask != task) {
16258                    lastTask = task;
16259                    pw.print("TASK "); pw.print(lastTask.affinity);
16260                            pw.print(" id="); pw.print(lastTask.taskId);
16261                            pw.print(" userId="); pw.println(lastTask.userId);
16262                    if (dumpAll) {
16263                        lastTask.dump(pw, "  ");
16264                    }
16265                }
16266            }
16267            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16268        }
16269        return true;
16270    }
16271
16272    /**
16273     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16274     * there is a thread associated with the activity.
16275     */
16276    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16277            final ActivityRecord r, String[] args, boolean dumpAll) {
16278        String innerPrefix = prefix + "  ";
16279        synchronized (this) {
16280            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16281                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16282                    pw.print(" pid=");
16283                    if (r.app != null) pw.println(r.app.pid);
16284                    else pw.println("(not running)");
16285            if (dumpAll) {
16286                r.dump(pw, innerPrefix);
16287            }
16288        }
16289        if (r.app != null && r.app.thread != null) {
16290            // flush anything that is already in the PrintWriter since the thread is going
16291            // to write to the file descriptor directly
16292            pw.flush();
16293            try {
16294                TransferPipe tp = new TransferPipe();
16295                try {
16296                    r.app.thread.dumpActivity(tp.getWriteFd(),
16297                            r.appToken, innerPrefix, args);
16298                    tp.go(fd);
16299                } finally {
16300                    tp.kill();
16301                }
16302            } catch (IOException e) {
16303                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16304            } catch (RemoteException e) {
16305                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16306            }
16307        }
16308    }
16309
16310    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16311            int opti, boolean dumpAll, String dumpPackage) {
16312        boolean needSep = false;
16313        boolean onlyHistory = false;
16314        boolean printedAnything = false;
16315
16316        if ("history".equals(dumpPackage)) {
16317            if (opti < args.length && "-s".equals(args[opti])) {
16318                dumpAll = false;
16319            }
16320            onlyHistory = true;
16321            dumpPackage = null;
16322        }
16323
16324        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16325        if (!onlyHistory && dumpAll) {
16326            if (mRegisteredReceivers.size() > 0) {
16327                boolean printed = false;
16328                Iterator it = mRegisteredReceivers.values().iterator();
16329                while (it.hasNext()) {
16330                    ReceiverList r = (ReceiverList)it.next();
16331                    if (dumpPackage != null && (r.app == null ||
16332                            !dumpPackage.equals(r.app.info.packageName))) {
16333                        continue;
16334                    }
16335                    if (!printed) {
16336                        pw.println("  Registered Receivers:");
16337                        needSep = true;
16338                        printed = true;
16339                        printedAnything = true;
16340                    }
16341                    pw.print("  * "); pw.println(r);
16342                    r.dump(pw, "    ");
16343                }
16344            }
16345
16346            if (mReceiverResolver.dump(pw, needSep ?
16347                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16348                    "    ", dumpPackage, false, false)) {
16349                needSep = true;
16350                printedAnything = true;
16351            }
16352        }
16353
16354        for (BroadcastQueue q : mBroadcastQueues) {
16355            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16356            printedAnything |= needSep;
16357        }
16358
16359        needSep = true;
16360
16361        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16362            for (int user=0; user<mStickyBroadcasts.size(); user++) {
16363                if (needSep) {
16364                    pw.println();
16365                }
16366                needSep = true;
16367                printedAnything = true;
16368                pw.print("  Sticky broadcasts for user ");
16369                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16370                StringBuilder sb = new StringBuilder(128);
16371                for (Map.Entry<String, ArrayList<Intent>> ent
16372                        : mStickyBroadcasts.valueAt(user).entrySet()) {
16373                    pw.print("  * Sticky action "); pw.print(ent.getKey());
16374                    if (dumpAll) {
16375                        pw.println(":");
16376                        ArrayList<Intent> intents = ent.getValue();
16377                        final int N = intents.size();
16378                        for (int i=0; i<N; i++) {
16379                            sb.setLength(0);
16380                            sb.append("    Intent: ");
16381                            intents.get(i).toShortString(sb, false, true, false, false);
16382                            pw.println(sb.toString());
16383                            Bundle bundle = intents.get(i).getExtras();
16384                            if (bundle != null) {
16385                                pw.print("      ");
16386                                pw.println(bundle.toString());
16387                            }
16388                        }
16389                    } else {
16390                        pw.println("");
16391                    }
16392                }
16393            }
16394        }
16395
16396        if (!onlyHistory && dumpAll) {
16397            pw.println();
16398            for (BroadcastQueue queue : mBroadcastQueues) {
16399                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16400                        + queue.mBroadcastsScheduled);
16401            }
16402            pw.println("  mHandler:");
16403            mHandler.dump(new PrintWriterPrinter(pw), "    ");
16404            needSep = true;
16405            printedAnything = true;
16406        }
16407
16408        if (!printedAnything) {
16409            pw.println("  (nothing)");
16410        }
16411    }
16412
16413    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16414            int opti, boolean dumpAll, String dumpPackage) {
16415        if (mCurBroadcastStats == null) {
16416            return;
16417        }
16418
16419        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16420        final long now = SystemClock.elapsedRealtime();
16421        if (mLastBroadcastStats != null) {
16422            pw.print("  Last stats (from ");
16423            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16424            pw.print(" to ");
16425            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16426            pw.print(", ");
16427            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16428                    - mLastBroadcastStats.mStartUptime, pw);
16429            pw.println(" uptime):");
16430            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16431                pw.println("    (nothing)");
16432            }
16433            pw.println();
16434        }
16435        pw.print("  Current stats (from ");
16436        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16437        pw.print(" to now, ");
16438        TimeUtils.formatDuration(SystemClock.uptimeMillis()
16439                - mCurBroadcastStats.mStartUptime, pw);
16440        pw.println(" uptime):");
16441        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16442            pw.println("    (nothing)");
16443        }
16444    }
16445
16446    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16447            int opti, boolean fullCheckin, String dumpPackage) {
16448        if (mCurBroadcastStats == null) {
16449            return;
16450        }
16451
16452        if (mLastBroadcastStats != null) {
16453            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16454            if (fullCheckin) {
16455                mLastBroadcastStats = null;
16456                return;
16457            }
16458        }
16459        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16460        if (fullCheckin) {
16461            mCurBroadcastStats = null;
16462        }
16463    }
16464
16465    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16466            int opti, boolean dumpAll, String dumpPackage) {
16467        boolean needSep;
16468        boolean printedAnything = false;
16469
16470        ItemMatcher matcher = new ItemMatcher();
16471        matcher.build(args, opti);
16472
16473        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16474
16475        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16476        printedAnything |= needSep;
16477
16478        if (mLaunchingProviders.size() > 0) {
16479            boolean printed = false;
16480            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16481                ContentProviderRecord r = mLaunchingProviders.get(i);
16482                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16483                    continue;
16484                }
16485                if (!printed) {
16486                    if (needSep) pw.println();
16487                    needSep = true;
16488                    pw.println("  Launching content providers:");
16489                    printed = true;
16490                    printedAnything = true;
16491                }
16492                pw.print("  Launching #"); pw.print(i); pw.print(": ");
16493                        pw.println(r);
16494            }
16495        }
16496
16497        if (!printedAnything) {
16498            pw.println("  (nothing)");
16499        }
16500    }
16501
16502    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16503            int opti, boolean dumpAll, String dumpPackage) {
16504        boolean needSep = false;
16505        boolean printedAnything = false;
16506
16507        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16508
16509        if (mGrantedUriPermissions.size() > 0) {
16510            boolean printed = false;
16511            int dumpUid = -2;
16512            if (dumpPackage != null) {
16513                try {
16514                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16515                            MATCH_ANY_USER, 0);
16516                } catch (NameNotFoundException e) {
16517                    dumpUid = -1;
16518                }
16519            }
16520            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16521                int uid = mGrantedUriPermissions.keyAt(i);
16522                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16523                    continue;
16524                }
16525                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16526                if (!printed) {
16527                    if (needSep) pw.println();
16528                    needSep = true;
16529                    pw.println("  Granted Uri Permissions:");
16530                    printed = true;
16531                    printedAnything = true;
16532                }
16533                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16534                for (UriPermission perm : perms.values()) {
16535                    pw.print("    "); pw.println(perm);
16536                    if (dumpAll) {
16537                        perm.dump(pw, "      ");
16538                    }
16539                }
16540            }
16541        }
16542
16543        if (!printedAnything) {
16544            pw.println("  (nothing)");
16545        }
16546    }
16547
16548    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16549            int opti, boolean dumpAll, String dumpPackage) {
16550        boolean printed = false;
16551
16552        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16553
16554        if (mIntentSenderRecords.size() > 0) {
16555            // Organize these by package name, so they are easier to read.
16556            final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16557            final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16558            final Iterator<WeakReference<PendingIntentRecord>> it
16559                    = mIntentSenderRecords.values().iterator();
16560            while (it.hasNext()) {
16561                WeakReference<PendingIntentRecord> ref = it.next();
16562                PendingIntentRecord rec = ref != null ? ref.get() : null;
16563                if (rec == null) {
16564                    weakRefs.add(ref);
16565                    continue;
16566                }
16567                if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16568                    continue;
16569                }
16570                ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16571                if (list == null) {
16572                    list = new ArrayList<>();
16573                    byPackage.put(rec.key.packageName, list);
16574                }
16575                list.add(rec);
16576            }
16577            for (int i = 0; i < byPackage.size(); i++) {
16578                ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16579                printed = true;
16580                pw.print("  * "); pw.print(byPackage.keyAt(i));
16581                pw.print(": "); pw.print(intents.size()); pw.println(" items");
16582                for (int j = 0; j < intents.size(); j++) {
16583                    pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16584                    if (dumpAll) {
16585                        intents.get(j).dump(pw, "      ");
16586                    }
16587                }
16588            }
16589            if (weakRefs.size() > 0) {
16590                printed = true;
16591                pw.println("  * WEAK REFS:");
16592                for (int i = 0; i < weakRefs.size(); i++) {
16593                    pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16594                }
16595            }
16596        }
16597
16598        if (!printed) {
16599            pw.println("  (nothing)");
16600        }
16601    }
16602
16603    private static final int dumpProcessList(PrintWriter pw,
16604            ActivityManagerService service, List list,
16605            String prefix, String normalLabel, String persistentLabel,
16606            String dumpPackage) {
16607        int numPers = 0;
16608        final int N = list.size()-1;
16609        for (int i=N; i>=0; i--) {
16610            ProcessRecord r = (ProcessRecord)list.get(i);
16611            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16612                continue;
16613            }
16614            pw.println(String.format("%s%s #%2d: %s",
16615                    prefix, (r.persistent ? persistentLabel : normalLabel),
16616                    i, r.toString()));
16617            if (r.persistent) {
16618                numPers++;
16619            }
16620        }
16621        return numPers;
16622    }
16623
16624    private static final boolean dumpProcessOomList(PrintWriter pw,
16625            ActivityManagerService service, List<ProcessRecord> origList,
16626            String prefix, String normalLabel, String persistentLabel,
16627            boolean inclDetails, String dumpPackage) {
16628
16629        ArrayList<Pair<ProcessRecord, Integer>> list
16630                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16631        for (int i=0; i<origList.size(); i++) {
16632            ProcessRecord r = origList.get(i);
16633            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16634                continue;
16635            }
16636            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16637        }
16638
16639        if (list.size() <= 0) {
16640            return false;
16641        }
16642
16643        Comparator<Pair<ProcessRecord, Integer>> comparator
16644                = new Comparator<Pair<ProcessRecord, Integer>>() {
16645            @Override
16646            public int compare(Pair<ProcessRecord, Integer> object1,
16647                    Pair<ProcessRecord, Integer> object2) {
16648                if (object1.first.setAdj != object2.first.setAdj) {
16649                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16650                }
16651                if (object1.first.setProcState != object2.first.setProcState) {
16652                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16653                }
16654                if (object1.second.intValue() != object2.second.intValue()) {
16655                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16656                }
16657                return 0;
16658            }
16659        };
16660
16661        Collections.sort(list, comparator);
16662
16663        final long curUptime = SystemClock.uptimeMillis();
16664        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16665
16666        for (int i=list.size()-1; i>=0; i--) {
16667            ProcessRecord r = list.get(i).first;
16668            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16669            char schedGroup;
16670            switch (r.setSchedGroup) {
16671                case ProcessList.SCHED_GROUP_BACKGROUND:
16672                    schedGroup = 'B';
16673                    break;
16674                case ProcessList.SCHED_GROUP_DEFAULT:
16675                    schedGroup = 'F';
16676                    break;
16677                case ProcessList.SCHED_GROUP_TOP_APP:
16678                    schedGroup = 'T';
16679                    break;
16680                default:
16681                    schedGroup = '?';
16682                    break;
16683            }
16684            char foreground;
16685            if (r.foregroundActivities) {
16686                foreground = 'A';
16687            } else if (r.foregroundServices) {
16688                foreground = 'S';
16689            } else {
16690                foreground = ' ';
16691            }
16692            String procState = ProcessList.makeProcStateString(r.curProcState);
16693            pw.print(prefix);
16694            pw.print(r.persistent ? persistentLabel : normalLabel);
16695            pw.print(" #");
16696            int num = (origList.size()-1)-list.get(i).second;
16697            if (num < 10) pw.print(' ');
16698            pw.print(num);
16699            pw.print(": ");
16700            pw.print(oomAdj);
16701            pw.print(' ');
16702            pw.print(schedGroup);
16703            pw.print('/');
16704            pw.print(foreground);
16705            pw.print('/');
16706            pw.print(procState);
16707            pw.print(" trm:");
16708            if (r.trimMemoryLevel < 10) pw.print(' ');
16709            pw.print(r.trimMemoryLevel);
16710            pw.print(' ');
16711            pw.print(r.toShortString());
16712            pw.print(" (");
16713            pw.print(r.adjType);
16714            pw.println(')');
16715            if (r.adjSource != null || r.adjTarget != null) {
16716                pw.print(prefix);
16717                pw.print("    ");
16718                if (r.adjTarget instanceof ComponentName) {
16719                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16720                } else if (r.adjTarget != null) {
16721                    pw.print(r.adjTarget.toString());
16722                } else {
16723                    pw.print("{null}");
16724                }
16725                pw.print("<=");
16726                if (r.adjSource instanceof ProcessRecord) {
16727                    pw.print("Proc{");
16728                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16729                    pw.println("}");
16730                } else if (r.adjSource != null) {
16731                    pw.println(r.adjSource.toString());
16732                } else {
16733                    pw.println("{null}");
16734                }
16735            }
16736            if (inclDetails) {
16737                pw.print(prefix);
16738                pw.print("    ");
16739                pw.print("oom: max="); pw.print(r.maxAdj);
16740                pw.print(" curRaw="); pw.print(r.curRawAdj);
16741                pw.print(" setRaw="); pw.print(r.setRawAdj);
16742                pw.print(" cur="); pw.print(r.curAdj);
16743                pw.print(" set="); pw.println(r.setAdj);
16744                pw.print(prefix);
16745                pw.print("    ");
16746                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16747                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16748                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16749                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16750                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16751                pw.println();
16752                pw.print(prefix);
16753                pw.print("    ");
16754                pw.print("cached="); pw.print(r.cached);
16755                pw.print(" empty="); pw.print(r.empty);
16756                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16757
16758                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16759                    if (r.lastCpuTime != 0) {
16760                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16761                        pw.print(prefix);
16762                        pw.print("    ");
16763                        pw.print("run cpu over ");
16764                        TimeUtils.formatDuration(uptimeSince, pw);
16765                        pw.print(" used ");
16766                        TimeUtils.formatDuration(timeUsed, pw);
16767                        pw.print(" (");
16768                        pw.print((timeUsed*100)/uptimeSince);
16769                        pw.println("%)");
16770                    }
16771                }
16772            }
16773        }
16774        return true;
16775    }
16776
16777    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16778            String[] args) {
16779        ArrayList<ProcessRecord> procs;
16780        synchronized (this) {
16781            if (args != null && args.length > start
16782                    && args[start].charAt(0) != '-') {
16783                procs = new ArrayList<ProcessRecord>();
16784                int pid = -1;
16785                try {
16786                    pid = Integer.parseInt(args[start]);
16787                } catch (NumberFormatException e) {
16788                }
16789                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16790                    ProcessRecord proc = mLruProcesses.get(i);
16791                    if (proc.pid == pid) {
16792                        procs.add(proc);
16793                    } else if (allPkgs && proc.pkgList != null
16794                            && proc.pkgList.containsKey(args[start])) {
16795                        procs.add(proc);
16796                    } else if (proc.processName.equals(args[start])) {
16797                        procs.add(proc);
16798                    }
16799                }
16800                if (procs.size() <= 0) {
16801                    return null;
16802                }
16803            } else {
16804                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16805            }
16806        }
16807        return procs;
16808    }
16809
16810    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16811            PrintWriter pw, String[] args) {
16812        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16813        if (procs == null) {
16814            pw.println("No process found for: " + args[0]);
16815            return;
16816        }
16817
16818        long uptime = SystemClock.uptimeMillis();
16819        long realtime = SystemClock.elapsedRealtime();
16820        pw.println("Applications Graphics Acceleration Info:");
16821        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16822
16823        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16824            ProcessRecord r = procs.get(i);
16825            if (r.thread != null) {
16826                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16827                pw.flush();
16828                try {
16829                    TransferPipe tp = new TransferPipe();
16830                    try {
16831                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16832                        tp.go(fd);
16833                    } finally {
16834                        tp.kill();
16835                    }
16836                } catch (IOException e) {
16837                    pw.println("Failure while dumping the app: " + r);
16838                    pw.flush();
16839                } catch (RemoteException e) {
16840                    pw.println("Got a RemoteException while dumping the app " + r);
16841                    pw.flush();
16842                }
16843            }
16844        }
16845    }
16846
16847    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16848        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16849        if (procs == null) {
16850            pw.println("No process found for: " + args[0]);
16851            return;
16852        }
16853
16854        pw.println("Applications Database Info:");
16855
16856        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16857            ProcessRecord r = procs.get(i);
16858            if (r.thread != null) {
16859                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16860                pw.flush();
16861                try {
16862                    TransferPipe tp = new TransferPipe();
16863                    try {
16864                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16865                        tp.go(fd);
16866                    } finally {
16867                        tp.kill();
16868                    }
16869                } catch (IOException e) {
16870                    pw.println("Failure while dumping the app: " + r);
16871                    pw.flush();
16872                } catch (RemoteException e) {
16873                    pw.println("Got a RemoteException while dumping the app " + r);
16874                    pw.flush();
16875                }
16876            }
16877        }
16878    }
16879
16880    final static class MemItem {
16881        final boolean isProc;
16882        final String label;
16883        final String shortLabel;
16884        final long pss;
16885        final long swapPss;
16886        final int id;
16887        final boolean hasActivities;
16888        ArrayList<MemItem> subitems;
16889
16890        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16891                boolean _hasActivities) {
16892            isProc = true;
16893            label = _label;
16894            shortLabel = _shortLabel;
16895            pss = _pss;
16896            swapPss = _swapPss;
16897            id = _id;
16898            hasActivities = _hasActivities;
16899        }
16900
16901        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16902            isProc = false;
16903            label = _label;
16904            shortLabel = _shortLabel;
16905            pss = _pss;
16906            swapPss = _swapPss;
16907            id = _id;
16908            hasActivities = false;
16909        }
16910    }
16911
16912    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16913            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16914        if (sort && !isCompact) {
16915            Collections.sort(items, new Comparator<MemItem>() {
16916                @Override
16917                public int compare(MemItem lhs, MemItem rhs) {
16918                    if (lhs.pss < rhs.pss) {
16919                        return 1;
16920                    } else if (lhs.pss > rhs.pss) {
16921                        return -1;
16922                    }
16923                    return 0;
16924                }
16925            });
16926        }
16927
16928        for (int i=0; i<items.size(); i++) {
16929            MemItem mi = items.get(i);
16930            if (!isCompact) {
16931                if (dumpSwapPss) {
16932                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16933                            mi.label, stringifyKBSize(mi.swapPss));
16934                } else {
16935                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16936                }
16937            } else if (mi.isProc) {
16938                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16939                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16940                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16941                pw.println(mi.hasActivities ? ",a" : ",e");
16942            } else {
16943                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16944                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16945            }
16946            if (mi.subitems != null) {
16947                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16948                        true, isCompact, dumpSwapPss);
16949            }
16950        }
16951    }
16952
16953    // These are in KB.
16954    static final long[] DUMP_MEM_BUCKETS = new long[] {
16955        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16956        120*1024, 160*1024, 200*1024,
16957        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16958        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16959    };
16960
16961    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16962            boolean stackLike) {
16963        int start = label.lastIndexOf('.');
16964        if (start >= 0) start++;
16965        else start = 0;
16966        int end = label.length();
16967        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16968            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16969                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16970                out.append(bucket);
16971                out.append(stackLike ? "MB." : "MB ");
16972                out.append(label, start, end);
16973                return;
16974            }
16975        }
16976        out.append(memKB/1024);
16977        out.append(stackLike ? "MB." : "MB ");
16978        out.append(label, start, end);
16979    }
16980
16981    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16982            ProcessList.NATIVE_ADJ,
16983            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16984            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16985            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16986            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16987            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16988            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16989    };
16990    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16991            "Native",
16992            "System", "Persistent", "Persistent Service", "Foreground",
16993            "Visible", "Perceptible",
16994            "Heavy Weight", "Backup",
16995            "A Services", "Home",
16996            "Previous", "B Services", "Cached"
16997    };
16998    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16999            "native",
17000            "sys", "pers", "persvc", "fore",
17001            "vis", "percept",
17002            "heavy", "backup",
17003            "servicea", "home",
17004            "prev", "serviceb", "cached"
17005    };
17006
17007    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17008            long realtime, boolean isCheckinRequest, boolean isCompact) {
17009        if (isCompact) {
17010            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17011        }
17012        if (isCheckinRequest || isCompact) {
17013            // short checkin version
17014            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17015        } else {
17016            pw.println("Applications Memory Usage (in Kilobytes):");
17017            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17018        }
17019    }
17020
17021    private static final int KSM_SHARED = 0;
17022    private static final int KSM_SHARING = 1;
17023    private static final int KSM_UNSHARED = 2;
17024    private static final int KSM_VOLATILE = 3;
17025
17026    private final long[] getKsmInfo() {
17027        long[] longOut = new long[4];
17028        final int[] SINGLE_LONG_FORMAT = new int[] {
17029            PROC_SPACE_TERM| PROC_OUT_LONG
17030        };
17031        long[] longTmp = new long[1];
17032        readProcFile("/sys/kernel/mm/ksm/pages_shared",
17033                SINGLE_LONG_FORMAT, null, longTmp, null);
17034        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17035        longTmp[0] = 0;
17036        readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17037                SINGLE_LONG_FORMAT, null, longTmp, null);
17038        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17039        longTmp[0] = 0;
17040        readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17041                SINGLE_LONG_FORMAT, null, longTmp, null);
17042        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17043        longTmp[0] = 0;
17044        readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17045                SINGLE_LONG_FORMAT, null, longTmp, null);
17046        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17047        return longOut;
17048    }
17049
17050    private static String stringifySize(long size, int order) {
17051        Locale locale = Locale.US;
17052        switch (order) {
17053            case 1:
17054                return String.format(locale, "%,13d", size);
17055            case 1024:
17056                return String.format(locale, "%,9dK", size / 1024);
17057            case 1024 * 1024:
17058                return String.format(locale, "%,5dM", size / 1024 / 1024);
17059            case 1024 * 1024 * 1024:
17060                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17061            default:
17062                throw new IllegalArgumentException("Invalid size order");
17063        }
17064    }
17065
17066    private static String stringifyKBSize(long size) {
17067        return stringifySize(size * 1024, 1024);
17068    }
17069
17070    // Update this version number in case you change the 'compact' format
17071    private static final int MEMINFO_COMPACT_VERSION = 1;
17072
17073    final void dumpApplicationMemoryUsage(FileDescriptor fd,
17074            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17075        boolean dumpDetails = false;
17076        boolean dumpFullDetails = false;
17077        boolean dumpDalvik = false;
17078        boolean dumpSummaryOnly = false;
17079        boolean dumpUnreachable = false;
17080        boolean oomOnly = false;
17081        boolean isCompact = false;
17082        boolean localOnly = false;
17083        boolean packages = false;
17084        boolean isCheckinRequest = false;
17085        boolean dumpSwapPss = false;
17086
17087        int opti = 0;
17088        while (opti < args.length) {
17089            String opt = args[opti];
17090            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17091                break;
17092            }
17093            opti++;
17094            if ("-a".equals(opt)) {
17095                dumpDetails = true;
17096                dumpFullDetails = true;
17097                dumpDalvik = true;
17098                dumpSwapPss = true;
17099            } else if ("-d".equals(opt)) {
17100                dumpDalvik = true;
17101            } else if ("-c".equals(opt)) {
17102                isCompact = true;
17103            } else if ("-s".equals(opt)) {
17104                dumpDetails = true;
17105                dumpSummaryOnly = true;
17106            } else if ("-S".equals(opt)) {
17107                dumpSwapPss = true;
17108            } else if ("--unreachable".equals(opt)) {
17109                dumpUnreachable = true;
17110            } else if ("--oom".equals(opt)) {
17111                oomOnly = true;
17112            } else if ("--local".equals(opt)) {
17113                localOnly = true;
17114            } else if ("--package".equals(opt)) {
17115                packages = true;
17116            } else if ("--checkin".equals(opt)) {
17117                isCheckinRequest = true;
17118
17119            } else if ("-h".equals(opt)) {
17120                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17121                pw.println("  -a: include all available information for each process.");
17122                pw.println("  -d: include dalvik details.");
17123                pw.println("  -c: dump in a compact machine-parseable representation.");
17124                pw.println("  -s: dump only summary of application memory usage.");
17125                pw.println("  -S: dump also SwapPss.");
17126                pw.println("  --oom: only show processes organized by oom adj.");
17127                pw.println("  --local: only collect details locally, don't call process.");
17128                pw.println("  --package: interpret process arg as package, dumping all");
17129                pw.println("             processes that have loaded that package.");
17130                pw.println("  --checkin: dump data for a checkin");
17131                pw.println("If [process] is specified it can be the name or ");
17132                pw.println("pid of a specific process to dump.");
17133                return;
17134            } else {
17135                pw.println("Unknown argument: " + opt + "; use -h for help");
17136            }
17137        }
17138
17139        long uptime = SystemClock.uptimeMillis();
17140        long realtime = SystemClock.elapsedRealtime();
17141        final long[] tmpLong = new long[1];
17142
17143        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17144        if (procs == null) {
17145            // No Java processes.  Maybe they want to print a native process.
17146            if (args != null && args.length > opti
17147                    && args[opti].charAt(0) != '-') {
17148                ArrayList<ProcessCpuTracker.Stats> nativeProcs
17149                        = new ArrayList<ProcessCpuTracker.Stats>();
17150                updateCpuStatsNow();
17151                int findPid = -1;
17152                try {
17153                    findPid = Integer.parseInt(args[opti]);
17154                } catch (NumberFormatException e) {
17155                }
17156                synchronized (mProcessCpuTracker) {
17157                    final int N = mProcessCpuTracker.countStats();
17158                    for (int i=0; i<N; i++) {
17159                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17160                        if (st.pid == findPid || (st.baseName != null
17161                                && st.baseName.equals(args[opti]))) {
17162                            nativeProcs.add(st);
17163                        }
17164                    }
17165                }
17166                if (nativeProcs.size() > 0) {
17167                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17168                            isCompact);
17169                    Debug.MemoryInfo mi = null;
17170                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17171                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17172                        final int pid = r.pid;
17173                        if (!isCheckinRequest && dumpDetails) {
17174                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17175                        }
17176                        if (mi == null) {
17177                            mi = new Debug.MemoryInfo();
17178                        }
17179                        if (dumpDetails || (!brief && !oomOnly)) {
17180                            Debug.getMemoryInfo(pid, mi);
17181                        } else {
17182                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17183                            mi.dalvikPrivateDirty = (int)tmpLong[0];
17184                        }
17185                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17186                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17187                        if (isCheckinRequest) {
17188                            pw.println();
17189                        }
17190                    }
17191                    return;
17192                }
17193            }
17194            pw.println("No process found for: " + args[opti]);
17195            return;
17196        }
17197
17198        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17199            dumpDetails = true;
17200        }
17201
17202        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17203
17204        String[] innerArgs = new String[args.length-opti];
17205        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17206
17207        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17208        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17209        long nativePss = 0;
17210        long nativeSwapPss = 0;
17211        long dalvikPss = 0;
17212        long dalvikSwapPss = 0;
17213        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17214                EmptyArray.LONG;
17215        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17216                EmptyArray.LONG;
17217        long otherPss = 0;
17218        long otherSwapPss = 0;
17219        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17220        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17221
17222        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17223        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17224        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17225                new ArrayList[DUMP_MEM_OOM_LABEL.length];
17226
17227        long totalPss = 0;
17228        long totalSwapPss = 0;
17229        long cachedPss = 0;
17230        long cachedSwapPss = 0;
17231        boolean hasSwapPss = false;
17232
17233        Debug.MemoryInfo mi = null;
17234        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17235            final ProcessRecord r = procs.get(i);
17236            final IApplicationThread thread;
17237            final int pid;
17238            final int oomAdj;
17239            final boolean hasActivities;
17240            synchronized (this) {
17241                thread = r.thread;
17242                pid = r.pid;
17243                oomAdj = r.getSetAdjWithServices();
17244                hasActivities = r.activities.size() > 0;
17245            }
17246            if (thread != null) {
17247                if (!isCheckinRequest && dumpDetails) {
17248                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17249                }
17250                if (mi == null) {
17251                    mi = new Debug.MemoryInfo();
17252                }
17253                if (dumpDetails || (!brief && !oomOnly)) {
17254                    Debug.getMemoryInfo(pid, mi);
17255                    hasSwapPss = mi.hasSwappedOutPss;
17256                } else {
17257                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17258                    mi.dalvikPrivateDirty = (int)tmpLong[0];
17259                }
17260                if (dumpDetails) {
17261                    if (localOnly) {
17262                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17263                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17264                        if (isCheckinRequest) {
17265                            pw.println();
17266                        }
17267                    } else {
17268                        pw.flush();
17269                        try {
17270                            TransferPipe tp = new TransferPipe();
17271                            try {
17272                                thread.dumpMemInfo(tp.getWriteFd(),
17273                                        mi, isCheckinRequest, dumpFullDetails,
17274                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17275                                tp.go(fd);
17276                            } finally {
17277                                tp.kill();
17278                            }
17279                        } catch (IOException e) {
17280                            if (!isCheckinRequest) {
17281                                pw.println("Got IoException! " + e);
17282                                pw.flush();
17283                            }
17284                        } catch (RemoteException e) {
17285                            if (!isCheckinRequest) {
17286                                pw.println("Got RemoteException! " + e);
17287                                pw.flush();
17288                            }
17289                        }
17290                    }
17291                }
17292
17293                final long myTotalPss = mi.getTotalPss();
17294                final long myTotalUss = mi.getTotalUss();
17295                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17296
17297                synchronized (this) {
17298                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17299                        // Record this for posterity if the process has been stable.
17300                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17301                    }
17302                }
17303
17304                if (!isCheckinRequest && mi != null) {
17305                    totalPss += myTotalPss;
17306                    totalSwapPss += myTotalSwapPss;
17307                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17308                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17309                            myTotalSwapPss, pid, hasActivities);
17310                    procMems.add(pssItem);
17311                    procMemsMap.put(pid, pssItem);
17312
17313                    nativePss += mi.nativePss;
17314                    nativeSwapPss += mi.nativeSwappedOutPss;
17315                    dalvikPss += mi.dalvikPss;
17316                    dalvikSwapPss += mi.dalvikSwappedOutPss;
17317                    for (int j=0; j<dalvikSubitemPss.length; j++) {
17318                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17319                        dalvikSubitemSwapPss[j] +=
17320                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17321                    }
17322                    otherPss += mi.otherPss;
17323                    otherSwapPss += mi.otherSwappedOutPss;
17324                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17325                        long mem = mi.getOtherPss(j);
17326                        miscPss[j] += mem;
17327                        otherPss -= mem;
17328                        mem = mi.getOtherSwappedOutPss(j);
17329                        miscSwapPss[j] += mem;
17330                        otherSwapPss -= mem;
17331                    }
17332
17333                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17334                        cachedPss += myTotalPss;
17335                        cachedSwapPss += myTotalSwapPss;
17336                    }
17337
17338                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17339                        if (oomIndex == (oomPss.length - 1)
17340                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17341                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17342                            oomPss[oomIndex] += myTotalPss;
17343                            oomSwapPss[oomIndex] += myTotalSwapPss;
17344                            if (oomProcs[oomIndex] == null) {
17345                                oomProcs[oomIndex] = new ArrayList<MemItem>();
17346                            }
17347                            oomProcs[oomIndex].add(pssItem);
17348                            break;
17349                        }
17350                    }
17351                }
17352            }
17353        }
17354
17355        long nativeProcTotalPss = 0;
17356
17357        if (!isCheckinRequest && procs.size() > 1 && !packages) {
17358            // If we are showing aggregations, also look for native processes to
17359            // include so that our aggregations are more accurate.
17360            updateCpuStatsNow();
17361            mi = null;
17362            synchronized (mProcessCpuTracker) {
17363                final int N = mProcessCpuTracker.countStats();
17364                for (int i=0; i<N; i++) {
17365                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17366                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17367                        if (mi == null) {
17368                            mi = new Debug.MemoryInfo();
17369                        }
17370                        if (!brief && !oomOnly) {
17371                            Debug.getMemoryInfo(st.pid, mi);
17372                        } else {
17373                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17374                            mi.nativePrivateDirty = (int)tmpLong[0];
17375                        }
17376
17377                        final long myTotalPss = mi.getTotalPss();
17378                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17379                        totalPss += myTotalPss;
17380                        nativeProcTotalPss += myTotalPss;
17381
17382                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17383                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17384                        procMems.add(pssItem);
17385
17386                        nativePss += mi.nativePss;
17387                        nativeSwapPss += mi.nativeSwappedOutPss;
17388                        dalvikPss += mi.dalvikPss;
17389                        dalvikSwapPss += mi.dalvikSwappedOutPss;
17390                        for (int j=0; j<dalvikSubitemPss.length; j++) {
17391                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17392                            dalvikSubitemSwapPss[j] +=
17393                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17394                        }
17395                        otherPss += mi.otherPss;
17396                        otherSwapPss += mi.otherSwappedOutPss;
17397                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17398                            long mem = mi.getOtherPss(j);
17399                            miscPss[j] += mem;
17400                            otherPss -= mem;
17401                            mem = mi.getOtherSwappedOutPss(j);
17402                            miscSwapPss[j] += mem;
17403                            otherSwapPss -= mem;
17404                        }
17405                        oomPss[0] += myTotalPss;
17406                        oomSwapPss[0] += myTotalSwapPss;
17407                        if (oomProcs[0] == null) {
17408                            oomProcs[0] = new ArrayList<MemItem>();
17409                        }
17410                        oomProcs[0].add(pssItem);
17411                    }
17412                }
17413            }
17414
17415            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17416
17417            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17418            final int dalvikId = -2;
17419            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17420            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17421            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17422                String label = Debug.MemoryInfo.getOtherLabel(j);
17423                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17424            }
17425            if (dalvikSubitemPss.length > 0) {
17426                // Add dalvik subitems.
17427                for (MemItem memItem : catMems) {
17428                    int memItemStart = 0, memItemEnd = 0;
17429                    if (memItem.id == dalvikId) {
17430                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17431                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17432                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17433                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17434                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17435                    } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17436                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17437                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17438                    } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17439                        memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17440                        memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17441                    } else {
17442                        continue;  // No subitems, continue.
17443                    }
17444                    memItem.subitems = new ArrayList<MemItem>();
17445                    for (int j=memItemStart; j<=memItemEnd; j++) {
17446                        final String name = Debug.MemoryInfo.getOtherLabel(
17447                                Debug.MemoryInfo.NUM_OTHER_STATS + j);
17448                        memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17449                                dalvikSubitemSwapPss[j], j));
17450                    }
17451                }
17452            }
17453
17454            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17455            for (int j=0; j<oomPss.length; j++) {
17456                if (oomPss[j] != 0) {
17457                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17458                            : DUMP_MEM_OOM_LABEL[j];
17459                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17460                            DUMP_MEM_OOM_ADJ[j]);
17461                    item.subitems = oomProcs[j];
17462                    oomMems.add(item);
17463                }
17464            }
17465
17466            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17467            if (!brief && !oomOnly && !isCompact) {
17468                pw.println();
17469                pw.println("Total PSS by process:");
17470                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17471                pw.println();
17472            }
17473            if (!isCompact) {
17474                pw.println("Total PSS by OOM adjustment:");
17475            }
17476            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17477            if (!brief && !oomOnly) {
17478                PrintWriter out = categoryPw != null ? categoryPw : pw;
17479                if (!isCompact) {
17480                    out.println();
17481                    out.println("Total PSS by category:");
17482                }
17483                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17484            }
17485            if (!isCompact) {
17486                pw.println();
17487            }
17488            MemInfoReader memInfo = new MemInfoReader();
17489            memInfo.readMemInfo();
17490            if (nativeProcTotalPss > 0) {
17491                synchronized (this) {
17492                    final long cachedKb = memInfo.getCachedSizeKb();
17493                    final long freeKb = memInfo.getFreeSizeKb();
17494                    final long zramKb = memInfo.getZramTotalSizeKb();
17495                    final long kernelKb = memInfo.getKernelUsedSizeKb();
17496                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17497                            kernelKb*1024, nativeProcTotalPss*1024);
17498                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17499                            nativeProcTotalPss);
17500                }
17501            }
17502            if (!brief) {
17503                if (!isCompact) {
17504                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17505                    pw.print(" (status ");
17506                    switch (mLastMemoryLevel) {
17507                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17508                            pw.println("normal)");
17509                            break;
17510                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17511                            pw.println("moderate)");
17512                            break;
17513                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
17514                            pw.println("low)");
17515                            break;
17516                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17517                            pw.println("critical)");
17518                            break;
17519                        default:
17520                            pw.print(mLastMemoryLevel);
17521                            pw.println(")");
17522                            break;
17523                    }
17524                    pw.print(" Free RAM: ");
17525                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17526                            + memInfo.getFreeSizeKb()));
17527                    pw.print(" (");
17528                    pw.print(stringifyKBSize(cachedPss));
17529                    pw.print(" cached pss + ");
17530                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17531                    pw.print(" cached kernel + ");
17532                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17533                    pw.println(" free)");
17534                } else {
17535                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17536                    pw.print(cachedPss + memInfo.getCachedSizeKb()
17537                            + memInfo.getFreeSizeKb()); pw.print(",");
17538                    pw.println(totalPss - cachedPss);
17539                }
17540            }
17541            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17542                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17543                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17544            if (!isCompact) {
17545                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17546                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17547                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17548                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17549                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17550            } else {
17551                pw.print("lostram,"); pw.println(lostRAM);
17552            }
17553            if (!brief) {
17554                if (memInfo.getZramTotalSizeKb() != 0) {
17555                    if (!isCompact) {
17556                        pw.print("     ZRAM: ");
17557                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17558                                pw.print(" physical used for ");
17559                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17560                                        - memInfo.getSwapFreeSizeKb()));
17561                                pw.print(" in swap (");
17562                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17563                                pw.println(" total swap)");
17564                    } else {
17565                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17566                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17567                                pw.println(memInfo.getSwapFreeSizeKb());
17568                    }
17569                }
17570                final long[] ksm = getKsmInfo();
17571                if (!isCompact) {
17572                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17573                            || ksm[KSM_VOLATILE] != 0) {
17574                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17575                                pw.print(" saved from shared ");
17576                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17577                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17578                                pw.print(" unshared; ");
17579                                pw.print(stringifyKBSize(
17580                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
17581                    }
17582                    pw.print("   Tuning: ");
17583                    pw.print(ActivityManager.staticGetMemoryClass());
17584                    pw.print(" (large ");
17585                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17586                    pw.print("), oom ");
17587                    pw.print(stringifySize(
17588                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17589                    pw.print(", restore limit ");
17590                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17591                    if (ActivityManager.isLowRamDeviceStatic()) {
17592                        pw.print(" (low-ram)");
17593                    }
17594                    if (ActivityManager.isHighEndGfx()) {
17595                        pw.print(" (high-end-gfx)");
17596                    }
17597                    pw.println();
17598                } else {
17599                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17600                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17601                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17602                    pw.print("tuning,");
17603                    pw.print(ActivityManager.staticGetMemoryClass());
17604                    pw.print(',');
17605                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17606                    pw.print(',');
17607                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17608                    if (ActivityManager.isLowRamDeviceStatic()) {
17609                        pw.print(",low-ram");
17610                    }
17611                    if (ActivityManager.isHighEndGfx()) {
17612                        pw.print(",high-end-gfx");
17613                    }
17614                    pw.println();
17615                }
17616            }
17617        }
17618    }
17619
17620    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17621            long memtrack, String name) {
17622        sb.append("  ");
17623        sb.append(ProcessList.makeOomAdjString(oomAdj));
17624        sb.append(' ');
17625        sb.append(ProcessList.makeProcStateString(procState));
17626        sb.append(' ');
17627        ProcessList.appendRamKb(sb, pss);
17628        sb.append(": ");
17629        sb.append(name);
17630        if (memtrack > 0) {
17631            sb.append(" (");
17632            sb.append(stringifyKBSize(memtrack));
17633            sb.append(" memtrack)");
17634        }
17635    }
17636
17637    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17638        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17639        sb.append(" (pid ");
17640        sb.append(mi.pid);
17641        sb.append(") ");
17642        sb.append(mi.adjType);
17643        sb.append('\n');
17644        if (mi.adjReason != null) {
17645            sb.append("                      ");
17646            sb.append(mi.adjReason);
17647            sb.append('\n');
17648        }
17649    }
17650
17651    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17652        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17653        for (int i=0, N=memInfos.size(); i<N; i++) {
17654            ProcessMemInfo mi = memInfos.get(i);
17655            infoMap.put(mi.pid, mi);
17656        }
17657        updateCpuStatsNow();
17658        long[] memtrackTmp = new long[1];
17659        final List<ProcessCpuTracker.Stats> stats;
17660        // Get a list of Stats that have vsize > 0
17661        synchronized (mProcessCpuTracker) {
17662            stats = mProcessCpuTracker.getStats((st) -> {
17663                return st.vsize > 0;
17664            });
17665        }
17666        final int statsCount = stats.size();
17667        for (int i = 0; i < statsCount; i++) {
17668            ProcessCpuTracker.Stats st = stats.get(i);
17669            long pss = Debug.getPss(st.pid, null, memtrackTmp);
17670            if (pss > 0) {
17671                if (infoMap.indexOfKey(st.pid) < 0) {
17672                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17673                            ProcessList.NATIVE_ADJ, -1, "native", null);
17674                    mi.pss = pss;
17675                    mi.memtrack = memtrackTmp[0];
17676                    memInfos.add(mi);
17677                }
17678            }
17679        }
17680
17681        long totalPss = 0;
17682        long totalMemtrack = 0;
17683        for (int i=0, N=memInfos.size(); i<N; i++) {
17684            ProcessMemInfo mi = memInfos.get(i);
17685            if (mi.pss == 0) {
17686                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17687                mi.memtrack = memtrackTmp[0];
17688            }
17689            totalPss += mi.pss;
17690            totalMemtrack += mi.memtrack;
17691        }
17692        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17693            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17694                if (lhs.oomAdj != rhs.oomAdj) {
17695                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17696                }
17697                if (lhs.pss != rhs.pss) {
17698                    return lhs.pss < rhs.pss ? 1 : -1;
17699                }
17700                return 0;
17701            }
17702        });
17703
17704        StringBuilder tag = new StringBuilder(128);
17705        StringBuilder stack = new StringBuilder(128);
17706        tag.append("Low on memory -- ");
17707        appendMemBucket(tag, totalPss, "total", false);
17708        appendMemBucket(stack, totalPss, "total", true);
17709
17710        StringBuilder fullNativeBuilder = new StringBuilder(1024);
17711        StringBuilder shortNativeBuilder = new StringBuilder(1024);
17712        StringBuilder fullJavaBuilder = new StringBuilder(1024);
17713
17714        boolean firstLine = true;
17715        int lastOomAdj = Integer.MIN_VALUE;
17716        long extraNativeRam = 0;
17717        long extraNativeMemtrack = 0;
17718        long cachedPss = 0;
17719        for (int i=0, N=memInfos.size(); i<N; i++) {
17720            ProcessMemInfo mi = memInfos.get(i);
17721
17722            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17723                cachedPss += mi.pss;
17724            }
17725
17726            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17727                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17728                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17729                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17730                if (lastOomAdj != mi.oomAdj) {
17731                    lastOomAdj = mi.oomAdj;
17732                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17733                        tag.append(" / ");
17734                    }
17735                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17736                        if (firstLine) {
17737                            stack.append(":");
17738                            firstLine = false;
17739                        }
17740                        stack.append("\n\t at ");
17741                    } else {
17742                        stack.append("$");
17743                    }
17744                } else {
17745                    tag.append(" ");
17746                    stack.append("$");
17747                }
17748                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17749                    appendMemBucket(tag, mi.pss, mi.name, false);
17750                }
17751                appendMemBucket(stack, mi.pss, mi.name, true);
17752                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17753                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17754                    stack.append("(");
17755                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17756                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17757                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17758                            stack.append(":");
17759                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17760                        }
17761                    }
17762                    stack.append(")");
17763                }
17764            }
17765
17766            appendMemInfo(fullNativeBuilder, mi);
17767            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17768                // The short form only has native processes that are >= 512K.
17769                if (mi.pss >= 512) {
17770                    appendMemInfo(shortNativeBuilder, mi);
17771                } else {
17772                    extraNativeRam += mi.pss;
17773                    extraNativeMemtrack += mi.memtrack;
17774                }
17775            } else {
17776                // Short form has all other details, but if we have collected RAM
17777                // from smaller native processes let's dump a summary of that.
17778                if (extraNativeRam > 0) {
17779                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17780                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17781                    shortNativeBuilder.append('\n');
17782                    extraNativeRam = 0;
17783                }
17784                appendMemInfo(fullJavaBuilder, mi);
17785            }
17786        }
17787
17788        fullJavaBuilder.append("           ");
17789        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17790        fullJavaBuilder.append(": TOTAL");
17791        if (totalMemtrack > 0) {
17792            fullJavaBuilder.append(" (");
17793            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17794            fullJavaBuilder.append(" memtrack)");
17795        } else {
17796        }
17797        fullJavaBuilder.append("\n");
17798
17799        MemInfoReader memInfo = new MemInfoReader();
17800        memInfo.readMemInfo();
17801        final long[] infos = memInfo.getRawInfo();
17802
17803        StringBuilder memInfoBuilder = new StringBuilder(1024);
17804        Debug.getMemInfo(infos);
17805        memInfoBuilder.append("  MemInfo: ");
17806        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17807        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17808        memInfoBuilder.append(stringifyKBSize(
17809                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17810        memInfoBuilder.append(stringifyKBSize(
17811                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17812        memInfoBuilder.append(stringifyKBSize(
17813                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17814        memInfoBuilder.append("           ");
17815        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17816        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17817        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17818        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17819        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17820            memInfoBuilder.append("  ZRAM: ");
17821            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17822            memInfoBuilder.append(" RAM, ");
17823            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17824            memInfoBuilder.append(" swap total, ");
17825            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17826            memInfoBuilder.append(" swap free\n");
17827        }
17828        final long[] ksm = getKsmInfo();
17829        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17830                || ksm[KSM_VOLATILE] != 0) {
17831            memInfoBuilder.append("  KSM: ");
17832            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17833            memInfoBuilder.append(" saved from shared ");
17834            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17835            memInfoBuilder.append("\n       ");
17836            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17837            memInfoBuilder.append(" unshared; ");
17838            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17839            memInfoBuilder.append(" volatile\n");
17840        }
17841        memInfoBuilder.append("  Free RAM: ");
17842        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17843                + memInfo.getFreeSizeKb()));
17844        memInfoBuilder.append("\n");
17845        memInfoBuilder.append("  Used RAM: ");
17846        memInfoBuilder.append(stringifyKBSize(
17847                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17848        memInfoBuilder.append("\n");
17849        memInfoBuilder.append("  Lost RAM: ");
17850        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17851                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17852                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17853        memInfoBuilder.append("\n");
17854        Slog.i(TAG, "Low on memory:");
17855        Slog.i(TAG, shortNativeBuilder.toString());
17856        Slog.i(TAG, fullJavaBuilder.toString());
17857        Slog.i(TAG, memInfoBuilder.toString());
17858
17859        StringBuilder dropBuilder = new StringBuilder(1024);
17860        /*
17861        StringWriter oomSw = new StringWriter();
17862        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17863        StringWriter catSw = new StringWriter();
17864        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17865        String[] emptyArgs = new String[] { };
17866        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17867        oomPw.flush();
17868        String oomString = oomSw.toString();
17869        */
17870        dropBuilder.append("Low on memory:");
17871        dropBuilder.append(stack);
17872        dropBuilder.append('\n');
17873        dropBuilder.append(fullNativeBuilder);
17874        dropBuilder.append(fullJavaBuilder);
17875        dropBuilder.append('\n');
17876        dropBuilder.append(memInfoBuilder);
17877        dropBuilder.append('\n');
17878        /*
17879        dropBuilder.append(oomString);
17880        dropBuilder.append('\n');
17881        */
17882        StringWriter catSw = new StringWriter();
17883        synchronized (ActivityManagerService.this) {
17884            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17885            String[] emptyArgs = new String[] { };
17886            catPw.println();
17887            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17888            catPw.println();
17889            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17890                    false, null).dumpLocked();
17891            catPw.println();
17892            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17893            catPw.flush();
17894        }
17895        dropBuilder.append(catSw.toString());
17896        addErrorToDropBox("lowmem", null, "system_server", null,
17897                null, tag.toString(), dropBuilder.toString(), null, null);
17898        //Slog.i(TAG, "Sent to dropbox:");
17899        //Slog.i(TAG, dropBuilder.toString());
17900        synchronized (ActivityManagerService.this) {
17901            long now = SystemClock.uptimeMillis();
17902            if (mLastMemUsageReportTime < now) {
17903                mLastMemUsageReportTime = now;
17904            }
17905        }
17906    }
17907
17908    /**
17909     * Searches array of arguments for the specified string
17910     * @param args array of argument strings
17911     * @param value value to search for
17912     * @return true if the value is contained in the array
17913     */
17914    private static boolean scanArgs(String[] args, String value) {
17915        if (args != null) {
17916            for (String arg : args) {
17917                if (value.equals(arg)) {
17918                    return true;
17919                }
17920            }
17921        }
17922        return false;
17923    }
17924
17925    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17926            ContentProviderRecord cpr, boolean always) {
17927        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17928
17929        if (!inLaunching || always) {
17930            synchronized (cpr) {
17931                cpr.launchingApp = null;
17932                cpr.notifyAll();
17933            }
17934            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17935            String names[] = cpr.info.authority.split(";");
17936            for (int j = 0; j < names.length; j++) {
17937                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17938            }
17939        }
17940
17941        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17942            ContentProviderConnection conn = cpr.connections.get(i);
17943            if (conn.waiting) {
17944                // If this connection is waiting for the provider, then we don't
17945                // need to mess with its process unless we are always removing
17946                // or for some reason the provider is not currently launching.
17947                if (inLaunching && !always) {
17948                    continue;
17949                }
17950            }
17951            ProcessRecord capp = conn.client;
17952            conn.dead = true;
17953            if (conn.stableCount > 0) {
17954                if (!capp.persistent && capp.thread != null
17955                        && capp.pid != 0
17956                        && capp.pid != MY_PID) {
17957                    capp.kill("depends on provider "
17958                            + cpr.name.flattenToShortString()
17959                            + " in dying proc " + (proc != null ? proc.processName : "??")
17960                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17961                }
17962            } else if (capp.thread != null && conn.provider.provider != null) {
17963                try {
17964                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17965                } catch (RemoteException e) {
17966                }
17967                // In the protocol here, we don't expect the client to correctly
17968                // clean up this connection, we'll just remove it.
17969                cpr.connections.remove(i);
17970                if (conn.client.conProviders.remove(conn)) {
17971                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17972                }
17973            }
17974        }
17975
17976        if (inLaunching && always) {
17977            mLaunchingProviders.remove(cpr);
17978        }
17979        return inLaunching;
17980    }
17981
17982    /**
17983     * Main code for cleaning up a process when it has gone away.  This is
17984     * called both as a result of the process dying, or directly when stopping
17985     * a process when running in single process mode.
17986     *
17987     * @return Returns true if the given process has been restarted, so the
17988     * app that was passed in must remain on the process lists.
17989     */
17990    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17991            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17992        if (index >= 0) {
17993            removeLruProcessLocked(app);
17994            ProcessList.remove(app.pid);
17995        }
17996
17997        mProcessesToGc.remove(app);
17998        mPendingPssProcesses.remove(app);
17999
18000        // Dismiss any open dialogs.
18001        if (app.crashDialog != null && !app.forceCrashReport) {
18002            app.crashDialog.dismiss();
18003            app.crashDialog = null;
18004        }
18005        if (app.anrDialog != null) {
18006            app.anrDialog.dismiss();
18007            app.anrDialog = null;
18008        }
18009        if (app.waitDialog != null) {
18010            app.waitDialog.dismiss();
18011            app.waitDialog = null;
18012        }
18013
18014        app.crashing = false;
18015        app.notResponding = false;
18016
18017        app.resetPackageList(mProcessStats);
18018        app.unlinkDeathRecipient();
18019        app.makeInactive(mProcessStats);
18020        app.waitingToKill = null;
18021        app.forcingToImportant = null;
18022        updateProcessForegroundLocked(app, false, false);
18023        app.foregroundActivities = false;
18024        app.hasShownUi = false;
18025        app.treatLikeActivity = false;
18026        app.hasAboveClient = false;
18027        app.hasClientActivities = false;
18028
18029        mServices.killServicesLocked(app, allowRestart);
18030
18031        boolean restart = false;
18032
18033        // Remove published content providers.
18034        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18035            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18036            final boolean always = app.bad || !allowRestart;
18037            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18038            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18039                // We left the provider in the launching list, need to
18040                // restart it.
18041                restart = true;
18042            }
18043
18044            cpr.provider = null;
18045            cpr.proc = null;
18046        }
18047        app.pubProviders.clear();
18048
18049        // Take care of any launching providers waiting for this process.
18050        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18051            restart = true;
18052        }
18053
18054        // Unregister from connected content providers.
18055        if (!app.conProviders.isEmpty()) {
18056            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18057                ContentProviderConnection conn = app.conProviders.get(i);
18058                conn.provider.connections.remove(conn);
18059                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18060                        conn.provider.name);
18061            }
18062            app.conProviders.clear();
18063        }
18064
18065        // At this point there may be remaining entries in mLaunchingProviders
18066        // where we were the only one waiting, so they are no longer of use.
18067        // Look for these and clean up if found.
18068        // XXX Commented out for now.  Trying to figure out a way to reproduce
18069        // the actual situation to identify what is actually going on.
18070        if (false) {
18071            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18072                ContentProviderRecord cpr = mLaunchingProviders.get(i);
18073                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18074                    synchronized (cpr) {
18075                        cpr.launchingApp = null;
18076                        cpr.notifyAll();
18077                    }
18078                }
18079            }
18080        }
18081
18082        skipCurrentReceiverLocked(app);
18083
18084        // Unregister any receivers.
18085        for (int i = app.receivers.size() - 1; i >= 0; i--) {
18086            removeReceiverLocked(app.receivers.valueAt(i));
18087        }
18088        app.receivers.clear();
18089
18090        // If the app is undergoing backup, tell the backup manager about it
18091        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18092            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18093                    + mBackupTarget.appInfo + " died during backup");
18094            mHandler.post(new Runnable() {
18095                @Override
18096                public void run(){
18097                    try {
18098                        IBackupManager bm = IBackupManager.Stub.asInterface(
18099                                ServiceManager.getService(Context.BACKUP_SERVICE));
18100                        bm.agentDisconnected(app.info.packageName);
18101                    } catch (RemoteException e) {
18102                        // can't happen; backup manager is local
18103                    }
18104                }
18105            });
18106        }
18107
18108        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18109            ProcessChangeItem item = mPendingProcessChanges.get(i);
18110            if (item.pid == app.pid) {
18111                mPendingProcessChanges.remove(i);
18112                mAvailProcessChanges.add(item);
18113            }
18114        }
18115        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18116                null).sendToTarget();
18117
18118        // If the caller is restarting this app, then leave it in its
18119        // current lists and let the caller take care of it.
18120        if (restarting) {
18121            return false;
18122        }
18123
18124        if (!app.persistent || app.isolated) {
18125            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18126                    "Removing non-persistent process during cleanup: " + app);
18127            if (!replacingPid) {
18128                removeProcessNameLocked(app.processName, app.uid, app);
18129            }
18130            if (mHeavyWeightProcess == app) {
18131                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18132                        mHeavyWeightProcess.userId, 0));
18133                mHeavyWeightProcess = null;
18134            }
18135        } else if (!app.removed) {
18136            // This app is persistent, so we need to keep its record around.
18137            // If it is not already on the pending app list, add it there
18138            // and start a new process for it.
18139            if (mPersistentStartingProcesses.indexOf(app) < 0) {
18140                mPersistentStartingProcesses.add(app);
18141                restart = true;
18142            }
18143        }
18144        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18145                TAG_CLEANUP, "Clean-up removing on hold: " + app);
18146        mProcessesOnHold.remove(app);
18147
18148        if (app == mHomeProcess) {
18149            mHomeProcess = null;
18150        }
18151        if (app == mPreviousProcess) {
18152            mPreviousProcess = null;
18153        }
18154
18155        if (restart && !app.isolated) {
18156            // We have components that still need to be running in the
18157            // process, so re-launch it.
18158            if (index < 0) {
18159                ProcessList.remove(app.pid);
18160            }
18161            addProcessNameLocked(app);
18162            startProcessLocked(app, "restart", app.processName);
18163            return true;
18164        } else if (app.pid > 0 && app.pid != MY_PID) {
18165            // Goodbye!
18166            boolean removed;
18167            synchronized (mPidsSelfLocked) {
18168                mPidsSelfLocked.remove(app.pid);
18169                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18170            }
18171            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18172            if (app.isolated) {
18173                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18174            }
18175            app.setPid(0);
18176        }
18177        return false;
18178    }
18179
18180    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18181        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18182            ContentProviderRecord cpr = mLaunchingProviders.get(i);
18183            if (cpr.launchingApp == app) {
18184                return true;
18185            }
18186        }
18187        return false;
18188    }
18189
18190    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18191        // Look through the content providers we are waiting to have launched,
18192        // and if any run in this process then either schedule a restart of
18193        // the process or kill the client waiting for it if this process has
18194        // gone bad.
18195        boolean restart = false;
18196        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18197            ContentProviderRecord cpr = mLaunchingProviders.get(i);
18198            if (cpr.launchingApp == app) {
18199                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18200                    restart = true;
18201                } else {
18202                    removeDyingProviderLocked(app, cpr, true);
18203                }
18204            }
18205        }
18206        return restart;
18207    }
18208
18209    // =========================================================
18210    // SERVICES
18211    // =========================================================
18212
18213    @Override
18214    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18215            int flags) {
18216        enforceNotIsolatedCaller("getServices");
18217
18218        final int callingUid = Binder.getCallingUid();
18219        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18220            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18221        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18222            callingUid);
18223        synchronized (this) {
18224            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18225                allowed, canInteractAcrossUsers);
18226        }
18227    }
18228
18229    @Override
18230    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18231        enforceNotIsolatedCaller("getRunningServiceControlPanel");
18232        synchronized (this) {
18233            return mServices.getRunningServiceControlPanelLocked(name);
18234        }
18235    }
18236
18237    @Override
18238    public ComponentName startService(IApplicationThread caller, Intent service,
18239            String resolvedType, boolean requireForeground, String callingPackage, int userId)
18240            throws TransactionTooLargeException {
18241        enforceNotIsolatedCaller("startService");
18242        // Refuse possible leaked file descriptors
18243        if (service != null && service.hasFileDescriptors() == true) {
18244            throw new IllegalArgumentException("File descriptors passed in Intent");
18245        }
18246
18247        if (callingPackage == null) {
18248            throw new IllegalArgumentException("callingPackage cannot be null");
18249        }
18250
18251        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18252                "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18253        synchronized(this) {
18254            final int callingPid = Binder.getCallingPid();
18255            final int callingUid = Binder.getCallingUid();
18256            final long origId = Binder.clearCallingIdentity();
18257            ComponentName res;
18258            try {
18259                res = mServices.startServiceLocked(caller, service,
18260                        resolvedType, callingPid, callingUid,
18261                        requireForeground, callingPackage, userId);
18262            } finally {
18263                Binder.restoreCallingIdentity(origId);
18264            }
18265            return res;
18266        }
18267    }
18268
18269    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18270            boolean fgRequired, String callingPackage, int userId)
18271            throws TransactionTooLargeException {
18272        synchronized(this) {
18273            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18274                    "startServiceInPackage: " + service + " type=" + resolvedType);
18275            final long origId = Binder.clearCallingIdentity();
18276            ComponentName res;
18277            try {
18278                res = mServices.startServiceLocked(null, service,
18279                        resolvedType, -1, uid, fgRequired, callingPackage, userId);
18280            } finally {
18281                Binder.restoreCallingIdentity(origId);
18282            }
18283            return res;
18284        }
18285    }
18286
18287    @Override
18288    public int stopService(IApplicationThread caller, Intent service,
18289            String resolvedType, int userId) {
18290        enforceNotIsolatedCaller("stopService");
18291        // Refuse possible leaked file descriptors
18292        if (service != null && service.hasFileDescriptors() == true) {
18293            throw new IllegalArgumentException("File descriptors passed in Intent");
18294        }
18295
18296        synchronized(this) {
18297            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18298        }
18299    }
18300
18301    @Override
18302    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18303        enforceNotIsolatedCaller("peekService");
18304        // Refuse possible leaked file descriptors
18305        if (service != null && service.hasFileDescriptors() == true) {
18306            throw new IllegalArgumentException("File descriptors passed in Intent");
18307        }
18308
18309        if (callingPackage == null) {
18310            throw new IllegalArgumentException("callingPackage cannot be null");
18311        }
18312
18313        synchronized(this) {
18314            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18315        }
18316    }
18317
18318    @Override
18319    public boolean stopServiceToken(ComponentName className, IBinder token,
18320            int startId) {
18321        synchronized(this) {
18322            return mServices.stopServiceTokenLocked(className, token, startId);
18323        }
18324    }
18325
18326    @Override
18327    public void setServiceForeground(ComponentName className, IBinder token,
18328            int id, Notification notification, int flags) {
18329        synchronized(this) {
18330            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18331        }
18332    }
18333
18334    @Override
18335    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18336            boolean requireFull, String name, String callerPackage) {
18337        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18338                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18339    }
18340
18341    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18342            String className, int flags) {
18343        boolean result = false;
18344        // For apps that don't have pre-defined UIDs, check for permission
18345        if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18346            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18347                if (ActivityManager.checkUidPermission(
18348                        INTERACT_ACROSS_USERS,
18349                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18350                    ComponentName comp = new ComponentName(aInfo.packageName, className);
18351                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
18352                            + " requests FLAG_SINGLE_USER, but app does not hold "
18353                            + INTERACT_ACROSS_USERS;
18354                    Slog.w(TAG, msg);
18355                    throw new SecurityException(msg);
18356                }
18357                // Permission passed
18358                result = true;
18359            }
18360        } else if ("system".equals(componentProcessName)) {
18361            result = true;
18362        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18363            // Phone app and persistent apps are allowed to export singleuser providers.
18364            result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18365                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18366        }
18367        if (DEBUG_MU) Slog.v(TAG_MU,
18368                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18369                + Integer.toHexString(flags) + ") = " + result);
18370        return result;
18371    }
18372
18373    /**
18374     * Checks to see if the caller is in the same app as the singleton
18375     * component, or the component is in a special app. It allows special apps
18376     * to export singleton components but prevents exporting singleton
18377     * components for regular apps.
18378     */
18379    boolean isValidSingletonCall(int callingUid, int componentUid) {
18380        int componentAppId = UserHandle.getAppId(componentUid);
18381        return UserHandle.isSameApp(callingUid, componentUid)
18382                || componentAppId == SYSTEM_UID
18383                || componentAppId == PHONE_UID
18384                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18385                        == PackageManager.PERMISSION_GRANTED;
18386    }
18387
18388    public int bindService(IApplicationThread caller, IBinder token, Intent service,
18389            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18390            int userId) throws TransactionTooLargeException {
18391        enforceNotIsolatedCaller("bindService");
18392
18393        // Refuse possible leaked file descriptors
18394        if (service != null && service.hasFileDescriptors() == true) {
18395            throw new IllegalArgumentException("File descriptors passed in Intent");
18396        }
18397
18398        if (callingPackage == null) {
18399            throw new IllegalArgumentException("callingPackage cannot be null");
18400        }
18401
18402        synchronized(this) {
18403            return mServices.bindServiceLocked(caller, token, service,
18404                    resolvedType, connection, flags, callingPackage, userId);
18405        }
18406    }
18407
18408    public boolean unbindService(IServiceConnection connection) {
18409        synchronized (this) {
18410            return mServices.unbindServiceLocked(connection);
18411        }
18412    }
18413
18414    public void publishService(IBinder token, Intent intent, IBinder service) {
18415        // Refuse possible leaked file descriptors
18416        if (intent != null && intent.hasFileDescriptors() == true) {
18417            throw new IllegalArgumentException("File descriptors passed in Intent");
18418        }
18419
18420        synchronized(this) {
18421            if (!(token instanceof ServiceRecord)) {
18422                throw new IllegalArgumentException("Invalid service token");
18423            }
18424            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18425        }
18426    }
18427
18428    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18429        // Refuse possible leaked file descriptors
18430        if (intent != null && intent.hasFileDescriptors() == true) {
18431            throw new IllegalArgumentException("File descriptors passed in Intent");
18432        }
18433
18434        synchronized(this) {
18435            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18436        }
18437    }
18438
18439    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18440        synchronized(this) {
18441            if (!(token instanceof ServiceRecord)) {
18442                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18443                throw new IllegalArgumentException("Invalid service token");
18444            }
18445            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18446        }
18447    }
18448
18449    // =========================================================
18450    // BACKUP AND RESTORE
18451    // =========================================================
18452
18453    // Cause the target app to be launched if necessary and its backup agent
18454    // instantiated.  The backup agent will invoke backupAgentCreated() on the
18455    // activity manager to announce its creation.
18456    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18457        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18458        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18459
18460        IPackageManager pm = AppGlobals.getPackageManager();
18461        ApplicationInfo app = null;
18462        try {
18463            app = pm.getApplicationInfo(packageName, 0, userId);
18464        } catch (RemoteException e) {
18465            // can't happen; package manager is process-local
18466        }
18467        if (app == null) {
18468            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18469            return false;
18470        }
18471
18472        int oldBackupUid;
18473        int newBackupUid;
18474
18475        synchronized(this) {
18476            // !!! TODO: currently no check here that we're already bound
18477            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18478            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18479            synchronized (stats) {
18480                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18481            }
18482
18483            // Backup agent is now in use, its package can't be stopped.
18484            try {
18485                AppGlobals.getPackageManager().setPackageStoppedState(
18486                        app.packageName, false, UserHandle.getUserId(app.uid));
18487            } catch (RemoteException e) {
18488            } catch (IllegalArgumentException e) {
18489                Slog.w(TAG, "Failed trying to unstop package "
18490                        + app.packageName + ": " + e);
18491            }
18492
18493            BackupRecord r = new BackupRecord(ss, app, backupMode);
18494            ComponentName hostingName =
18495                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18496                            ? new ComponentName(app.packageName, app.backupAgentName)
18497                            : new ComponentName("android", "FullBackupAgent");
18498            // startProcessLocked() returns existing proc's record if it's already running
18499            ProcessRecord proc = startProcessLocked(app.processName, app,
18500                    false, 0, "backup", hostingName, false, false, false);
18501            if (proc == null) {
18502                Slog.e(TAG, "Unable to start backup agent process " + r);
18503                return false;
18504            }
18505
18506            // If the app is a regular app (uid >= 10000) and not the system server or phone
18507            // process, etc, then mark it as being in full backup so that certain calls to the
18508            // process can be blocked. This is not reset to false anywhere because we kill the
18509            // process after the full backup is done and the ProcessRecord will vaporize anyway.
18510            if (UserHandle.isApp(app.uid) &&
18511                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18512                proc.inFullBackup = true;
18513            }
18514            r.app = proc;
18515            oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18516            newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18517            mBackupTarget = r;
18518            mBackupAppName = app.packageName;
18519
18520            // Try not to kill the process during backup
18521            updateOomAdjLocked(proc, true);
18522
18523            // If the process is already attached, schedule the creation of the backup agent now.
18524            // If it is not yet live, this will be done when it attaches to the framework.
18525            if (proc.thread != null) {
18526                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18527                try {
18528                    proc.thread.scheduleCreateBackupAgent(app,
18529                            compatibilityInfoForPackageLocked(app), backupMode);
18530                } catch (RemoteException e) {
18531                    // Will time out on the backup manager side
18532                }
18533            } else {
18534                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18535            }
18536            // Invariants: at this point, the target app process exists and the application
18537            // is either already running or in the process of coming up.  mBackupTarget and
18538            // mBackupAppName describe the app, so that when it binds back to the AM we
18539            // know that it's scheduled for a backup-agent operation.
18540        }
18541
18542        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18543        if (oldBackupUid != -1) {
18544            js.removeBackingUpUid(oldBackupUid);
18545        }
18546        if (newBackupUid != -1) {
18547            js.addBackingUpUid(newBackupUid);
18548        }
18549
18550        return true;
18551    }
18552
18553    @Override
18554    public void clearPendingBackup() {
18555        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18556        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18557
18558        synchronized (this) {
18559            mBackupTarget = null;
18560            mBackupAppName = null;
18561        }
18562
18563        JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18564        js.clearAllBackingUpUids();
18565    }
18566
18567    // A backup agent has just come up
18568    public void backupAgentCreated(String agentPackageName, IBinder agent) {
18569        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18570                + " = " + agent);
18571
18572        synchronized(this) {
18573            if (!agentPackageName.equals(mBackupAppName)) {
18574                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18575                return;
18576            }
18577        }
18578
18579        long oldIdent = Binder.clearCallingIdentity();
18580        try {
18581            IBackupManager bm = IBackupManager.Stub.asInterface(
18582                    ServiceManager.getService(Context.BACKUP_SERVICE));
18583            bm.agentConnected(agentPackageName, agent);
18584        } catch (RemoteException e) {
18585            // can't happen; the backup manager service is local
18586        } catch (Exception e) {
18587            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18588            e.printStackTrace();
18589        } finally {
18590            Binder.restoreCallingIdentity(oldIdent);
18591        }
18592    }
18593
18594    // done with this agent
18595    public void unbindBackupAgent(ApplicationInfo appInfo) {
18596        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18597        if (appInfo == null) {
18598            Slog.w(TAG, "unbind backup agent for null app");
18599            return;
18600        }
18601
18602        int oldBackupUid;
18603
18604        synchronized(this) {
18605            try {
18606                if (mBackupAppName == null) {
18607                    Slog.w(TAG, "Unbinding backup agent with no active backup");
18608                    return;
18609                }
18610
18611                if (!mBackupAppName.equals(appInfo.packageName)) {
18612                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18613                    return;
18614                }
18615
18616                // Not backing this app up any more; reset its OOM adjustment
18617                final ProcessRecord proc = mBackupTarget.app;
18618                updateOomAdjLocked(proc, true);
18619                proc.inFullBackup = false;
18620
18621                oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18622
18623                // If the app crashed during backup, 'thread' will be null here
18624                if (proc.thread != null) {
18625                    try {
18626                        proc.thread.scheduleDestroyBackupAgent(appInfo,
18627                                compatibilityInfoForPackageLocked(appInfo));
18628                    } catch (Exception e) {
18629                        Slog.e(TAG, "Exception when unbinding backup agent:");
18630                        e.printStackTrace();
18631                    }
18632                }
18633            } finally {
18634                mBackupTarget = null;
18635                mBackupAppName = null;
18636            }
18637        }
18638
18639        if (oldBackupUid != -1) {
18640            JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18641            js.removeBackingUpUid(oldBackupUid);
18642        }
18643    }
18644
18645    // =========================================================
18646    // BROADCASTS
18647    // =========================================================
18648
18649    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18650        if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18651            return false;
18652        }
18653        // Easy case -- we have the app's ProcessRecord.
18654        if (record != null) {
18655            return record.info.isInstantApp();
18656        }
18657        // Otherwise check with PackageManager.
18658        if (callerPackage == null) {
18659            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18660            throw new IllegalArgumentException("Calling application did not provide package name");
18661        }
18662        mAppOpsService.checkPackage(uid, callerPackage);
18663        try {
18664            IPackageManager pm = AppGlobals.getPackageManager();
18665            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18666        } catch (RemoteException e) {
18667            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18668            return true;
18669        }
18670    }
18671
18672    boolean isPendingBroadcastProcessLocked(int pid) {
18673        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18674                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18675    }
18676
18677    void skipPendingBroadcastLocked(int pid) {
18678            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18679            for (BroadcastQueue queue : mBroadcastQueues) {
18680                queue.skipPendingBroadcastLocked(pid);
18681            }
18682    }
18683
18684    // The app just attached; send any pending broadcasts that it should receive
18685    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18686        boolean didSomething = false;
18687        for (BroadcastQueue queue : mBroadcastQueues) {
18688            didSomething |= queue.sendPendingBroadcastsLocked(app);
18689        }
18690        return didSomething;
18691    }
18692
18693    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18694            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18695            int flags) {
18696        enforceNotIsolatedCaller("registerReceiver");
18697        ArrayList<Intent> stickyIntents = null;
18698        ProcessRecord callerApp = null;
18699        final boolean visibleToInstantApps
18700                = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18701        int callingUid;
18702        int callingPid;
18703        boolean instantApp;
18704        synchronized(this) {
18705            if (caller != null) {
18706                callerApp = getRecordForAppLocked(caller);
18707                if (callerApp == null) {
18708                    throw new SecurityException(
18709                            "Unable to find app for caller " + caller
18710                            + " (pid=" + Binder.getCallingPid()
18711                            + ") when registering receiver " + receiver);
18712                }
18713                if (callerApp.info.uid != SYSTEM_UID &&
18714                        !callerApp.pkgList.containsKey(callerPackage) &&
18715                        !"android".equals(callerPackage)) {
18716                    throw new SecurityException("Given caller package " + callerPackage
18717                            + " is not running in process " + callerApp);
18718                }
18719                callingUid = callerApp.info.uid;
18720                callingPid = callerApp.pid;
18721            } else {
18722                callerPackage = null;
18723                callingUid = Binder.getCallingUid();
18724                callingPid = Binder.getCallingPid();
18725            }
18726
18727            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18728            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18729                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18730
18731            Iterator<String> actions = filter.actionsIterator();
18732            if (actions == null) {
18733                ArrayList<String> noAction = new ArrayList<String>(1);
18734                noAction.add(null);
18735                actions = noAction.iterator();
18736            }
18737
18738            // Collect stickies of users
18739            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18740            while (actions.hasNext()) {
18741                String action = actions.next();
18742                for (int id : userIds) {
18743                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18744                    if (stickies != null) {
18745                        ArrayList<Intent> intents = stickies.get(action);
18746                        if (intents != null) {
18747                            if (stickyIntents == null) {
18748                                stickyIntents = new ArrayList<Intent>();
18749                            }
18750                            stickyIntents.addAll(intents);
18751                        }
18752                    }
18753                }
18754            }
18755        }
18756
18757        ArrayList<Intent> allSticky = null;
18758        if (stickyIntents != null) {
18759            final ContentResolver resolver = mContext.getContentResolver();
18760            // Look for any matching sticky broadcasts...
18761            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18762                Intent intent = stickyIntents.get(i);
18763                // Don't provided intents that aren't available to instant apps.
18764                if (instantApp &&
18765                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18766                    continue;
18767                }
18768                // If intent has scheme "content", it will need to acccess
18769                // provider that needs to lock mProviderMap in ActivityThread
18770                // and also it may need to wait application response, so we
18771                // cannot lock ActivityManagerService here.
18772                if (filter.match(resolver, intent, true, TAG) >= 0) {
18773                    if (allSticky == null) {
18774                        allSticky = new ArrayList<Intent>();
18775                    }
18776                    allSticky.add(intent);
18777                }
18778            }
18779        }
18780
18781        // The first sticky in the list is returned directly back to the client.
18782        Intent sticky = allSticky != null ? allSticky.get(0) : null;
18783        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18784        if (receiver == null) {
18785            return sticky;
18786        }
18787
18788        synchronized (this) {
18789            if (callerApp != null && (callerApp.thread == null
18790                    || callerApp.thread.asBinder() != caller.asBinder())) {
18791                // Original caller already died
18792                return null;
18793            }
18794            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18795            if (rl == null) {
18796                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18797                        userId, receiver);
18798                if (rl.app != null) {
18799                    rl.app.receivers.add(rl);
18800                } else {
18801                    try {
18802                        receiver.asBinder().linkToDeath(rl, 0);
18803                    } catch (RemoteException e) {
18804                        return sticky;
18805                    }
18806                    rl.linkedToDeath = true;
18807                }
18808                mRegisteredReceivers.put(receiver.asBinder(), rl);
18809            } else if (rl.uid != callingUid) {
18810                throw new IllegalArgumentException(
18811                        "Receiver requested to register for uid " + callingUid
18812                        + " was previously registered for uid " + rl.uid
18813                        + " callerPackage is " + callerPackage);
18814            } else if (rl.pid != callingPid) {
18815                throw new IllegalArgumentException(
18816                        "Receiver requested to register for pid " + callingPid
18817                        + " was previously registered for pid " + rl.pid
18818                        + " callerPackage is " + callerPackage);
18819            } else if (rl.userId != userId) {
18820                throw new IllegalArgumentException(
18821                        "Receiver requested to register for user " + userId
18822                        + " was previously registered for user " + rl.userId
18823                        + " callerPackage is " + callerPackage);
18824            }
18825            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18826                    permission, callingUid, userId, instantApp, visibleToInstantApps);
18827            rl.add(bf);
18828            if (!bf.debugCheck()) {
18829                Slog.w(TAG, "==> For Dynamic broadcast");
18830            }
18831            mReceiverResolver.addFilter(bf);
18832
18833            // Enqueue broadcasts for all existing stickies that match
18834            // this filter.
18835            if (allSticky != null) {
18836                ArrayList receivers = new ArrayList();
18837                receivers.add(bf);
18838
18839                final int stickyCount = allSticky.size();
18840                for (int i = 0; i < stickyCount; i++) {
18841                    Intent intent = allSticky.get(i);
18842                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18843                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18844                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18845                            null, 0, null, null, false, true, true, -1);
18846                    queue.enqueueParallelBroadcastLocked(r);
18847                    queue.scheduleBroadcastsLocked();
18848                }
18849            }
18850
18851            return sticky;
18852        }
18853    }
18854
18855    public void unregisterReceiver(IIntentReceiver receiver) {
18856        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18857
18858        final long origId = Binder.clearCallingIdentity();
18859        try {
18860            boolean doTrim = false;
18861
18862            synchronized(this) {
18863                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18864                if (rl != null) {
18865                    final BroadcastRecord r = rl.curBroadcast;
18866                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18867                        final boolean doNext = r.queue.finishReceiverLocked(
18868                                r, r.resultCode, r.resultData, r.resultExtras,
18869                                r.resultAbort, false);
18870                        if (doNext) {
18871                            doTrim = true;
18872                            r.queue.processNextBroadcast(false);
18873                        }
18874                    }
18875
18876                    if (rl.app != null) {
18877                        rl.app.receivers.remove(rl);
18878                    }
18879                    removeReceiverLocked(rl);
18880                    if (rl.linkedToDeath) {
18881                        rl.linkedToDeath = false;
18882                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18883                    }
18884                }
18885            }
18886
18887            // If we actually concluded any broadcasts, we might now be able
18888            // to trim the recipients' apps from our working set
18889            if (doTrim) {
18890                trimApplications();
18891                return;
18892            }
18893
18894        } finally {
18895            Binder.restoreCallingIdentity(origId);
18896        }
18897    }
18898
18899    void removeReceiverLocked(ReceiverList rl) {
18900        mRegisteredReceivers.remove(rl.receiver.asBinder());
18901        for (int i = rl.size() - 1; i >= 0; i--) {
18902            mReceiverResolver.removeFilter(rl.get(i));
18903        }
18904    }
18905
18906    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18907        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18908            ProcessRecord r = mLruProcesses.get(i);
18909            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18910                try {
18911                    r.thread.dispatchPackageBroadcast(cmd, packages);
18912                } catch (RemoteException ex) {
18913                }
18914            }
18915        }
18916    }
18917
18918    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18919            int callingUid, int[] users) {
18920        // TODO: come back and remove this assumption to triage all broadcasts
18921        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18922
18923        List<ResolveInfo> receivers = null;
18924        try {
18925            HashSet<ComponentName> singleUserReceivers = null;
18926            boolean scannedFirstReceivers = false;
18927            for (int user : users) {
18928                // Skip users that have Shell restrictions, with exception of always permitted
18929                // Shell broadcasts
18930                if (callingUid == SHELL_UID
18931                        && mUserController.hasUserRestriction(
18932                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18933                        && !isPermittedShellBroadcast(intent)) {
18934                    continue;
18935                }
18936                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18937                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18938                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18939                    // If this is not the system user, we need to check for
18940                    // any receivers that should be filtered out.
18941                    for (int i=0; i<newReceivers.size(); i++) {
18942                        ResolveInfo ri = newReceivers.get(i);
18943                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18944                            newReceivers.remove(i);
18945                            i--;
18946                        }
18947                    }
18948                }
18949                if (newReceivers != null && newReceivers.size() == 0) {
18950                    newReceivers = null;
18951                }
18952                if (receivers == null) {
18953                    receivers = newReceivers;
18954                } else if (newReceivers != null) {
18955                    // We need to concatenate the additional receivers
18956                    // found with what we have do far.  This would be easy,
18957                    // but we also need to de-dup any receivers that are
18958                    // singleUser.
18959                    if (!scannedFirstReceivers) {
18960                        // Collect any single user receivers we had already retrieved.
18961                        scannedFirstReceivers = true;
18962                        for (int i=0; i<receivers.size(); i++) {
18963                            ResolveInfo ri = receivers.get(i);
18964                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18965                                ComponentName cn = new ComponentName(
18966                                        ri.activityInfo.packageName, ri.activityInfo.name);
18967                                if (singleUserReceivers == null) {
18968                                    singleUserReceivers = new HashSet<ComponentName>();
18969                                }
18970                                singleUserReceivers.add(cn);
18971                            }
18972                        }
18973                    }
18974                    // Add the new results to the existing results, tracking
18975                    // and de-dupping single user receivers.
18976                    for (int i=0; i<newReceivers.size(); i++) {
18977                        ResolveInfo ri = newReceivers.get(i);
18978                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18979                            ComponentName cn = new ComponentName(
18980                                    ri.activityInfo.packageName, ri.activityInfo.name);
18981                            if (singleUserReceivers == null) {
18982                                singleUserReceivers = new HashSet<ComponentName>();
18983                            }
18984                            if (!singleUserReceivers.contains(cn)) {
18985                                singleUserReceivers.add(cn);
18986                                receivers.add(ri);
18987                            }
18988                        } else {
18989                            receivers.add(ri);
18990                        }
18991                    }
18992                }
18993            }
18994        } catch (RemoteException ex) {
18995            // pm is in same process, this will never happen.
18996        }
18997        return receivers;
18998    }
18999
19000    private boolean isPermittedShellBroadcast(Intent intent) {
19001        // remote bugreport should always be allowed to be taken
19002        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19003    }
19004
19005    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19006            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19007        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19008            // Don't yell about broadcasts sent via shell
19009            return;
19010        }
19011
19012        final String action = intent.getAction();
19013        if (isProtectedBroadcast
19014                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19015                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19016                || Intent.ACTION_MEDIA_BUTTON.equals(action)
19017                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19018                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19019                || Intent.ACTION_MASTER_CLEAR.equals(action)
19020                || Intent.ACTION_FACTORY_RESET.equals(action)
19021                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19022                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19023                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19024                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19025                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19026                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19027                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19028            // Broadcast is either protected, or it's a public action that
19029            // we've relaxed, so it's fine for system internals to send.
19030            return;
19031        }
19032
19033        // This broadcast may be a problem...  but there are often system components that
19034        // want to send an internal broadcast to themselves, which is annoying to have to
19035        // explicitly list each action as a protected broadcast, so we will check for that
19036        // one safe case and allow it: an explicit broadcast, only being received by something
19037        // that has protected itself.
19038        if (receivers != null && receivers.size() > 0
19039                && (intent.getPackage() != null || intent.getComponent() != null)) {
19040            boolean allProtected = true;
19041            for (int i = receivers.size()-1; i >= 0; i--) {
19042                Object target = receivers.get(i);
19043                if (target instanceof ResolveInfo) {
19044                    ResolveInfo ri = (ResolveInfo)target;
19045                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19046                        allProtected = false;
19047                        break;
19048                    }
19049                } else {
19050                    BroadcastFilter bf = (BroadcastFilter)target;
19051                    if (bf.requiredPermission == null) {
19052                        allProtected = false;
19053                        break;
19054                    }
19055                }
19056            }
19057            if (allProtected) {
19058                // All safe!
19059                return;
19060            }
19061        }
19062
19063        // The vast majority of broadcasts sent from system internals
19064        // should be protected to avoid security holes, so yell loudly
19065        // to ensure we examine these cases.
19066        if (callerApp != null) {
19067            Log.wtf(TAG, "Sending non-protected broadcast " + action
19068                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19069                    new Throwable());
19070        } else {
19071            Log.wtf(TAG, "Sending non-protected broadcast " + action
19072                            + " from system uid " + UserHandle.formatUid(callingUid)
19073                            + " pkg " + callerPackage,
19074                    new Throwable());
19075        }
19076    }
19077
19078    final int broadcastIntentLocked(ProcessRecord callerApp,
19079            String callerPackage, Intent intent, String resolvedType,
19080            IIntentReceiver resultTo, int resultCode, String resultData,
19081            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19082            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19083        intent = new Intent(intent);
19084
19085        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19086        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19087        if (callerInstantApp) {
19088            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19089        }
19090
19091        // By default broadcasts do not go to stopped apps.
19092        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19093
19094        // If we have not finished booting, don't allow this to launch new processes.
19095        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19096            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19097        }
19098
19099        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19100                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19101                + " ordered=" + ordered + " userid=" + userId);
19102        if ((resultTo != null) && !ordered) {
19103            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19104        }
19105
19106        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19107                ALLOW_NON_FULL, "broadcast", callerPackage);
19108
19109        // Make sure that the user who is receiving this broadcast is running.
19110        // If not, we will just skip it. Make an exception for shutdown broadcasts
19111        // and upgrade steps.
19112
19113        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19114            if ((callingUid != SYSTEM_UID
19115                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19116                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19117                Slog.w(TAG, "Skipping broadcast of " + intent
19118                        + ": user " + userId + " is stopped");
19119                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19120            }
19121        }
19122
19123        BroadcastOptions brOptions = null;
19124        if (bOptions != null) {
19125            brOptions = new BroadcastOptions(bOptions);
19126            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19127                // See if the caller is allowed to do this.  Note we are checking against
19128                // the actual real caller (not whoever provided the operation as say a
19129                // PendingIntent), because that who is actually supplied the arguments.
19130                if (checkComponentPermission(
19131                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19132                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19133                        != PackageManager.PERMISSION_GRANTED) {
19134                    String msg = "Permission Denial: " + intent.getAction()
19135                            + " broadcast from " + callerPackage + " (pid=" + callingPid
19136                            + ", uid=" + callingUid + ")"
19137                            + " requires "
19138                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19139                    Slog.w(TAG, msg);
19140                    throw new SecurityException(msg);
19141                }
19142            }
19143        }
19144
19145        // Verify that protected broadcasts are only being sent by system code,
19146        // and that system code is only sending protected broadcasts.
19147        final String action = intent.getAction();
19148        final boolean isProtectedBroadcast;
19149        try {
19150            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19151        } catch (RemoteException e) {
19152            Slog.w(TAG, "Remote exception", e);
19153            return ActivityManager.BROADCAST_SUCCESS;
19154        }
19155
19156        final boolean isCallerSystem;
19157        switch (UserHandle.getAppId(callingUid)) {
19158            case ROOT_UID:
19159            case SYSTEM_UID:
19160            case PHONE_UID:
19161            case BLUETOOTH_UID:
19162            case NFC_UID:
19163                isCallerSystem = true;
19164                break;
19165            default:
19166                isCallerSystem = (callerApp != null) && callerApp.persistent;
19167                break;
19168        }
19169
19170        // First line security check before anything else: stop non-system apps from
19171        // sending protected broadcasts.
19172        if (!isCallerSystem) {
19173            if (isProtectedBroadcast) {
19174                String msg = "Permission Denial: not allowed to send broadcast "
19175                        + action + " from pid="
19176                        + callingPid + ", uid=" + callingUid;
19177                Slog.w(TAG, msg);
19178                throw new SecurityException(msg);
19179
19180            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19181                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19182                // Special case for compatibility: we don't want apps to send this,
19183                // but historically it has not been protected and apps may be using it
19184                // to poke their own app widget.  So, instead of making it protected,
19185                // just limit it to the caller.
19186                if (callerPackage == null) {
19187                    String msg = "Permission Denial: not allowed to send broadcast "
19188                            + action + " from unknown caller.";
19189                    Slog.w(TAG, msg);
19190                    throw new SecurityException(msg);
19191                } else if (intent.getComponent() != null) {
19192                    // They are good enough to send to an explicit component...  verify
19193                    // it is being sent to the calling app.
19194                    if (!intent.getComponent().getPackageName().equals(
19195                            callerPackage)) {
19196                        String msg = "Permission Denial: not allowed to send broadcast "
19197                                + action + " to "
19198                                + intent.getComponent().getPackageName() + " from "
19199                                + callerPackage;
19200                        Slog.w(TAG, msg);
19201                        throw new SecurityException(msg);
19202                    }
19203                } else {
19204                    // Limit broadcast to their own package.
19205                    intent.setPackage(callerPackage);
19206                }
19207            }
19208        }
19209
19210        if (action != null) {
19211            if (getBackgroundLaunchBroadcasts().contains(action)) {
19212                if (DEBUG_BACKGROUND_CHECK) {
19213                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19214                }
19215                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19216            }
19217
19218            switch (action) {
19219                case Intent.ACTION_UID_REMOVED:
19220                case Intent.ACTION_PACKAGE_REMOVED:
19221                case Intent.ACTION_PACKAGE_CHANGED:
19222                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19223                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19224                case Intent.ACTION_PACKAGES_SUSPENDED:
19225                case Intent.ACTION_PACKAGES_UNSUSPENDED:
19226                    // Handle special intents: if this broadcast is from the package
19227                    // manager about a package being removed, we need to remove all of
19228                    // its activities from the history stack.
19229                    if (checkComponentPermission(
19230                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19231                            callingPid, callingUid, -1, true)
19232                            != PackageManager.PERMISSION_GRANTED) {
19233                        String msg = "Permission Denial: " + intent.getAction()
19234                                + " broadcast from " + callerPackage + " (pid=" + callingPid
19235                                + ", uid=" + callingUid + ")"
19236                                + " requires "
19237                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19238                        Slog.w(TAG, msg);
19239                        throw new SecurityException(msg);
19240                    }
19241                    switch (action) {
19242                        case Intent.ACTION_UID_REMOVED:
19243                            final int uid = getUidFromIntent(intent);
19244                            if (uid >= 0) {
19245                                mBatteryStatsService.removeUid(uid);
19246                                mAppOpsService.uidRemoved(uid);
19247                            }
19248                            break;
19249                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19250                            // If resources are unavailable just force stop all those packages
19251                            // and flush the attribute cache as well.
19252                            String list[] =
19253                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19254                            if (list != null && list.length > 0) {
19255                                for (int i = 0; i < list.length; i++) {
19256                                    forceStopPackageLocked(list[i], -1, false, true, true,
19257                                            false, false, userId, "storage unmount");
19258                                }
19259                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19260                                sendPackageBroadcastLocked(
19261                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19262                                        list, userId);
19263                            }
19264                            break;
19265                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19266                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19267                            break;
19268                        case Intent.ACTION_PACKAGE_REMOVED:
19269                        case Intent.ACTION_PACKAGE_CHANGED:
19270                            Uri data = intent.getData();
19271                            String ssp;
19272                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19273                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19274                                final boolean replacing =
19275                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19276                                final boolean killProcess =
19277                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19278                                final boolean fullUninstall = removed && !replacing;
19279                                if (removed) {
19280                                    if (killProcess) {
19281                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
19282                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19283                                                false, true, true, false, fullUninstall, userId,
19284                                                removed ? "pkg removed" : "pkg changed");
19285                                    }
19286                                    final int cmd = killProcess
19287                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
19288                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19289                                    sendPackageBroadcastLocked(cmd,
19290                                            new String[] {ssp}, userId);
19291                                    if (fullUninstall) {
19292                                        mAppOpsService.packageRemoved(
19293                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19294
19295                                        // Remove all permissions granted from/to this package
19296                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
19297
19298                                        removeTasksByPackageNameLocked(ssp, userId);
19299
19300                                        mServices.forceStopPackageLocked(ssp, userId);
19301
19302                                        // Hide the "unsupported display" dialog if necessary.
19303                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19304                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19305                                            mUnsupportedDisplaySizeDialog.dismiss();
19306                                            mUnsupportedDisplaySizeDialog = null;
19307                                        }
19308                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
19309                                        mBatteryStatsService.notePackageUninstalled(ssp);
19310                                    }
19311                                } else {
19312                                    if (killProcess) {
19313                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
19314                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
19315                                                userId, ProcessList.INVALID_ADJ,
19316                                                false, true, true, false, "change " + ssp);
19317                                    }
19318                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19319                                            intent.getStringArrayExtra(
19320                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19321                                }
19322                            }
19323                            break;
19324                        case Intent.ACTION_PACKAGES_SUSPENDED:
19325                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
19326                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19327                                    intent.getAction());
19328                            final String[] packageNames = intent.getStringArrayExtra(
19329                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
19330                            final int userHandle = intent.getIntExtra(
19331                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19332
19333                            synchronized(ActivityManagerService.this) {
19334                                mRecentTasks.onPackagesSuspendedChanged(
19335                                        packageNames, suspended, userHandle);
19336                            }
19337                            break;
19338                    }
19339                    break;
19340                case Intent.ACTION_PACKAGE_REPLACED:
19341                {
19342                    final Uri data = intent.getData();
19343                    final String ssp;
19344                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19345                        ApplicationInfo aInfo = null;
19346                        try {
19347                            aInfo = AppGlobals.getPackageManager()
19348                                    .getApplicationInfo(ssp, 0 /*flags*/, userId);
19349                        } catch (RemoteException ignore) {}
19350                        if (aInfo == null) {
19351                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19352                                    + " ssp=" + ssp + " data=" + data);
19353                            return ActivityManager.BROADCAST_SUCCESS;
19354                        }
19355                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19356                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19357                                new String[] {ssp}, userId);
19358                    }
19359                    break;
19360                }
19361                case Intent.ACTION_PACKAGE_ADDED:
19362                {
19363                    // Special case for adding a package: by default turn on compatibility mode.
19364                    Uri data = intent.getData();
19365                    String ssp;
19366                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19367                        final boolean replacing =
19368                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19369                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19370
19371                        try {
19372                            ApplicationInfo ai = AppGlobals.getPackageManager().
19373                                    getApplicationInfo(ssp, 0, 0);
19374                            mBatteryStatsService.notePackageInstalled(ssp,
19375                                    ai != null ? ai.versionCode : 0);
19376                        } catch (RemoteException e) {
19377                        }
19378                    }
19379                    break;
19380                }
19381                case Intent.ACTION_PACKAGE_DATA_CLEARED:
19382                {
19383                    Uri data = intent.getData();
19384                    String ssp;
19385                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19386                        // Hide the "unsupported display" dialog if necessary.
19387                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19388                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19389                            mUnsupportedDisplaySizeDialog.dismiss();
19390                            mUnsupportedDisplaySizeDialog = null;
19391                        }
19392                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
19393                    }
19394                    break;
19395                }
19396                case Intent.ACTION_TIMEZONE_CHANGED:
19397                    // If this is the time zone changed action, queue up a message that will reset
19398                    // the timezone of all currently running processes. This message will get
19399                    // queued up before the broadcast happens.
19400                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19401                    break;
19402                case Intent.ACTION_TIME_CHANGED:
19403                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19404                    // the tri-state value it may contain and "unknown".
19405                    // For convenience we re-use the Intent extra values.
19406                    final int NO_EXTRA_VALUE_FOUND = -1;
19407                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19408                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19409                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
19410                    // Only send a message if the time preference is available.
19411                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19412                        Message updateTimePreferenceMsg =
19413                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19414                                        timeFormatPreferenceMsgValue, 0);
19415                        mHandler.sendMessage(updateTimePreferenceMsg);
19416                    }
19417                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19418                    synchronized (stats) {
19419                        stats.noteCurrentTimeChangedLocked();
19420                    }
19421                    break;
19422                case Intent.ACTION_CLEAR_DNS_CACHE:
19423                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19424                    break;
19425                case Proxy.PROXY_CHANGE_ACTION:
19426                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19427                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19428                    break;
19429                case android.hardware.Camera.ACTION_NEW_PICTURE:
19430                case android.hardware.Camera.ACTION_NEW_VIDEO:
19431                    // In N we just turned these off; in O we are turing them back on partly,
19432                    // only for registered receivers.  This will still address the main problem
19433                    // (a spam of apps waking up when a picture is taken putting significant
19434                    // memory pressure on the system at a bad point), while still allowing apps
19435                    // that are already actively running to know about this happening.
19436                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19437                    break;
19438                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19439                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19440                    break;
19441                case "com.android.launcher.action.INSTALL_SHORTCUT":
19442                    // As of O, we no longer support this broadcasts, even for pre-O apps.
19443                    // Apps should now be using ShortcutManager.pinRequestShortcut().
19444                    Log.w(TAG, "Broadcast " + action
19445                            + " no longer supported. It will not be delivered.");
19446                    return ActivityManager.BROADCAST_SUCCESS;
19447            }
19448
19449            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19450                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19451                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19452                final int uid = getUidFromIntent(intent);
19453                if (uid != -1) {
19454                    final UidRecord uidRec = mActiveUids.get(uid);
19455                    if (uidRec != null) {
19456                        uidRec.updateHasInternetPermission();
19457                    }
19458                }
19459            }
19460        }
19461
19462        // Add to the sticky list if requested.
19463        if (sticky) {
19464            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19465                    callingPid, callingUid)
19466                    != PackageManager.PERMISSION_GRANTED) {
19467                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19468                        + callingPid + ", uid=" + callingUid
19469                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19470                Slog.w(TAG, msg);
19471                throw new SecurityException(msg);
19472            }
19473            if (requiredPermissions != null && requiredPermissions.length > 0) {
19474                Slog.w(TAG, "Can't broadcast sticky intent " + intent
19475                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
19476                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19477            }
19478            if (intent.getComponent() != null) {
19479                throw new SecurityException(
19480                        "Sticky broadcasts can't target a specific component");
19481            }
19482            // We use userId directly here, since the "all" target is maintained
19483            // as a separate set of sticky broadcasts.
19484            if (userId != UserHandle.USER_ALL) {
19485                // But first, if this is not a broadcast to all users, then
19486                // make sure it doesn't conflict with an existing broadcast to
19487                // all users.
19488                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19489                        UserHandle.USER_ALL);
19490                if (stickies != null) {
19491                    ArrayList<Intent> list = stickies.get(intent.getAction());
19492                    if (list != null) {
19493                        int N = list.size();
19494                        int i;
19495                        for (i=0; i<N; i++) {
19496                            if (intent.filterEquals(list.get(i))) {
19497                                throw new IllegalArgumentException(
19498                                        "Sticky broadcast " + intent + " for user "
19499                                        + userId + " conflicts with existing global broadcast");
19500                            }
19501                        }
19502                    }
19503                }
19504            }
19505            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19506            if (stickies == null) {
19507                stickies = new ArrayMap<>();
19508                mStickyBroadcasts.put(userId, stickies);
19509            }
19510            ArrayList<Intent> list = stickies.get(intent.getAction());
19511            if (list == null) {
19512                list = new ArrayList<>();
19513                stickies.put(intent.getAction(), list);
19514            }
19515            final int stickiesCount = list.size();
19516            int i;
19517            for (i = 0; i < stickiesCount; i++) {
19518                if (intent.filterEquals(list.get(i))) {
19519                    // This sticky already exists, replace it.
19520                    list.set(i, new Intent(intent));
19521                    break;
19522                }
19523            }
19524            if (i >= stickiesCount) {
19525                list.add(new Intent(intent));
19526            }
19527        }
19528
19529        int[] users;
19530        if (userId == UserHandle.USER_ALL) {
19531            // Caller wants broadcast to go to all started users.
19532            users = mUserController.getStartedUserArrayLocked();
19533        } else {
19534            // Caller wants broadcast to go to one specific user.
19535            users = new int[] {userId};
19536        }
19537
19538        // Figure out who all will receive this broadcast.
19539        List receivers = null;
19540        List<BroadcastFilter> registeredReceivers = null;
19541        // Need to resolve the intent to interested receivers...
19542        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19543                 == 0) {
19544            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19545        }
19546        if (intent.getComponent() == null) {
19547            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19548                // Query one target user at a time, excluding shell-restricted users
19549                for (int i = 0; i < users.length; i++) {
19550                    if (mUserController.hasUserRestriction(
19551                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19552                        continue;
19553                    }
19554                    List<BroadcastFilter> registeredReceiversForUser =
19555                            mReceiverResolver.queryIntent(intent,
19556                                    resolvedType, false /*defaultOnly*/, users[i]);
19557                    if (registeredReceivers == null) {
19558                        registeredReceivers = registeredReceiversForUser;
19559                    } else if (registeredReceiversForUser != null) {
19560                        registeredReceivers.addAll(registeredReceiversForUser);
19561                    }
19562                }
19563            } else {
19564                registeredReceivers = mReceiverResolver.queryIntent(intent,
19565                        resolvedType, false /*defaultOnly*/, userId);
19566            }
19567        }
19568
19569        final boolean replacePending =
19570                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19571
19572        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19573                + " replacePending=" + replacePending);
19574
19575        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19576        if (!ordered && NR > 0) {
19577            // If we are not serializing this broadcast, then send the
19578            // registered receivers separately so they don't wait for the
19579            // components to be launched.
19580            if (isCallerSystem) {
19581                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19582                        isProtectedBroadcast, registeredReceivers);
19583            }
19584            final BroadcastQueue queue = broadcastQueueForIntent(intent);
19585            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19586                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19587                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19588                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19589            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19590            final boolean replaced = replacePending
19591                    && (queue.replaceParallelBroadcastLocked(r) != null);
19592            // Note: We assume resultTo is null for non-ordered broadcasts.
19593            if (!replaced) {
19594                queue.enqueueParallelBroadcastLocked(r);
19595                queue.scheduleBroadcastsLocked();
19596            }
19597            registeredReceivers = null;
19598            NR = 0;
19599        }
19600
19601        // Merge into one list.
19602        int ir = 0;
19603        if (receivers != null) {
19604            // A special case for PACKAGE_ADDED: do not allow the package
19605            // being added to see this broadcast.  This prevents them from
19606            // using this as a back door to get run as soon as they are
19607            // installed.  Maybe in the future we want to have a special install
19608            // broadcast or such for apps, but we'd like to deliberately make
19609            // this decision.
19610            String skipPackages[] = null;
19611            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19612                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19613                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19614                Uri data = intent.getData();
19615                if (data != null) {
19616                    String pkgName = data.getSchemeSpecificPart();
19617                    if (pkgName != null) {
19618                        skipPackages = new String[] { pkgName };
19619                    }
19620                }
19621            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19622                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19623            }
19624            if (skipPackages != null && (skipPackages.length > 0)) {
19625                for (String skipPackage : skipPackages) {
19626                    if (skipPackage != null) {
19627                        int NT = receivers.size();
19628                        for (int it=0; it<NT; it++) {
19629                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
19630                            if (curt.activityInfo.packageName.equals(skipPackage)) {
19631                                receivers.remove(it);
19632                                it--;
19633                                NT--;
19634                            }
19635                        }
19636                    }
19637                }
19638            }
19639
19640            int NT = receivers != null ? receivers.size() : 0;
19641            int it = 0;
19642            ResolveInfo curt = null;
19643            BroadcastFilter curr = null;
19644            while (it < NT && ir < NR) {
19645                if (curt == null) {
19646                    curt = (ResolveInfo)receivers.get(it);
19647                }
19648                if (curr == null) {
19649                    curr = registeredReceivers.get(ir);
19650                }
19651                if (curr.getPriority() >= curt.priority) {
19652                    // Insert this broadcast record into the final list.
19653                    receivers.add(it, curr);
19654                    ir++;
19655                    curr = null;
19656                    it++;
19657                    NT++;
19658                } else {
19659                    // Skip to the next ResolveInfo in the final list.
19660                    it++;
19661                    curt = null;
19662                }
19663            }
19664        }
19665        while (ir < NR) {
19666            if (receivers == null) {
19667                receivers = new ArrayList();
19668            }
19669            receivers.add(registeredReceivers.get(ir));
19670            ir++;
19671        }
19672
19673        if (isCallerSystem) {
19674            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19675                    isProtectedBroadcast, receivers);
19676        }
19677
19678        if ((receivers != null && receivers.size() > 0)
19679                || resultTo != null) {
19680            BroadcastQueue queue = broadcastQueueForIntent(intent);
19681            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19682                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19683                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19684                    resultData, resultExtras, ordered, sticky, false, userId);
19685
19686            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19687                    + ": prev had " + queue.mOrderedBroadcasts.size());
19688            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19689                    "Enqueueing broadcast " + r.intent.getAction());
19690
19691            final BroadcastRecord oldRecord =
19692                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19693            if (oldRecord != null) {
19694                // Replaced, fire the result-to receiver.
19695                if (oldRecord.resultTo != null) {
19696                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19697                    try {
19698                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19699                                oldRecord.intent,
19700                                Activity.RESULT_CANCELED, null, null,
19701                                false, false, oldRecord.userId);
19702                    } catch (RemoteException e) {
19703                        Slog.w(TAG, "Failure ["
19704                                + queue.mQueueName + "] sending broadcast result of "
19705                                + intent, e);
19706
19707                    }
19708                }
19709            } else {
19710                queue.enqueueOrderedBroadcastLocked(r);
19711                queue.scheduleBroadcastsLocked();
19712            }
19713        } else {
19714            // There was nobody interested in the broadcast, but we still want to record
19715            // that it happened.
19716            if (intent.getComponent() == null && intent.getPackage() == null
19717                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19718                // This was an implicit broadcast... let's record it for posterity.
19719                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19720            }
19721        }
19722
19723        return ActivityManager.BROADCAST_SUCCESS;
19724    }
19725
19726    /**
19727     * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19728     */
19729    private int getUidFromIntent(Intent intent) {
19730        if (intent == null) {
19731            return -1;
19732        }
19733        final Bundle intentExtras = intent.getExtras();
19734        return intent.hasExtra(Intent.EXTRA_UID)
19735                ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19736    }
19737
19738    final void rotateBroadcastStatsIfNeededLocked() {
19739        final long now = SystemClock.elapsedRealtime();
19740        if (mCurBroadcastStats == null ||
19741                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19742            mLastBroadcastStats = mCurBroadcastStats;
19743            if (mLastBroadcastStats != null) {
19744                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19745                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19746            }
19747            mCurBroadcastStats = new BroadcastStats();
19748        }
19749    }
19750
19751    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19752            int skipCount, long dispatchTime) {
19753        rotateBroadcastStatsIfNeededLocked();
19754        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19755    }
19756
19757    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19758        rotateBroadcastStatsIfNeededLocked();
19759        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19760    }
19761
19762    final Intent verifyBroadcastLocked(Intent intent) {
19763        // Refuse possible leaked file descriptors
19764        if (intent != null && intent.hasFileDescriptors() == true) {
19765            throw new IllegalArgumentException("File descriptors passed in Intent");
19766        }
19767
19768        int flags = intent.getFlags();
19769
19770        if (!mProcessesReady) {
19771            // if the caller really truly claims to know what they're doing, go
19772            // ahead and allow the broadcast without launching any receivers
19773            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19774                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19775            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19776                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19777                        + " before boot completion");
19778                throw new IllegalStateException("Cannot broadcast before boot completed");
19779            }
19780        }
19781
19782        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19783            throw new IllegalArgumentException(
19784                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19785        }
19786
19787        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19788            switch (Binder.getCallingUid()) {
19789                case ROOT_UID:
19790                case SHELL_UID:
19791                    break;
19792                default:
19793                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19794                            + Binder.getCallingUid());
19795                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19796                    break;
19797            }
19798        }
19799
19800        return intent;
19801    }
19802
19803    public final int broadcastIntent(IApplicationThread caller,
19804            Intent intent, String resolvedType, IIntentReceiver resultTo,
19805            int resultCode, String resultData, Bundle resultExtras,
19806            String[] requiredPermissions, int appOp, Bundle bOptions,
19807            boolean serialized, boolean sticky, int userId) {
19808        enforceNotIsolatedCaller("broadcastIntent");
19809        synchronized(this) {
19810            intent = verifyBroadcastLocked(intent);
19811
19812            final ProcessRecord callerApp = getRecordForAppLocked(caller);
19813            final int callingPid = Binder.getCallingPid();
19814            final int callingUid = Binder.getCallingUid();
19815            final long origId = Binder.clearCallingIdentity();
19816            int res = broadcastIntentLocked(callerApp,
19817                    callerApp != null ? callerApp.info.packageName : null,
19818                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19819                    requiredPermissions, appOp, bOptions, serialized, sticky,
19820                    callingPid, callingUid, userId);
19821            Binder.restoreCallingIdentity(origId);
19822            return res;
19823        }
19824    }
19825
19826
19827    int broadcastIntentInPackage(String packageName, int uid,
19828            Intent intent, String resolvedType, IIntentReceiver resultTo,
19829            int resultCode, String resultData, Bundle resultExtras,
19830            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19831            int userId) {
19832        synchronized(this) {
19833            intent = verifyBroadcastLocked(intent);
19834
19835            final long origId = Binder.clearCallingIdentity();
19836            String[] requiredPermissions = requiredPermission == null ? null
19837                    : new String[] {requiredPermission};
19838            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19839                    resultTo, resultCode, resultData, resultExtras,
19840                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19841                    sticky, -1, uid, userId);
19842            Binder.restoreCallingIdentity(origId);
19843            return res;
19844        }
19845    }
19846
19847    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19848        // Refuse possible leaked file descriptors
19849        if (intent != null && intent.hasFileDescriptors() == true) {
19850            throw new IllegalArgumentException("File descriptors passed in Intent");
19851        }
19852
19853        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19854                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19855
19856        synchronized(this) {
19857            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19858                    != PackageManager.PERMISSION_GRANTED) {
19859                String msg = "Permission Denial: unbroadcastIntent() from pid="
19860                        + Binder.getCallingPid()
19861                        + ", uid=" + Binder.getCallingUid()
19862                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19863                Slog.w(TAG, msg);
19864                throw new SecurityException(msg);
19865            }
19866            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19867            if (stickies != null) {
19868                ArrayList<Intent> list = stickies.get(intent.getAction());
19869                if (list != null) {
19870                    int N = list.size();
19871                    int i;
19872                    for (i=0; i<N; i++) {
19873                        if (intent.filterEquals(list.get(i))) {
19874                            list.remove(i);
19875                            break;
19876                        }
19877                    }
19878                    if (list.size() <= 0) {
19879                        stickies.remove(intent.getAction());
19880                    }
19881                }
19882                if (stickies.size() <= 0) {
19883                    mStickyBroadcasts.remove(userId);
19884                }
19885            }
19886        }
19887    }
19888
19889    void backgroundServicesFinishedLocked(int userId) {
19890        for (BroadcastQueue queue : mBroadcastQueues) {
19891            queue.backgroundServicesFinishedLocked(userId);
19892        }
19893    }
19894
19895    public void finishReceiver(IBinder who, int resultCode, String resultData,
19896            Bundle resultExtras, boolean resultAbort, int flags) {
19897        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19898
19899        // Refuse possible leaked file descriptors
19900        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19901            throw new IllegalArgumentException("File descriptors passed in Bundle");
19902        }
19903
19904        final long origId = Binder.clearCallingIdentity();
19905        try {
19906            boolean doNext = false;
19907            BroadcastRecord r;
19908
19909            synchronized(this) {
19910                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19911                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19912                r = queue.getMatchingOrderedReceiver(who);
19913                if (r != null) {
19914                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19915                        resultData, resultExtras, resultAbort, true);
19916                }
19917            }
19918
19919            if (doNext) {
19920                r.queue.processNextBroadcast(false);
19921            }
19922            trimApplications();
19923        } finally {
19924            Binder.restoreCallingIdentity(origId);
19925        }
19926    }
19927
19928    // =========================================================
19929    // INSTRUMENTATION
19930    // =========================================================
19931
19932    public boolean startInstrumentation(ComponentName className,
19933            String profileFile, int flags, Bundle arguments,
19934            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19935            int userId, String abiOverride) {
19936        enforceNotIsolatedCaller("startInstrumentation");
19937        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19938                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19939        // Refuse possible leaked file descriptors
19940        if (arguments != null && arguments.hasFileDescriptors()) {
19941            throw new IllegalArgumentException("File descriptors passed in Bundle");
19942        }
19943
19944        synchronized(this) {
19945            InstrumentationInfo ii = null;
19946            ApplicationInfo ai = null;
19947            try {
19948                ii = mContext.getPackageManager().getInstrumentationInfo(
19949                    className, STOCK_PM_FLAGS);
19950                ai = AppGlobals.getPackageManager().getApplicationInfo(
19951                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19952            } catch (PackageManager.NameNotFoundException e) {
19953            } catch (RemoteException e) {
19954            }
19955            if (ii == null) {
19956                reportStartInstrumentationFailureLocked(watcher, className,
19957                        "Unable to find instrumentation info for: " + className);
19958                return false;
19959            }
19960            if (ai == null) {
19961                reportStartInstrumentationFailureLocked(watcher, className,
19962                        "Unable to find instrumentation target package: " + ii.targetPackage);
19963                return false;
19964            }
19965            if (!ai.hasCode()) {
19966                reportStartInstrumentationFailureLocked(watcher, className,
19967                        "Instrumentation target has no code: " + ii.targetPackage);
19968                return false;
19969            }
19970
19971            int match = mContext.getPackageManager().checkSignatures(
19972                    ii.targetPackage, ii.packageName);
19973            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19974                String msg = "Permission Denial: starting instrumentation "
19975                        + className + " from pid="
19976                        + Binder.getCallingPid()
19977                        + ", uid=" + Binder.getCallingPid()
19978                        + " not allowed because package " + ii.packageName
19979                        + " does not have a signature matching the target "
19980                        + ii.targetPackage;
19981                reportStartInstrumentationFailureLocked(watcher, className, msg);
19982                throw new SecurityException(msg);
19983            }
19984
19985            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19986            activeInstr.mClass = className;
19987            String defProcess = ai.processName;;
19988            if (ii.targetProcesses == null) {
19989                activeInstr.mTargetProcesses = new String[]{ai.processName};
19990            } else if (ii.targetProcesses.equals("*")) {
19991                activeInstr.mTargetProcesses = new String[0];
19992            } else {
19993                activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
19994                defProcess = activeInstr.mTargetProcesses[0];
19995            }
19996            activeInstr.mTargetInfo = ai;
19997            activeInstr.mProfileFile = profileFile;
19998            activeInstr.mArguments = arguments;
19999            activeInstr.mWatcher = watcher;
20000            activeInstr.mUiAutomationConnection = uiAutomationConnection;
20001            activeInstr.mResultClass = className;
20002
20003            final long origId = Binder.clearCallingIdentity();
20004            // Instrumentation can kill and relaunch even persistent processes
20005            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20006                    "start instr");
20007            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20008            app.instr = activeInstr;
20009            activeInstr.mFinished = false;
20010            activeInstr.mRunningProcesses.add(app);
20011            if (!mActiveInstrumentation.contains(activeInstr)) {
20012                mActiveInstrumentation.add(activeInstr);
20013            }
20014            Binder.restoreCallingIdentity(origId);
20015        }
20016
20017        return true;
20018    }
20019
20020    /**
20021     * Report errors that occur while attempting to start Instrumentation.  Always writes the
20022     * error to the logs, but if somebody is watching, send the report there too.  This enables
20023     * the "am" command to report errors with more information.
20024     *
20025     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
20026     * @param cn The component name of the instrumentation.
20027     * @param report The error report.
20028     */
20029    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20030            ComponentName cn, String report) {
20031        Slog.w(TAG, report);
20032        if (watcher != null) {
20033            Bundle results = new Bundle();
20034            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20035            results.putString("Error", report);
20036            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20037        }
20038    }
20039
20040    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20041        if (app.instr == null) {
20042            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20043            return;
20044        }
20045
20046        if (!app.instr.mFinished && results != null) {
20047            if (app.instr.mCurResults == null) {
20048                app.instr.mCurResults = new Bundle(results);
20049            } else {
20050                app.instr.mCurResults.putAll(results);
20051            }
20052        }
20053    }
20054
20055    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20056        int userId = UserHandle.getCallingUserId();
20057        // Refuse possible leaked file descriptors
20058        if (results != null && results.hasFileDescriptors()) {
20059            throw new IllegalArgumentException("File descriptors passed in Intent");
20060        }
20061
20062        synchronized(this) {
20063            ProcessRecord app = getRecordForAppLocked(target);
20064            if (app == null) {
20065                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20066                return;
20067            }
20068            final long origId = Binder.clearCallingIdentity();
20069            addInstrumentationResultsLocked(app, results);
20070            Binder.restoreCallingIdentity(origId);
20071        }
20072    }
20073
20074    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20075        if (app.instr == null) {
20076            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20077            return;
20078        }
20079
20080        if (!app.instr.mFinished) {
20081            if (app.instr.mWatcher != null) {
20082                Bundle finalResults = app.instr.mCurResults;
20083                if (finalResults != null) {
20084                    if (app.instr.mCurResults != null && results != null) {
20085                        finalResults.putAll(results);
20086                    }
20087                } else {
20088                    finalResults = results;
20089                }
20090                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20091                        app.instr.mClass, resultCode, finalResults);
20092            }
20093
20094            // Can't call out of the system process with a lock held, so post a message.
20095            if (app.instr.mUiAutomationConnection != null) {
20096                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20097                        app.instr.mUiAutomationConnection).sendToTarget();
20098            }
20099            app.instr.mFinished = true;
20100        }
20101
20102        app.instr.removeProcess(app);
20103        app.instr = null;
20104
20105        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20106                "finished inst");
20107    }
20108
20109    public void finishInstrumentation(IApplicationThread target,
20110            int resultCode, Bundle results) {
20111        int userId = UserHandle.getCallingUserId();
20112        // Refuse possible leaked file descriptors
20113        if (results != null && results.hasFileDescriptors()) {
20114            throw new IllegalArgumentException("File descriptors passed in Intent");
20115        }
20116
20117        synchronized(this) {
20118            ProcessRecord app = getRecordForAppLocked(target);
20119            if (app == null) {
20120                Slog.w(TAG, "finishInstrumentation: no app for " + target);
20121                return;
20122            }
20123            final long origId = Binder.clearCallingIdentity();
20124            finishInstrumentationLocked(app, resultCode, results);
20125            Binder.restoreCallingIdentity(origId);
20126        }
20127    }
20128
20129    // =========================================================
20130    // CONFIGURATION
20131    // =========================================================
20132
20133    public ConfigurationInfo getDeviceConfigurationInfo() {
20134        ConfigurationInfo config = new ConfigurationInfo();
20135        synchronized (this) {
20136            final Configuration globalConfig = getGlobalConfiguration();
20137            config.reqTouchScreen = globalConfig.touchscreen;
20138            config.reqKeyboardType = globalConfig.keyboard;
20139            config.reqNavigation = globalConfig.navigation;
20140            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20141                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20142                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20143            }
20144            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20145                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20146                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20147            }
20148            config.reqGlEsVersion = GL_ES_VERSION;
20149        }
20150        return config;
20151    }
20152
20153    ActivityStack getFocusedStack() {
20154        return mStackSupervisor.getFocusedStack();
20155    }
20156
20157    @Override
20158    public int getFocusedStackId() throws RemoteException {
20159        ActivityStack focusedStack = getFocusedStack();
20160        if (focusedStack != null) {
20161            return focusedStack.getStackId();
20162        }
20163        return -1;
20164    }
20165
20166    public Configuration getConfiguration() {
20167        Configuration ci;
20168        synchronized(this) {
20169            ci = new Configuration(getGlobalConfiguration());
20170            ci.userSetLocale = false;
20171        }
20172        return ci;
20173    }
20174
20175    @Override
20176    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20177        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20178        synchronized (this) {
20179            mSuppressResizeConfigChanges = suppress;
20180        }
20181    }
20182
20183    /**
20184     * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20185     *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20186     *       activity and clearing the task at the same time.
20187     */
20188    @Override
20189    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20190        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20191        if (StackId.isHomeOrRecentsStack(fromStackId)) {
20192            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20193        }
20194        synchronized (this) {
20195            final long origId = Binder.clearCallingIdentity();
20196            try {
20197                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20198            } finally {
20199                Binder.restoreCallingIdentity(origId);
20200            }
20201        }
20202    }
20203
20204    @Override
20205    public void updatePersistentConfiguration(Configuration values) {
20206        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20207        enforceWriteSettingsPermission("updatePersistentConfiguration()");
20208        if (values == null) {
20209            throw new NullPointerException("Configuration must not be null");
20210        }
20211
20212        int userId = UserHandle.getCallingUserId();
20213
20214        synchronized(this) {
20215            updatePersistentConfigurationLocked(values, userId);
20216        }
20217    }
20218
20219    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20220        final long origId = Binder.clearCallingIdentity();
20221        try {
20222            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20223        } finally {
20224            Binder.restoreCallingIdentity(origId);
20225        }
20226    }
20227
20228    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20229        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20230                FONT_SCALE, 1.0f, userId);
20231
20232        synchronized (this) {
20233            if (getGlobalConfiguration().fontScale == scaleFactor) {
20234                return;
20235            }
20236
20237            final Configuration configuration
20238                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20239            configuration.fontScale = scaleFactor;
20240            updatePersistentConfigurationLocked(configuration, userId);
20241        }
20242    }
20243
20244    private void enforceWriteSettingsPermission(String func) {
20245        int uid = Binder.getCallingUid();
20246        if (uid == ROOT_UID) {
20247            return;
20248        }
20249
20250        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20251                Settings.getPackageNameForUid(mContext, uid), false)) {
20252            return;
20253        }
20254
20255        String msg = "Permission Denial: " + func + " from pid="
20256                + Binder.getCallingPid()
20257                + ", uid=" + uid
20258                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20259        Slog.w(TAG, msg);
20260        throw new SecurityException(msg);
20261    }
20262
20263    @Override
20264    public boolean updateConfiguration(Configuration values) {
20265        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20266
20267        synchronized(this) {
20268            if (values == null && mWindowManager != null) {
20269                // sentinel: fetch the current configuration from the window manager
20270                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20271            }
20272
20273            if (mWindowManager != null) {
20274                // Update OOM levels based on display size.
20275                mProcessList.applyDisplaySize(mWindowManager);
20276            }
20277
20278            final long origId = Binder.clearCallingIdentity();
20279            try {
20280                if (values != null) {
20281                    Settings.System.clearConfiguration(values);
20282                }
20283                updateConfigurationLocked(values, null, false, false /* persistent */,
20284                        UserHandle.USER_NULL, false /* deferResume */,
20285                        mTmpUpdateConfigurationResult);
20286                return mTmpUpdateConfigurationResult.changes != 0;
20287            } finally {
20288                Binder.restoreCallingIdentity(origId);
20289            }
20290        }
20291    }
20292
20293    void updateUserConfigurationLocked() {
20294        final Configuration configuration = new Configuration(getGlobalConfiguration());
20295        final int currentUserId = mUserController.getCurrentUserIdLocked();
20296        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20297                currentUserId, Settings.System.canWrite(mContext));
20298        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20299                false /* persistent */, currentUserId, false /* deferResume */);
20300    }
20301
20302    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20303            boolean initLocale) {
20304        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20305    }
20306
20307    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20308            boolean initLocale, boolean deferResume) {
20309        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20310        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20311                UserHandle.USER_NULL, deferResume);
20312    }
20313
20314    // To cache the list of supported system locales
20315    private String[] mSupportedSystemLocales = null;
20316
20317    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20318            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20319        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20320                deferResume, null /* result */);
20321    }
20322
20323    /**
20324     * Do either or both things: (1) change the current configuration, and (2)
20325     * make sure the given activity is running with the (now) current
20326     * configuration.  Returns true if the activity has been left running, or
20327     * false if <var>starting</var> is being destroyed to match the new
20328     * configuration.
20329     *
20330     * @param userId is only used when persistent parameter is set to true to persist configuration
20331     *               for that particular user
20332     */
20333    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20334            boolean initLocale, boolean persistent, int userId, boolean deferResume,
20335            UpdateConfigurationResult result) {
20336        int changes = 0;
20337        boolean kept = true;
20338
20339        if (mWindowManager != null) {
20340            mWindowManager.deferSurfaceLayout();
20341        }
20342        try {
20343            if (values != null) {
20344                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20345                        deferResume);
20346            }
20347
20348            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20349        } finally {
20350            if (mWindowManager != null) {
20351                mWindowManager.continueSurfaceLayout();
20352            }
20353        }
20354
20355        if (result != null) {
20356            result.changes = changes;
20357            result.activityRelaunched = !kept;
20358        }
20359        return kept;
20360    }
20361
20362    /** Update default (global) configuration and notify listeners about changes. */
20363    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20364            boolean persistent, int userId, boolean deferResume) {
20365        mTempConfig.setTo(getGlobalConfiguration());
20366        final int changes = mTempConfig.updateFrom(values);
20367        if (changes == 0) {
20368            // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20369            // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20370            // performDisplayOverrideConfigUpdate in order to send the new display configuration
20371            // (even if there are no actual changes) to unfreeze the window.
20372            performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20373            return 0;
20374        }
20375
20376        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20377                "Updating global configuration to: " + values);
20378
20379        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20380
20381        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20382            final LocaleList locales = values.getLocales();
20383            int bestLocaleIndex = 0;
20384            if (locales.size() > 1) {
20385                if (mSupportedSystemLocales == null) {
20386                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20387                }
20388                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20389            }
20390            SystemProperties.set("persist.sys.locale",
20391                    locales.get(bestLocaleIndex).toLanguageTag());
20392            LocaleList.setDefault(locales, bestLocaleIndex);
20393            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20394                    locales.get(bestLocaleIndex)));
20395        }
20396
20397        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20398        mTempConfig.seq = mConfigurationSeq;
20399
20400        // Update stored global config and notify everyone about the change.
20401        mStackSupervisor.onConfigurationChanged(mTempConfig);
20402
20403        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20404        // TODO(multi-display): Update UsageEvents#Event to include displayId.
20405        mUsageStatsService.reportConfigurationChange(mTempConfig,
20406                mUserController.getCurrentUserIdLocked());
20407
20408        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20409        mShowDialogs = shouldShowDialogs(mTempConfig);
20410
20411        AttributeCache ac = AttributeCache.instance();
20412        if (ac != null) {
20413            ac.updateConfiguration(mTempConfig);
20414        }
20415
20416        // Make sure all resources in our process are updated right now, so that anyone who is going
20417        // to retrieve resource values after we return will be sure to get the new ones. This is
20418        // especially important during boot, where the first config change needs to guarantee all
20419        // resources have that config before following boot code is executed.
20420        mSystemThread.applyConfigurationToResources(mTempConfig);
20421
20422        // We need another copy of global config because we're scheduling some calls instead of
20423        // running them in place. We need to be sure that object we send will be handled unchanged.
20424        final Configuration configCopy = new Configuration(mTempConfig);
20425        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20426            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20427            msg.obj = configCopy;
20428            msg.arg1 = userId;
20429            mHandler.sendMessage(msg);
20430        }
20431
20432        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20433            ProcessRecord app = mLruProcesses.get(i);
20434            try {
20435                if (app.thread != null) {
20436                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20437                            + app.processName + " new config " + configCopy);
20438                    app.thread.scheduleConfigurationChanged(configCopy);
20439                }
20440            } catch (Exception e) {
20441            }
20442        }
20443
20444        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20445        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20446                | Intent.FLAG_RECEIVER_FOREGROUND
20447                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20448        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20449                AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20450                UserHandle.USER_ALL);
20451        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20452            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20453            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20454                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20455                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20456            if (initLocale || !mProcessesReady) {
20457                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20458            }
20459            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20460                    AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20461                    UserHandle.USER_ALL);
20462        }
20463
20464        // Override configuration of the default display duplicates global config, so we need to
20465        // update it also. This will also notify WindowManager about changes.
20466        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20467                DEFAULT_DISPLAY);
20468
20469        return changes;
20470    }
20471
20472    @Override
20473    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20474        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20475
20476        synchronized (this) {
20477            // Check if display is initialized in AM.
20478            if (!mStackSupervisor.isDisplayAdded(displayId)) {
20479                // Call might come when display is not yet added or has already been removed.
20480                if (DEBUG_CONFIGURATION) {
20481                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20482                            + displayId);
20483                }
20484                return false;
20485            }
20486
20487            if (values == null && mWindowManager != null) {
20488                // sentinel: fetch the current configuration from the window manager
20489                values = mWindowManager.computeNewConfiguration(displayId);
20490            }
20491
20492            if (mWindowManager != null) {
20493                // Update OOM levels based on display size.
20494                mProcessList.applyDisplaySize(mWindowManager);
20495            }
20496
20497            final long origId = Binder.clearCallingIdentity();
20498            try {
20499                if (values != null) {
20500                    Settings.System.clearConfiguration(values);
20501                }
20502                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20503                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20504                return mTmpUpdateConfigurationResult.changes != 0;
20505            } finally {
20506                Binder.restoreCallingIdentity(origId);
20507            }
20508        }
20509    }
20510
20511    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20512            boolean deferResume, int displayId) {
20513        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20514                displayId, null /* result */);
20515    }
20516
20517    /**
20518     * Updates override configuration specific for the selected display. If no config is provided,
20519     * new one will be computed in WM based on current display info.
20520     */
20521    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20522            ActivityRecord starting, boolean deferResume, int displayId,
20523            UpdateConfigurationResult result) {
20524        int changes = 0;
20525        boolean kept = true;
20526
20527        if (mWindowManager != null) {
20528            mWindowManager.deferSurfaceLayout();
20529        }
20530        try {
20531            if (values != null) {
20532                if (displayId == DEFAULT_DISPLAY) {
20533                    // Override configuration of the default display duplicates global config, so
20534                    // we're calling global config update instead for default display. It will also
20535                    // apply the correct override config.
20536                    changes = updateGlobalConfiguration(values, false /* initLocale */,
20537                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20538                } else {
20539                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20540                }
20541            }
20542
20543            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20544        } finally {
20545            if (mWindowManager != null) {
20546                mWindowManager.continueSurfaceLayout();
20547            }
20548        }
20549
20550        if (result != null) {
20551            result.changes = changes;
20552            result.activityRelaunched = !kept;
20553        }
20554        return kept;
20555    }
20556
20557    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20558            int displayId) {
20559        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20560        final int changes = mTempConfig.updateFrom(values);
20561        if (changes != 0) {
20562            Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20563                    + mTempConfig + " for displayId=" + displayId);
20564            mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20565
20566            final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20567            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20568                // Reset the unsupported display size dialog.
20569                mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20570
20571                killAllBackgroundProcessesExcept(N,
20572                        ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20573            }
20574        }
20575
20576        // Update the configuration with WM first and check if any of the stacks need to be resized
20577        // due to the configuration change. If so, resize the stacks now and do any relaunches if
20578        // necessary. This way we don't need to relaunch again afterwards in
20579        // ensureActivityConfigurationLocked().
20580        if (mWindowManager != null) {
20581            final int[] resizedStacks =
20582                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20583            if (resizedStacks != null) {
20584                for (int stackId : resizedStacks) {
20585                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20586                }
20587            }
20588        }
20589
20590        return changes;
20591    }
20592
20593    /** Applies latest configuration and/or visibility updates if needed. */
20594    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20595        boolean kept = true;
20596        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20597        // mainStack is null during startup.
20598        if (mainStack != null) {
20599            if (changes != 0 && starting == null) {
20600                // If the configuration changed, and the caller is not already
20601                // in the process of starting an activity, then find the top
20602                // activity to check if its configuration needs to change.
20603                starting = mainStack.topRunningActivityLocked();
20604            }
20605
20606            if (starting != null) {
20607                kept = starting.ensureActivityConfigurationLocked(changes,
20608                        false /* preserveWindow */);
20609                // And we need to make sure at this point that all other activities
20610                // are made visible with the correct configuration.
20611                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20612                        !PRESERVE_WINDOWS);
20613            }
20614        }
20615
20616        return kept;
20617    }
20618
20619    /** Helper method that requests bounds from WM and applies them to stack. */
20620    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20621        final Rect newStackBounds = new Rect();
20622        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20623        mStackSupervisor.resizeStackLocked(
20624                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20625                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20626                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20627    }
20628
20629    /**
20630     * Decide based on the configuration whether we should show the ANR,
20631     * crash, etc dialogs.  The idea is that if there is no affordance to
20632     * press the on-screen buttons, or the user experience would be more
20633     * greatly impacted than the crash itself, we shouldn't show the dialog.
20634     *
20635     * A thought: SystemUI might also want to get told about this, the Power
20636     * dialog / global actions also might want different behaviors.
20637     */
20638    private static boolean shouldShowDialogs(Configuration config) {
20639        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20640                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20641                                   && config.navigation == Configuration.NAVIGATION_NONAV);
20642        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20643        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20644                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20645                && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20646                && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20647        return inputMethodExists && uiModeSupportsDialogs;
20648    }
20649
20650    @Override
20651    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20652        synchronized (this) {
20653            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20654            if (srec != null) {
20655                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20656            }
20657        }
20658        return false;
20659    }
20660
20661    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20662            Intent resultData) {
20663
20664        synchronized (this) {
20665            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20666            if (r != null) {
20667                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20668            }
20669            return false;
20670        }
20671    }
20672
20673    public int getLaunchedFromUid(IBinder activityToken) {
20674        ActivityRecord srec;
20675        synchronized (this) {
20676            srec = ActivityRecord.forTokenLocked(activityToken);
20677        }
20678        if (srec == null) {
20679            return -1;
20680        }
20681        return srec.launchedFromUid;
20682    }
20683
20684    public String getLaunchedFromPackage(IBinder activityToken) {
20685        ActivityRecord srec;
20686        synchronized (this) {
20687            srec = ActivityRecord.forTokenLocked(activityToken);
20688        }
20689        if (srec == null) {
20690            return null;
20691        }
20692        return srec.launchedFromPackage;
20693    }
20694
20695    // =========================================================
20696    // LIFETIME MANAGEMENT
20697    // =========================================================
20698
20699    // Returns whether the app is receiving broadcast.
20700    // If receiving, fetch all broadcast queues which the app is
20701    // the current [or imminent] receiver on.
20702    private boolean isReceivingBroadcastLocked(ProcessRecord app,
20703            ArraySet<BroadcastQueue> receivingQueues) {
20704        if (!app.curReceivers.isEmpty()) {
20705            for (BroadcastRecord r : app.curReceivers) {
20706                receivingQueues.add(r.queue);
20707            }
20708            return true;
20709        }
20710
20711        // It's not the current receiver, but it might be starting up to become one
20712        for (BroadcastQueue queue : mBroadcastQueues) {
20713            final BroadcastRecord r = queue.mPendingBroadcast;
20714            if (r != null && r.curApp == app) {
20715                // found it; report which queue it's in
20716                receivingQueues.add(queue);
20717            }
20718        }
20719
20720        return !receivingQueues.isEmpty();
20721    }
20722
20723    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20724            int targetUid, ComponentName targetComponent, String targetProcess) {
20725        if (!mTrackingAssociations) {
20726            return null;
20727        }
20728        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20729                = mAssociations.get(targetUid);
20730        if (components == null) {
20731            components = new ArrayMap<>();
20732            mAssociations.put(targetUid, components);
20733        }
20734        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20735        if (sourceUids == null) {
20736            sourceUids = new SparseArray<>();
20737            components.put(targetComponent, sourceUids);
20738        }
20739        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20740        if (sourceProcesses == null) {
20741            sourceProcesses = new ArrayMap<>();
20742            sourceUids.put(sourceUid, sourceProcesses);
20743        }
20744        Association ass = sourceProcesses.get(sourceProcess);
20745        if (ass == null) {
20746            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20747                    targetProcess);
20748            sourceProcesses.put(sourceProcess, ass);
20749        }
20750        ass.mCount++;
20751        ass.mNesting++;
20752        if (ass.mNesting == 1) {
20753            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20754            ass.mLastState = sourceState;
20755        }
20756        return ass;
20757    }
20758
20759    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20760            ComponentName targetComponent) {
20761        if (!mTrackingAssociations) {
20762            return;
20763        }
20764        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20765                = mAssociations.get(targetUid);
20766        if (components == null) {
20767            return;
20768        }
20769        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20770        if (sourceUids == null) {
20771            return;
20772        }
20773        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20774        if (sourceProcesses == null) {
20775            return;
20776        }
20777        Association ass = sourceProcesses.get(sourceProcess);
20778        if (ass == null || ass.mNesting <= 0) {
20779            return;
20780        }
20781        ass.mNesting--;
20782        if (ass.mNesting == 0) {
20783            long uptime = SystemClock.uptimeMillis();
20784            ass.mTime += uptime - ass.mStartTime;
20785            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20786                    += uptime - ass.mLastStateUptime;
20787            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20788        }
20789    }
20790
20791    private void noteUidProcessState(final int uid, final int state) {
20792        mBatteryStatsService.noteUidProcessState(uid, state);
20793        if (mTrackingAssociations) {
20794            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20795                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20796                        = mAssociations.valueAt(i1);
20797                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20798                    SparseArray<ArrayMap<String, Association>> sourceUids
20799                            = targetComponents.valueAt(i2);
20800                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20801                    if (sourceProcesses != null) {
20802                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20803                            Association ass = sourceProcesses.valueAt(i4);
20804                            if (ass.mNesting >= 1) {
20805                                // currently associated
20806                                long uptime = SystemClock.uptimeMillis();
20807                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20808                                        += uptime - ass.mLastStateUptime;
20809                                ass.mLastState = state;
20810                                ass.mLastStateUptime = uptime;
20811                            }
20812                        }
20813                    }
20814                }
20815            }
20816        }
20817    }
20818
20819    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20820            boolean doingAll, long now) {
20821        if (mAdjSeq == app.adjSeq) {
20822            // This adjustment has already been computed.
20823            return app.curRawAdj;
20824        }
20825
20826        if (app.thread == null) {
20827            app.adjSeq = mAdjSeq;
20828            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20829            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20830            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20831        }
20832
20833        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20834        app.adjSource = null;
20835        app.adjTarget = null;
20836        app.empty = false;
20837        app.cached = false;
20838
20839        final int activitiesSize = app.activities.size();
20840
20841        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20842            // The max adjustment doesn't allow this app to be anything
20843            // below foreground, so it is not worth doing work for it.
20844            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20845            app.adjType = "fixed";
20846            app.adjSeq = mAdjSeq;
20847            app.curRawAdj = app.maxAdj;
20848            app.foregroundActivities = false;
20849            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20850            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20851            // System processes can do UI, and when they do we want to have
20852            // them trim their memory after the user leaves the UI.  To
20853            // facilitate this, here we need to determine whether or not it
20854            // is currently showing UI.
20855            app.systemNoUi = true;
20856            if (app == TOP_APP) {
20857                app.systemNoUi = false;
20858                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20859                app.adjType = "pers-top-activity";
20860            } else if (app.hasTopUi) {
20861                app.systemNoUi = false;
20862                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20863                app.adjType = "pers-top-ui";
20864            } else if (activitiesSize > 0) {
20865                for (int j = 0; j < activitiesSize; j++) {
20866                    final ActivityRecord r = app.activities.get(j);
20867                    if (r.visible) {
20868                        app.systemNoUi = false;
20869                    }
20870                }
20871            }
20872            if (!app.systemNoUi) {
20873                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20874            }
20875            return (app.curAdj=app.maxAdj);
20876        }
20877
20878        app.systemNoUi = false;
20879
20880        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20881
20882        // Determine the importance of the process, starting with most
20883        // important to least, and assign an appropriate OOM adjustment.
20884        int adj;
20885        int schedGroup;
20886        int procState;
20887        boolean foregroundActivities = false;
20888        mTmpBroadcastQueue.clear();
20889        if (app == TOP_APP) {
20890            // The last app on the list is the foreground app.
20891            adj = ProcessList.FOREGROUND_APP_ADJ;
20892            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20893            app.adjType = "top-activity";
20894            foregroundActivities = true;
20895            procState = PROCESS_STATE_CUR_TOP;
20896            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20897        } else if (app.instr != null) {
20898            // Don't want to kill running instrumentation.
20899            adj = ProcessList.FOREGROUND_APP_ADJ;
20900            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20901            app.adjType = "instrumentation";
20902            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20903            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20904        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20905            // An app that is currently receiving a broadcast also
20906            // counts as being in the foreground for OOM killer purposes.
20907            // It's placed in a sched group based on the nature of the
20908            // broadcast as reflected by which queue it's active in.
20909            adj = ProcessList.FOREGROUND_APP_ADJ;
20910            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20911                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20912            app.adjType = "broadcast";
20913            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20914            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20915        } else if (app.executingServices.size() > 0) {
20916            // An app that is currently executing a service callback also
20917            // counts as being in the foreground.
20918            adj = ProcessList.FOREGROUND_APP_ADJ;
20919            schedGroup = app.execServicesFg ?
20920                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20921            app.adjType = "exec-service";
20922            procState = ActivityManager.PROCESS_STATE_SERVICE;
20923            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20924            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20925        } else {
20926            // As far as we know the process is empty.  We may change our mind later.
20927            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20928            // At this point we don't actually know the adjustment.  Use the cached adj
20929            // value that the caller wants us to.
20930            adj = cachedAdj;
20931            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20932            app.cached = true;
20933            app.empty = true;
20934            app.adjType = "cch-empty";
20935            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20936        }
20937
20938        // Examine all activities if not already foreground.
20939        if (!foregroundActivities && activitiesSize > 0) {
20940            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20941            for (int j = 0; j < activitiesSize; j++) {
20942                final ActivityRecord r = app.activities.get(j);
20943                if (r.app != app) {
20944                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20945                            + " instead of expected " + app);
20946                    if (r.app == null || (r.app.uid == app.uid)) {
20947                        // Only fix things up when they look sane
20948                        r.app = app;
20949                    } else {
20950                        continue;
20951                    }
20952                }
20953                if (r.visible) {
20954                    // App has a visible activity; only upgrade adjustment.
20955                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20956                        adj = ProcessList.VISIBLE_APP_ADJ;
20957                        app.adjType = "vis-activity";
20958                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20959                    }
20960                    if (procState > PROCESS_STATE_CUR_TOP) {
20961                        procState = PROCESS_STATE_CUR_TOP;
20962                        app.adjType = "vis-activity";
20963                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20964                    }
20965                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20966                    app.cached = false;
20967                    app.empty = false;
20968                    foregroundActivities = true;
20969                    final TaskRecord task = r.getTask();
20970                    if (task != null && minLayer > 0) {
20971                        final int layer = task.mLayerRank;
20972                        if (layer >= 0 && minLayer > layer) {
20973                            minLayer = layer;
20974                        }
20975                    }
20976                    break;
20977                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20978                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20979                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20980                        app.adjType = "pause-activity";
20981                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20982                    }
20983                    if (procState > PROCESS_STATE_CUR_TOP) {
20984                        procState = PROCESS_STATE_CUR_TOP;
20985                        app.adjType = "pause-activity";
20986                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
20987                    }
20988                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20989                    app.cached = false;
20990                    app.empty = false;
20991                    foregroundActivities = true;
20992                } else if (r.state == ActivityState.STOPPING) {
20993                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20994                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20995                        app.adjType = "stop-activity";
20996                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
20997                    }
20998                    // For the process state, we will at this point consider the
20999                    // process to be cached.  It will be cached either as an activity
21000                    // or empty depending on whether the activity is finishing.  We do
21001                    // this so that we can treat the process as cached for purposes of
21002                    // memory trimming (determing current memory level, trim command to
21003                    // send to process) since there can be an arbitrary number of stopping
21004                    // processes and they should soon all go into the cached state.
21005                    if (!r.finishing) {
21006                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21007                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21008                            app.adjType = "stop-activity";
21009                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21010                        }
21011                    }
21012                    app.cached = false;
21013                    app.empty = false;
21014                    foregroundActivities = true;
21015                } else {
21016                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21017                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21018                        app.adjType = "cch-act";
21019                        if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21020                    }
21021                }
21022            }
21023            if (adj == ProcessList.VISIBLE_APP_ADJ) {
21024                adj += minLayer;
21025            }
21026        }
21027
21028        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21029                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21030            if (app.foregroundServices) {
21031                // The user is aware of this app, so make it visible.
21032                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21033                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21034                app.cached = false;
21035                app.adjType = "fg-service";
21036                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21037                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21038            } else if (app.hasOverlayUi) {
21039                // The process is display an overlay UI.
21040                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21041                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21042                app.cached = false;
21043                app.adjType = "has-overlay-ui";
21044                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21045                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21046            }
21047        }
21048
21049        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21050                || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21051            if (app.forcingToImportant != null) {
21052                // This is currently used for toasts...  they are not interactive, and
21053                // we don't want them to cause the app to become fully foreground (and
21054                // thus out of background check), so we yes the best background level we can.
21055                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21056                procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21057                app.cached = false;
21058                app.adjType = "force-imp";
21059                app.adjSource = app.forcingToImportant;
21060                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21061                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21062            }
21063        }
21064
21065        if (app == mHeavyWeightProcess) {
21066            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21067                // We don't want to kill the current heavy-weight process.
21068                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21069                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21070                app.cached = false;
21071                app.adjType = "heavy";
21072                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21073            }
21074            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21075                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21076                app.adjType = "heavy";
21077                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21078            }
21079        }
21080
21081        if (app == mHomeProcess) {
21082            if (adj > ProcessList.HOME_APP_ADJ) {
21083                // This process is hosting what we currently consider to be the
21084                // home app, so we don't want to let it go into the background.
21085                adj = ProcessList.HOME_APP_ADJ;
21086                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21087                app.cached = false;
21088                app.adjType = "home";
21089                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21090            }
21091            if (procState > ActivityManager.PROCESS_STATE_HOME) {
21092                procState = ActivityManager.PROCESS_STATE_HOME;
21093                app.adjType = "home";
21094                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21095            }
21096        }
21097
21098        if (app == mPreviousProcess && app.activities.size() > 0) {
21099            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21100                // This was the previous process that showed UI to the user.
21101                // We want to try to keep it around more aggressively, to give
21102                // a good experience around switching between two apps.
21103                adj = ProcessList.PREVIOUS_APP_ADJ;
21104                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21105                app.cached = false;
21106                app.adjType = "previous";
21107                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21108            }
21109            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21110                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21111                app.adjType = "previous";
21112                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21113            }
21114        }
21115
21116        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21117                + " reason=" + app.adjType);
21118
21119        // By default, we use the computed adjustment.  It may be changed if
21120        // there are applications dependent on our services or providers, but
21121        // this gives us a baseline and makes sure we don't get into an
21122        // infinite recursion.
21123        app.adjSeq = mAdjSeq;
21124        app.curRawAdj = adj;
21125        app.hasStartedServices = false;
21126
21127        if (mBackupTarget != null && app == mBackupTarget.app) {
21128            // If possible we want to avoid killing apps while they're being backed up
21129            if (adj > ProcessList.BACKUP_APP_ADJ) {
21130                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21131                adj = ProcessList.BACKUP_APP_ADJ;
21132                if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21133                    procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21134                }
21135                app.adjType = "backup";
21136                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21137                app.cached = false;
21138            }
21139            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21140                procState = ActivityManager.PROCESS_STATE_BACKUP;
21141                app.adjType = "backup";
21142                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21143            }
21144        }
21145
21146        boolean mayBeTop = false;
21147        String mayBeTopType = null;
21148        Object mayBeTopSource = null;
21149        Object mayBeTopTarget = null;
21150
21151        for (int is = app.services.size()-1;
21152                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21153                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21154                        || procState > ActivityManager.PROCESS_STATE_TOP);
21155                is--) {
21156            ServiceRecord s = app.services.valueAt(is);
21157            if (s.startRequested) {
21158                app.hasStartedServices = true;
21159                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21160                    procState = ActivityManager.PROCESS_STATE_SERVICE;
21161                    app.adjType = "started-services";
21162                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21163                }
21164                if (app.hasShownUi && app != mHomeProcess) {
21165                    // If this process has shown some UI, let it immediately
21166                    // go to the LRU list because it may be pretty heavy with
21167                    // UI stuff.  We'll tag it with a label just to help
21168                    // debug and understand what is going on.
21169                    if (adj > ProcessList.SERVICE_ADJ) {
21170                        app.adjType = "cch-started-ui-services";
21171                    }
21172                } else {
21173                    if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21174                        // This service has seen some activity within
21175                        // recent memory, so we will keep its process ahead
21176                        // of the background processes.
21177                        if (adj > ProcessList.SERVICE_ADJ) {
21178                            adj = ProcessList.SERVICE_ADJ;
21179                            app.adjType = "started-services";
21180                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21181                            app.cached = false;
21182                        }
21183                    }
21184                    // If we have let the service slide into the background
21185                    // state, still have some text describing what it is doing
21186                    // even though the service no longer has an impact.
21187                    if (adj > ProcessList.SERVICE_ADJ) {
21188                        app.adjType = "cch-started-services";
21189                    }
21190                }
21191            }
21192
21193            for (int conni = s.connections.size()-1;
21194                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21195                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21196                            || procState > ActivityManager.PROCESS_STATE_TOP);
21197                    conni--) {
21198                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21199                for (int i = 0;
21200                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21201                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21202                                || procState > ActivityManager.PROCESS_STATE_TOP);
21203                        i++) {
21204                    // XXX should compute this based on the max of
21205                    // all connected clients.
21206                    ConnectionRecord cr = clist.get(i);
21207                    if (cr.binding.client == app) {
21208                        // Binding to ourself is not interesting.
21209                        continue;
21210                    }
21211
21212                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21213                        ProcessRecord client = cr.binding.client;
21214                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
21215                                TOP_APP, doingAll, now);
21216                        int clientProcState = client.curProcState;
21217                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21218                            // If the other app is cached for any reason, for purposes here
21219                            // we are going to consider it empty.  The specific cached state
21220                            // doesn't propagate except under certain conditions.
21221                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21222                        }
21223                        String adjType = null;
21224                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21225                            // Not doing bind OOM management, so treat
21226                            // this guy more like a started service.
21227                            if (app.hasShownUi && app != mHomeProcess) {
21228                                // If this process has shown some UI, let it immediately
21229                                // go to the LRU list because it may be pretty heavy with
21230                                // UI stuff.  We'll tag it with a label just to help
21231                                // debug and understand what is going on.
21232                                if (adj > clientAdj) {
21233                                    adjType = "cch-bound-ui-services";
21234                                }
21235                                app.cached = false;
21236                                clientAdj = adj;
21237                                clientProcState = procState;
21238                            } else {
21239                                if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21240                                    // This service has not seen activity within
21241                                    // recent memory, so allow it to drop to the
21242                                    // LRU list if there is no other reason to keep
21243                                    // it around.  We'll also tag it with a label just
21244                                    // to help debug and undertand what is going on.
21245                                    if (adj > clientAdj) {
21246                                        adjType = "cch-bound-services";
21247                                    }
21248                                    clientAdj = adj;
21249                                }
21250                            }
21251                        }
21252                        if (adj > clientAdj) {
21253                            // If this process has recently shown UI, and
21254                            // the process that is binding to it is less
21255                            // important than being visible, then we don't
21256                            // care about the binding as much as we care
21257                            // about letting this process get into the LRU
21258                            // list to be killed and restarted if needed for
21259                            // memory.
21260                            if (app.hasShownUi && app != mHomeProcess
21261                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21262                                if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21263                                    adjType = "cch-bound-ui-services";
21264                                }
21265                            } else {
21266                                int newAdj;
21267                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21268                                        |Context.BIND_IMPORTANT)) != 0) {
21269                                    newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21270                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21271                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21272                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21273                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21274                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21275                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21276                                    newAdj = clientAdj;
21277                                } else {
21278                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
21279                                        newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21280                                    } else {
21281                                        newAdj = adj;
21282                                    }
21283                                }
21284                                if (!client.cached) {
21285                                    app.cached = false;
21286                                }
21287                                if (adj >  newAdj) {
21288                                    adj = newAdj;
21289                                    adjType = "service";
21290                                }
21291                            }
21292                        }
21293                        if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21294                                | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21295                            // This will treat important bound services identically to
21296                            // the top app, which may behave differently than generic
21297                            // foreground work.
21298                            if (client.curSchedGroup > schedGroup) {
21299                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21300                                    schedGroup = client.curSchedGroup;
21301                                } else {
21302                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21303                                }
21304                            }
21305                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21306                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21307                                    // Special handling of clients who are in the top state.
21308                                    // We *may* want to consider this process to be in the
21309                                    // top state as well, but only if there is not another
21310                                    // reason for it to be running.  Being on the top is a
21311                                    // special state, meaning you are specifically running
21312                                    // for the current top app.  If the process is already
21313                                    // running in the background for some other reason, it
21314                                    // is more important to continue considering it to be
21315                                    // in the background state.
21316                                    mayBeTop = true;
21317                                    mayBeTopType = "service";
21318                                    mayBeTopSource = cr.binding.client;
21319                                    mayBeTopTarget = s.name;
21320                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21321                                } else {
21322                                    // Special handling for above-top states (persistent
21323                                    // processes).  These should not bring the current process
21324                                    // into the top state, since they are not on top.  Instead
21325                                    // give them the best state after that.
21326                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21327                                        clientProcState =
21328                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21329                                    } else if (mWakefulness
21330                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21331                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21332                                                    != 0) {
21333                                        clientProcState =
21334                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21335                                    } else {
21336                                        clientProcState =
21337                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21338                                    }
21339                                }
21340                            }
21341                        } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21342                            if (clientProcState <
21343                                    ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21344                                clientProcState =
21345                                        ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21346                            }
21347                        } else {
21348                            if (clientProcState <
21349                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21350                                clientProcState =
21351                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21352                            }
21353                        }
21354                        if (procState > clientProcState) {
21355                            procState = clientProcState;
21356                            if (adjType == null) {
21357                                adjType = "service";
21358                            }
21359                        }
21360                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21361                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21362                            app.pendingUiClean = true;
21363                        }
21364                        if (adjType != null) {
21365                            app.adjType = adjType;
21366                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21367                                    .REASON_SERVICE_IN_USE;
21368                            app.adjSource = cr.binding.client;
21369                            app.adjSourceProcState = clientProcState;
21370                            app.adjTarget = s.name;
21371                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21372                                    + ": " + app + ", due to " + cr.binding.client
21373                                    + " adj=" + adj + " procState=" + procState);
21374                        }
21375                    }
21376                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21377                        app.treatLikeActivity = true;
21378                    }
21379                    final ActivityRecord a = cr.activity;
21380                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21381                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21382                            (a.visible || a.state == ActivityState.RESUMED ||
21383                             a.state == ActivityState.PAUSING)) {
21384                            adj = ProcessList.FOREGROUND_APP_ADJ;
21385                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21386                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21387                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21388                                } else {
21389                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21390                                }
21391                            }
21392                            app.cached = false;
21393                            app.adjType = "service";
21394                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21395                                    .REASON_SERVICE_IN_USE;
21396                            app.adjSource = a;
21397                            app.adjSourceProcState = procState;
21398                            app.adjTarget = s.name;
21399                            if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21400                                    + app);
21401                        }
21402                    }
21403                }
21404            }
21405        }
21406
21407        for (int provi = app.pubProviders.size()-1;
21408                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21409                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21410                        || procState > ActivityManager.PROCESS_STATE_TOP);
21411                provi--) {
21412            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21413            for (int i = cpr.connections.size()-1;
21414                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21415                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21416                            || procState > ActivityManager.PROCESS_STATE_TOP);
21417                    i--) {
21418                ContentProviderConnection conn = cpr.connections.get(i);
21419                ProcessRecord client = conn.client;
21420                if (client == app) {
21421                    // Being our own client is not interesting.
21422                    continue;
21423                }
21424                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21425                int clientProcState = client.curProcState;
21426                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21427                    // If the other app is cached for any reason, for purposes here
21428                    // we are going to consider it empty.
21429                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21430                }
21431                String adjType = null;
21432                if (adj > clientAdj) {
21433                    if (app.hasShownUi && app != mHomeProcess
21434                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21435                        adjType = "cch-ui-provider";
21436                    } else {
21437                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21438                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21439                        adjType = "provider";
21440                    }
21441                    app.cached &= client.cached;
21442                }
21443                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21444                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21445                        // Special handling of clients who are in the top state.
21446                        // We *may* want to consider this process to be in the
21447                        // top state as well, but only if there is not another
21448                        // reason for it to be running.  Being on the top is a
21449                        // special state, meaning you are specifically running
21450                        // for the current top app.  If the process is already
21451                        // running in the background for some other reason, it
21452                        // is more important to continue considering it to be
21453                        // in the background state.
21454                        mayBeTop = true;
21455                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21456                        mayBeTopType = adjType = "provider-top";
21457                        mayBeTopSource = client;
21458                        mayBeTopTarget = cpr.name;
21459                    } else {
21460                        // Special handling for above-top states (persistent
21461                        // processes).  These should not bring the current process
21462                        // into the top state, since they are not on top.  Instead
21463                        // give them the best state after that.
21464                        clientProcState =
21465                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21466                        if (adjType == null) {
21467                            adjType = "provider";
21468                        }
21469                    }
21470                }
21471                if (procState > clientProcState) {
21472                    procState = clientProcState;
21473                }
21474                if (client.curSchedGroup > schedGroup) {
21475                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21476                }
21477                if (adjType != null) {
21478                    app.adjType = adjType;
21479                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21480                            .REASON_PROVIDER_IN_USE;
21481                    app.adjSource = client;
21482                    app.adjSourceProcState = clientProcState;
21483                    app.adjTarget = cpr.name;
21484                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21485                            + ": " + app + ", due to " + client
21486                            + " adj=" + adj + " procState=" + procState);
21487                }
21488            }
21489            // If the provider has external (non-framework) process
21490            // dependencies, ensure that its adjustment is at least
21491            // FOREGROUND_APP_ADJ.
21492            if (cpr.hasExternalProcessHandles()) {
21493                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21494                    adj = ProcessList.FOREGROUND_APP_ADJ;
21495                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21496                    app.cached = false;
21497                    app.adjType = "ext-provider";
21498                    app.adjTarget = cpr.name;
21499                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21500                }
21501                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21502                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21503                }
21504            }
21505        }
21506
21507        if (app.lastProviderTime > 0 &&
21508                (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21509            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21510                adj = ProcessList.PREVIOUS_APP_ADJ;
21511                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21512                app.cached = false;
21513                app.adjType = "recent-provider";
21514                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21515            }
21516            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21517                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21518                app.adjType = "recent-provider";
21519                if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21520            }
21521        }
21522
21523        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21524            // A client of one of our services or providers is in the top state.  We
21525            // *may* want to be in the top state, but not if we are already running in
21526            // the background for some other reason.  For the decision here, we are going
21527            // to pick out a few specific states that we want to remain in when a client
21528            // is top (states that tend to be longer-term) and otherwise allow it to go
21529            // to the top state.
21530            switch (procState) {
21531                case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21532                    // Something else is keeping it at this level, just leave it.
21533                    break;
21534                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21535                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21536                case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21537                case ActivityManager.PROCESS_STATE_SERVICE:
21538                    // These all are longer-term states, so pull them up to the top
21539                    // of the background states, but not all the way to the top state.
21540                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21541                    app.adjType = mayBeTopType;
21542                    app.adjSource = mayBeTopSource;
21543                    app.adjTarget = mayBeTopTarget;
21544                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21545                            + ": " + app + ", due to " + mayBeTopSource
21546                            + " adj=" + adj + " procState=" + procState);
21547                    break;
21548                default:
21549                    // Otherwise, top is a better choice, so take it.
21550                    procState = ActivityManager.PROCESS_STATE_TOP;
21551                    app.adjType = mayBeTopType;
21552                    app.adjSource = mayBeTopSource;
21553                    app.adjTarget = mayBeTopTarget;
21554                    if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21555                            + ": " + app + ", due to " + mayBeTopSource
21556                            + " adj=" + adj + " procState=" + procState);
21557                    break;
21558            }
21559        }
21560
21561        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21562            if (app.hasClientActivities) {
21563                // This is a cached process, but with client activities.  Mark it so.
21564                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21565                app.adjType = "cch-client-act";
21566            } else if (app.treatLikeActivity) {
21567                // This is a cached process, but somebody wants us to treat it like it has
21568                // an activity, okay!
21569                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21570                app.adjType = "cch-as-act";
21571            }
21572        }
21573
21574        if (adj == ProcessList.SERVICE_ADJ) {
21575            if (doingAll) {
21576                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21577                mNewNumServiceProcs++;
21578                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21579                if (!app.serviceb) {
21580                    // This service isn't far enough down on the LRU list to
21581                    // normally be a B service, but if we are low on RAM and it
21582                    // is large we want to force it down since we would prefer to
21583                    // keep launcher over it.
21584                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21585                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21586                        app.serviceHighRam = true;
21587                        app.serviceb = true;
21588                        //Slog.i(TAG, "ADJ " + app + " high ram!");
21589                    } else {
21590                        mNewNumAServiceProcs++;
21591                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
21592                    }
21593                } else {
21594                    app.serviceHighRam = false;
21595                }
21596            }
21597            if (app.serviceb) {
21598                adj = ProcessList.SERVICE_B_ADJ;
21599            }
21600        }
21601
21602        app.curRawAdj = adj;
21603
21604        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21605        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21606        if (adj > app.maxAdj) {
21607            adj = app.maxAdj;
21608            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21609                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21610            }
21611        }
21612
21613        // Do final modification to adj.  Everything we do between here and applying
21614        // the final setAdj must be done in this function, because we will also use
21615        // it when computing the final cached adj later.  Note that we don't need to
21616        // worry about this for max adj above, since max adj will always be used to
21617        // keep it out of the cached vaues.
21618        app.curAdj = app.modifyRawOomAdj(adj);
21619        app.curSchedGroup = schedGroup;
21620        app.curProcState = procState;
21621        app.foregroundActivities = foregroundActivities;
21622
21623        return app.curRawAdj;
21624    }
21625
21626    /**
21627     * Record new PSS sample for a process.
21628     */
21629    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21630            long now) {
21631        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21632                swapPss * 1024);
21633        proc.lastPssTime = now;
21634        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21635        if (DEBUG_PSS) Slog.d(TAG_PSS,
21636                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21637                + " state=" + ProcessList.makeProcStateString(procState));
21638        if (proc.initialIdlePss == 0) {
21639            proc.initialIdlePss = pss;
21640        }
21641        proc.lastPss = pss;
21642        proc.lastSwapPss = swapPss;
21643        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21644            proc.lastCachedPss = pss;
21645            proc.lastCachedSwapPss = swapPss;
21646        }
21647
21648        final SparseArray<Pair<Long, String>> watchUids
21649                = mMemWatchProcesses.getMap().get(proc.processName);
21650        Long check = null;
21651        if (watchUids != null) {
21652            Pair<Long, String> val = watchUids.get(proc.uid);
21653            if (val == null) {
21654                val = watchUids.get(0);
21655            }
21656            if (val != null) {
21657                check = val.first;
21658            }
21659        }
21660        if (check != null) {
21661            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21662                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21663                if (!isDebuggable) {
21664                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21665                        isDebuggable = true;
21666                    }
21667                }
21668                if (isDebuggable) {
21669                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21670                    final ProcessRecord myProc = proc;
21671                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
21672                    mMemWatchDumpProcName = proc.processName;
21673                    mMemWatchDumpFile = heapdumpFile.toString();
21674                    mMemWatchDumpPid = proc.pid;
21675                    mMemWatchDumpUid = proc.uid;
21676                    BackgroundThread.getHandler().post(new Runnable() {
21677                        @Override
21678                        public void run() {
21679                            revokeUriPermission(ActivityThread.currentActivityThread()
21680                                            .getApplicationThread(),
21681                                    null, DumpHeapActivity.JAVA_URI,
21682                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
21683                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21684                                    UserHandle.myUserId());
21685                            ParcelFileDescriptor fd = null;
21686                            try {
21687                                heapdumpFile.delete();
21688                                fd = ParcelFileDescriptor.open(heapdumpFile,
21689                                        ParcelFileDescriptor.MODE_CREATE |
21690                                                ParcelFileDescriptor.MODE_TRUNCATE |
21691                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
21692                                                ParcelFileDescriptor.MODE_APPEND);
21693                                IApplicationThread thread = myProc.thread;
21694                                if (thread != null) {
21695                                    try {
21696                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
21697                                                "Requesting dump heap from "
21698                                                + myProc + " to " + heapdumpFile);
21699                                        thread.dumpHeap(/* managed= */ true,
21700                                                /* mallocInfo= */ false, /* runGc= */ false,
21701                                                heapdumpFile.toString(), fd);
21702                                    } catch (RemoteException e) {
21703                                    }
21704                                }
21705                            } catch (FileNotFoundException e) {
21706                                e.printStackTrace();
21707                            } finally {
21708                                if (fd != null) {
21709                                    try {
21710                                        fd.close();
21711                                    } catch (IOException e) {
21712                                    }
21713                                }
21714                            }
21715                        }
21716                    });
21717                } else {
21718                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21719                            + ", but debugging not enabled");
21720                }
21721            }
21722        }
21723    }
21724
21725    /**
21726     * Schedule PSS collection of a process.
21727     */
21728    void requestPssLocked(ProcessRecord proc, int procState) {
21729        if (mPendingPssProcesses.contains(proc)) {
21730            return;
21731        }
21732        if (mPendingPssProcesses.size() == 0) {
21733            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21734        }
21735        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21736        proc.pssProcState = procState;
21737        mPendingPssProcesses.add(proc);
21738    }
21739
21740    /**
21741     * Schedule PSS collection of all processes.
21742     */
21743    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21744        if (!always) {
21745            if (now < (mLastFullPssTime +
21746                    (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21747                            : mConstants.FULL_PSS_MIN_INTERVAL))) {
21748                return;
21749            }
21750        }
21751        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21752        mLastFullPssTime = now;
21753        mFullPssPending = true;
21754        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21755        mPendingPssProcesses.clear();
21756        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21757            ProcessRecord app = mLruProcesses.get(i);
21758            if (app.thread == null
21759                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21760                continue;
21761            }
21762            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21763                app.pssProcState = app.setProcState;
21764                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21765                        mTestPssMode, isSleepingLocked(), now);
21766                mPendingPssProcesses.add(app);
21767            }
21768        }
21769        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21770    }
21771
21772    public void setTestPssMode(boolean enabled) {
21773        synchronized (this) {
21774            mTestPssMode = enabled;
21775            if (enabled) {
21776                // Whenever we enable the mode, we want to take a snapshot all of current
21777                // process mem use.
21778                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21779            }
21780        }
21781    }
21782
21783    /**
21784     * Ask a given process to GC right now.
21785     */
21786    final void performAppGcLocked(ProcessRecord app) {
21787        try {
21788            app.lastRequestedGc = SystemClock.uptimeMillis();
21789            if (app.thread != null) {
21790                if (app.reportLowMemory) {
21791                    app.reportLowMemory = false;
21792                    app.thread.scheduleLowMemory();
21793                } else {
21794                    app.thread.processInBackground();
21795                }
21796            }
21797        } catch (Exception e) {
21798            // whatever.
21799        }
21800    }
21801
21802    /**
21803     * Returns true if things are idle enough to perform GCs.
21804     */
21805    private final boolean canGcNowLocked() {
21806        boolean processingBroadcasts = false;
21807        for (BroadcastQueue q : mBroadcastQueues) {
21808            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21809                processingBroadcasts = true;
21810            }
21811        }
21812        return !processingBroadcasts
21813                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21814    }
21815
21816    /**
21817     * Perform GCs on all processes that are waiting for it, but only
21818     * if things are idle.
21819     */
21820    final void performAppGcsLocked() {
21821        final int N = mProcessesToGc.size();
21822        if (N <= 0) {
21823            return;
21824        }
21825        if (canGcNowLocked()) {
21826            while (mProcessesToGc.size() > 0) {
21827                ProcessRecord proc = mProcessesToGc.remove(0);
21828                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21829                    if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21830                            <= SystemClock.uptimeMillis()) {
21831                        // To avoid spamming the system, we will GC processes one
21832                        // at a time, waiting a few seconds between each.
21833                        performAppGcLocked(proc);
21834                        scheduleAppGcsLocked();
21835                        return;
21836                    } else {
21837                        // It hasn't been long enough since we last GCed this
21838                        // process...  put it in the list to wait for its time.
21839                        addProcessToGcListLocked(proc);
21840                        break;
21841                    }
21842                }
21843            }
21844
21845            scheduleAppGcsLocked();
21846        }
21847    }
21848
21849    /**
21850     * If all looks good, perform GCs on all processes waiting for them.
21851     */
21852    final void performAppGcsIfAppropriateLocked() {
21853        if (canGcNowLocked()) {
21854            performAppGcsLocked();
21855            return;
21856        }
21857        // Still not idle, wait some more.
21858        scheduleAppGcsLocked();
21859    }
21860
21861    /**
21862     * Schedule the execution of all pending app GCs.
21863     */
21864    final void scheduleAppGcsLocked() {
21865        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21866
21867        if (mProcessesToGc.size() > 0) {
21868            // Schedule a GC for the time to the next process.
21869            ProcessRecord proc = mProcessesToGc.get(0);
21870            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21871
21872            long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21873            long now = SystemClock.uptimeMillis();
21874            if (when < (now+mConstants.GC_TIMEOUT)) {
21875                when = now + mConstants.GC_TIMEOUT;
21876            }
21877            mHandler.sendMessageAtTime(msg, when);
21878        }
21879    }
21880
21881    /**
21882     * Add a process to the array of processes waiting to be GCed.  Keeps the
21883     * list in sorted order by the last GC time.  The process can't already be
21884     * on the list.
21885     */
21886    final void addProcessToGcListLocked(ProcessRecord proc) {
21887        boolean added = false;
21888        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21889            if (mProcessesToGc.get(i).lastRequestedGc <
21890                    proc.lastRequestedGc) {
21891                added = true;
21892                mProcessesToGc.add(i+1, proc);
21893                break;
21894            }
21895        }
21896        if (!added) {
21897            mProcessesToGc.add(0, proc);
21898        }
21899    }
21900
21901    /**
21902     * Set up to ask a process to GC itself.  This will either do it
21903     * immediately, or put it on the list of processes to gc the next
21904     * time things are idle.
21905     */
21906    final void scheduleAppGcLocked(ProcessRecord app) {
21907        long now = SystemClock.uptimeMillis();
21908        if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21909            return;
21910        }
21911        if (!mProcessesToGc.contains(app)) {
21912            addProcessToGcListLocked(app);
21913            scheduleAppGcsLocked();
21914        }
21915    }
21916
21917    final void checkExcessivePowerUsageLocked() {
21918        updateCpuStatsNow();
21919
21920        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21921        boolean doCpuKills = true;
21922        if (mLastPowerCheckUptime == 0) {
21923            doCpuKills = false;
21924        }
21925        final long curUptime = SystemClock.uptimeMillis();
21926        final long uptimeSince = curUptime - mLastPowerCheckUptime;
21927        mLastPowerCheckUptime = curUptime;
21928        int i = mLruProcesses.size();
21929        while (i > 0) {
21930            i--;
21931            ProcessRecord app = mLruProcesses.get(i);
21932            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21933                if (app.lastCpuTime <= 0) {
21934                    continue;
21935                }
21936                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21937                if (DEBUG_POWER) {
21938                    StringBuilder sb = new StringBuilder(128);
21939                    sb.append("CPU for ");
21940                    app.toShortString(sb);
21941                    sb.append(": over ");
21942                    TimeUtils.formatDuration(uptimeSince, sb);
21943                    sb.append(" used ");
21944                    TimeUtils.formatDuration(cputimeUsed, sb);
21945                    sb.append(" (");
21946                    sb.append((cputimeUsed*100)/uptimeSince);
21947                    sb.append("%)");
21948                    Slog.i(TAG_POWER, sb.toString());
21949                }
21950                // If the process has used too much CPU over the last duration, the
21951                // user probably doesn't want this, so kill!
21952                if (doCpuKills && uptimeSince > 0) {
21953                    // What is the limit for this process?
21954                    int cpuLimit;
21955                    long checkDur = curUptime - app.whenUnimportant;
21956                    if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21957                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21958                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21959                            || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21960                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21961                    } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21962                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21963                    } else {
21964                        cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
21965                    }
21966                    if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
21967                        synchronized (stats) {
21968                            stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21969                                    uptimeSince, cputimeUsed);
21970                        }
21971                        app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
21972                                + " dur=" + checkDur + " limit=" + cpuLimit, true);
21973                        app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21974                    }
21975                }
21976                app.lastCpuTime = app.curCpuTime;
21977            }
21978        }
21979    }
21980
21981    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21982            long nowElapsed) {
21983        boolean success = true;
21984
21985        if (app.curRawAdj != app.setRawAdj) {
21986            app.setRawAdj = app.curRawAdj;
21987        }
21988
21989        int changes = 0;
21990
21991        if (app.curAdj != app.setAdj) {
21992            ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
21993            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
21994                String msg = "Set " + app.pid + " " + app.processName + " adj "
21995                        + app.curAdj + ": " + app.adjType;
21996                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
21997            }
21998            app.setAdj = app.curAdj;
21999            app.verifiedAdj = ProcessList.INVALID_ADJ;
22000        }
22001
22002        if (app.setSchedGroup != app.curSchedGroup) {
22003            int oldSchedGroup = app.setSchedGroup;
22004            app.setSchedGroup = app.curSchedGroup;
22005            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22006                String msg = "Setting sched group of " + app.processName
22007                        + " to " + app.curSchedGroup;
22008                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22009            }
22010            if (app.waitingToKill != null && app.curReceivers.isEmpty()
22011                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22012                app.kill(app.waitingToKill, true);
22013                success = false;
22014            } else {
22015                int processGroup;
22016                switch (app.curSchedGroup) {
22017                    case ProcessList.SCHED_GROUP_BACKGROUND:
22018                        processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22019                        break;
22020                    case ProcessList.SCHED_GROUP_TOP_APP:
22021                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22022                        processGroup = THREAD_GROUP_TOP_APP;
22023                        break;
22024                    default:
22025                        processGroup = THREAD_GROUP_DEFAULT;
22026                        break;
22027                }
22028                long oldId = Binder.clearCallingIdentity();
22029                try {
22030                    setProcessGroup(app.pid, processGroup);
22031                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22032                        // do nothing if we already switched to RT
22033                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22034                            mVrController.onTopProcChangedLocked(app);
22035                            if (mUseFifoUiScheduling) {
22036                                // Switch UI pipeline for app to SCHED_FIFO
22037                                app.savedPriority = Process.getThreadPriority(app.pid);
22038                                scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22039                                if (app.renderThreadTid != 0) {
22040                                    scheduleAsFifoPriority(app.renderThreadTid,
22041                                        /* suppressLogs */true);
22042                                    if (DEBUG_OOM_ADJ) {
22043                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
22044                                            app.renderThreadTid + ") to FIFO");
22045                                    }
22046                                } else {
22047                                    if (DEBUG_OOM_ADJ) {
22048                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
22049                                    }
22050                                }
22051                            } else {
22052                                // Boost priority for top app UI and render threads
22053                                setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22054                                if (app.renderThreadTid != 0) {
22055                                    try {
22056                                        setThreadPriority(app.renderThreadTid,
22057                                                TOP_APP_PRIORITY_BOOST);
22058                                    } catch (IllegalArgumentException e) {
22059                                        // thread died, ignore
22060                                    }
22061                                }
22062                            }
22063                        }
22064                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22065                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22066                        mVrController.onTopProcChangedLocked(app);
22067                        if (mUseFifoUiScheduling) {
22068                            try {
22069                                // Reset UI pipeline to SCHED_OTHER
22070                                setThreadScheduler(app.pid, SCHED_OTHER, 0);
22071                                setThreadPriority(app.pid, app.savedPriority);
22072                                if (app.renderThreadTid != 0) {
22073                                    setThreadScheduler(app.renderThreadTid,
22074                                        SCHED_OTHER, 0);
22075                                    setThreadPriority(app.renderThreadTid, -4);
22076                                }
22077                            } catch (IllegalArgumentException e) {
22078                                Slog.w(TAG,
22079                                        "Failed to set scheduling policy, thread does not exist:\n"
22080                                                + e);
22081                            } catch (SecurityException e) {
22082                                Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22083                            }
22084                        } else {
22085                            // Reset priority for top app UI and render threads
22086                            setThreadPriority(app.pid, 0);
22087                            if (app.renderThreadTid != 0) {
22088                                setThreadPriority(app.renderThreadTid, 0);
22089                            }
22090                        }
22091                    }
22092                } catch (Exception e) {
22093                    if (false) {
22094                        Slog.w(TAG, "Failed setting process group of " + app.pid
22095                                + " to " + app.curSchedGroup);
22096                        Slog.w(TAG, "at location", e);
22097                    }
22098                } finally {
22099                    Binder.restoreCallingIdentity(oldId);
22100                }
22101            }
22102        }
22103        if (app.repForegroundActivities != app.foregroundActivities) {
22104            app.repForegroundActivities = app.foregroundActivities;
22105            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22106        }
22107        if (app.repProcState != app.curProcState) {
22108            app.repProcState = app.curProcState;
22109            if (app.thread != null) {
22110                try {
22111                    if (false) {
22112                        //RuntimeException h = new RuntimeException("here");
22113                        Slog.i(TAG, "Sending new process state " + app.repProcState
22114                                + " to " + app /*, h*/);
22115                    }
22116                    app.thread.setProcessState(app.repProcState);
22117                } catch (RemoteException e) {
22118                }
22119            }
22120        }
22121        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22122                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22123            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22124                // Experimental code to more aggressively collect pss while
22125                // running test...  the problem is that this tends to collect
22126                // the data right when a process is transitioning between process
22127                // states, which well tend to give noisy data.
22128                long start = SystemClock.uptimeMillis();
22129                long pss = Debug.getPss(app.pid, mTmpLong, null);
22130                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22131                mPendingPssProcesses.remove(app);
22132                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22133                        + " to " + app.curProcState + ": "
22134                        + (SystemClock.uptimeMillis()-start) + "ms");
22135            }
22136            app.lastStateTime = now;
22137            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22138                    mTestPssMode, isSleepingLocked(), now);
22139            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22140                    + ProcessList.makeProcStateString(app.setProcState) + " to "
22141                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22142                    + (app.nextPssTime-now) + ": " + app);
22143        } else {
22144            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22145                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22146                    mTestPssMode)))) {
22147                requestPssLocked(app, app.setProcState);
22148                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22149                        mTestPssMode, isSleepingLocked(), now);
22150            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22151                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22152        }
22153        if (app.setProcState != app.curProcState) {
22154            if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22155                String msg = "Proc state change of " + app.processName
22156                        + " to " + app.curProcState;
22157                reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22158            }
22159            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22160            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22161            if (setImportant && !curImportant) {
22162                // This app is no longer something we consider important enough to allow to
22163                // use arbitrary amounts of battery power.  Note
22164                // its current CPU time to later know to kill it if
22165                // it is not behaving well.
22166                app.whenUnimportant = now;
22167                app.lastCpuTime = 0;
22168            }
22169            // Inform UsageStats of important process state change
22170            // Must be called before updating setProcState
22171            maybeUpdateUsageStatsLocked(app, nowElapsed);
22172
22173            app.setProcState = app.curProcState;
22174            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22175                app.notCachedSinceIdle = false;
22176            }
22177            if (!doingAll) {
22178                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22179            } else {
22180                app.procStateChanged = true;
22181            }
22182        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22183                > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22184            // For apps that sit around for a long time in the interactive state, we need
22185            // to report this at least once a day so they don't go idle.
22186            maybeUpdateUsageStatsLocked(app, nowElapsed);
22187        }
22188
22189        if (changes != 0) {
22190            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22191                    "Changes in " + app + ": " + changes);
22192            int i = mPendingProcessChanges.size()-1;
22193            ProcessChangeItem item = null;
22194            while (i >= 0) {
22195                item = mPendingProcessChanges.get(i);
22196                if (item.pid == app.pid) {
22197                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22198                            "Re-using existing item: " + item);
22199                    break;
22200                }
22201                i--;
22202            }
22203            if (i < 0) {
22204                // No existing item in pending changes; need a new one.
22205                final int NA = mAvailProcessChanges.size();
22206                if (NA > 0) {
22207                    item = mAvailProcessChanges.remove(NA-1);
22208                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22209                            "Retrieving available item: " + item);
22210                } else {
22211                    item = new ProcessChangeItem();
22212                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22213                            "Allocating new item: " + item);
22214                }
22215                item.changes = 0;
22216                item.pid = app.pid;
22217                item.uid = app.info.uid;
22218                if (mPendingProcessChanges.size() == 0) {
22219                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22220                            "*** Enqueueing dispatch processes changed!");
22221                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22222                }
22223                mPendingProcessChanges.add(item);
22224            }
22225            item.changes |= changes;
22226            item.foregroundActivities = app.repForegroundActivities;
22227            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22228                    "Item " + Integer.toHexString(System.identityHashCode(item))
22229                    + " " + app.toShortString() + ": changes=" + item.changes
22230                    + " foreground=" + item.foregroundActivities
22231                    + " type=" + app.adjType + " source=" + app.adjSource
22232                    + " target=" + app.adjTarget);
22233        }
22234
22235        return success;
22236    }
22237
22238    private boolean isEphemeralLocked(int uid) {
22239        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22240        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22241            return false;
22242        }
22243        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22244                packages[0]);
22245    }
22246
22247    @VisibleForTesting
22248    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22249        final UidRecord.ChangeItem pendingChange;
22250        if (uidRec == null || uidRec.pendingChange == null) {
22251            if (mPendingUidChanges.size() == 0) {
22252                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22253                        "*** Enqueueing dispatch uid changed!");
22254                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22255            }
22256            final int NA = mAvailUidChanges.size();
22257            if (NA > 0) {
22258                pendingChange = mAvailUidChanges.remove(NA-1);
22259                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22260                        "Retrieving available item: " + pendingChange);
22261            } else {
22262                pendingChange = new UidRecord.ChangeItem();
22263                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22264                        "Allocating new item: " + pendingChange);
22265            }
22266            if (uidRec != null) {
22267                uidRec.pendingChange = pendingChange;
22268                if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22269                    // If this uid is going away, and we haven't yet reported it is gone,
22270                    // then do so now.
22271                    change |= UidRecord.CHANGE_IDLE;
22272                }
22273            } else if (uid < 0) {
22274                throw new IllegalArgumentException("No UidRecord or uid");
22275            }
22276            pendingChange.uidRecord = uidRec;
22277            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22278            mPendingUidChanges.add(pendingChange);
22279        } else {
22280            pendingChange = uidRec.pendingChange;
22281            // If there is no change in idle or active state, then keep whatever was pending.
22282            if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22283                change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22284                        | UidRecord.CHANGE_ACTIVE));
22285            }
22286            // If there is no change in cached or uncached state, then keep whatever was pending.
22287            if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22288                change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22289                        | UidRecord.CHANGE_UNCACHED));
22290            }
22291            // If this is a report of the UID being gone, then we shouldn't keep any previous
22292            // report of it being active or cached.  (That is, a gone uid is never active,
22293            // and never cached.)
22294            if ((change & UidRecord.CHANGE_GONE) != 0) {
22295                change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22296                if (!uidRec.idle) {
22297                    // If this uid is going away, and we haven't yet reported it is gone,
22298                    // then do so now.
22299                    change |= UidRecord.CHANGE_IDLE;
22300                }
22301            }
22302        }
22303        pendingChange.change = change;
22304        pendingChange.processState = uidRec != null
22305                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22306        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22307        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22308        if (uidRec != null) {
22309            uidRec.lastReportedChange = change;
22310            uidRec.updateLastDispatchedProcStateSeq(change);
22311        }
22312
22313        // Directly update the power manager, since we sit on top of it and it is critical
22314        // it be kept in sync (so wake locks will be held as soon as appropriate).
22315        if (mLocalPowerManager != null) {
22316            // TO DO: dispatch cached/uncached changes here, so we don't need to report
22317            // all proc state changes.
22318            if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22319                mLocalPowerManager.uidActive(pendingChange.uid);
22320            }
22321            if ((change & UidRecord.CHANGE_IDLE) != 0) {
22322                mLocalPowerManager.uidIdle(pendingChange.uid);
22323            }
22324            if ((change & UidRecord.CHANGE_GONE) != 0) {
22325                mLocalPowerManager.uidGone(pendingChange.uid);
22326            } else {
22327                mLocalPowerManager.updateUidProcState(pendingChange.uid,
22328                        pendingChange.processState);
22329            }
22330        }
22331    }
22332
22333    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22334            String authority) {
22335        if (app == null) return;
22336        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22337            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22338            if (userState == null) return;
22339            final long now = SystemClock.elapsedRealtime();
22340            Long lastReported = userState.mProviderLastReportedFg.get(authority);
22341            if (lastReported == null || lastReported < now - 60 * 1000L) {
22342                if (mSystemReady) {
22343                    // Cannot touch the user stats if not system ready
22344                    mUsageStatsService.reportContentProviderUsage(
22345                            authority, providerPkgName, app.userId);
22346                }
22347                userState.mProviderLastReportedFg.put(authority, now);
22348            }
22349        }
22350    }
22351
22352    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22353        if (DEBUG_USAGE_STATS) {
22354            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22355                    + "] state changes: old = " + app.setProcState + ", new = "
22356                    + app.curProcState);
22357        }
22358        if (mUsageStatsService == null) {
22359            return;
22360        }
22361        boolean isInteraction;
22362        // To avoid some abuse patterns, we are going to be careful about what we consider
22363        // to be an app interaction.  Being the top activity doesn't count while the display
22364        // is sleeping, nor do short foreground services.
22365        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22366            isInteraction = true;
22367            app.fgInteractionTime = 0;
22368        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22369            if (app.fgInteractionTime == 0) {
22370                app.fgInteractionTime = nowElapsed;
22371                isInteraction = false;
22372            } else {
22373                isInteraction = nowElapsed > app.fgInteractionTime
22374                        + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22375            }
22376        } else {
22377            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22378            app.fgInteractionTime = 0;
22379        }
22380        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22381                > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22382            app.interactionEventTime = nowElapsed;
22383            String[] packages = app.getPackageList();
22384            if (packages != null) {
22385                for (int i = 0; i < packages.length; i++) {
22386                    mUsageStatsService.reportEvent(packages[i], app.userId,
22387                            UsageEvents.Event.SYSTEM_INTERACTION);
22388                }
22389            }
22390        }
22391        app.reportedInteraction = isInteraction;
22392        if (!isInteraction) {
22393            app.interactionEventTime = 0;
22394        }
22395    }
22396
22397    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22398        if (proc.thread != null) {
22399            if (proc.baseProcessTracker != null) {
22400                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22401            }
22402        }
22403    }
22404
22405    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22406            ProcessRecord TOP_APP, boolean doingAll, long now) {
22407        if (app.thread == null) {
22408            return false;
22409        }
22410
22411        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22412
22413        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22414    }
22415
22416    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22417            boolean oomAdj) {
22418        if (isForeground != proc.foregroundServices) {
22419            proc.foregroundServices = isForeground;
22420            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22421                    proc.info.uid);
22422            if (isForeground) {
22423                if (curProcs == null) {
22424                    curProcs = new ArrayList<ProcessRecord>();
22425                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22426                }
22427                if (!curProcs.contains(proc)) {
22428                    curProcs.add(proc);
22429                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22430                            proc.info.packageName, proc.info.uid);
22431                }
22432            } else {
22433                if (curProcs != null) {
22434                    if (curProcs.remove(proc)) {
22435                        mBatteryStatsService.noteEvent(
22436                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22437                                proc.info.packageName, proc.info.uid);
22438                        if (curProcs.size() <= 0) {
22439                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22440                        }
22441                    }
22442                }
22443            }
22444            if (oomAdj) {
22445                updateOomAdjLocked();
22446            }
22447        }
22448    }
22449
22450    private final ActivityRecord resumedAppLocked() {
22451        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22452        String pkg;
22453        int uid;
22454        if (act != null) {
22455            pkg = act.packageName;
22456            uid = act.info.applicationInfo.uid;
22457        } else {
22458            pkg = null;
22459            uid = -1;
22460        }
22461        // Has the UID or resumed package name changed?
22462        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22463                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22464            if (mCurResumedPackage != null) {
22465                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22466                        mCurResumedPackage, mCurResumedUid);
22467            }
22468            mCurResumedPackage = pkg;
22469            mCurResumedUid = uid;
22470            if (mCurResumedPackage != null) {
22471                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22472                        mCurResumedPackage, mCurResumedUid);
22473            }
22474        }
22475        return act;
22476    }
22477
22478    /**
22479     * Update OomAdj for a specific process.
22480     * @param app The process to update
22481     * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22482     *                  if necessary, or skip.
22483     * @return whether updateOomAdjLocked(app) was successful.
22484     */
22485    final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22486        final ActivityRecord TOP_ACT = resumedAppLocked();
22487        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22488        final boolean wasCached = app.cached;
22489
22490        mAdjSeq++;
22491
22492        // This is the desired cached adjusment we want to tell it to use.
22493        // If our app is currently cached, we know it, and that is it.  Otherwise,
22494        // we don't know it yet, and it needs to now be cached we will then
22495        // need to do a complete oom adj.
22496        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22497                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22498        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22499                SystemClock.uptimeMillis());
22500        if (oomAdjAll
22501                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22502            // Changed to/from cached state, so apps after it in the LRU
22503            // list may also be changed.
22504            updateOomAdjLocked();
22505        }
22506        return success;
22507    }
22508
22509    final void updateOomAdjLocked() {
22510        final ActivityRecord TOP_ACT = resumedAppLocked();
22511        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22512        final long now = SystemClock.uptimeMillis();
22513        final long nowElapsed = SystemClock.elapsedRealtime();
22514        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22515        final int N = mLruProcesses.size();
22516
22517        if (false) {
22518            RuntimeException e = new RuntimeException();
22519            e.fillInStackTrace();
22520            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22521        }
22522
22523        // Reset state in all uid records.
22524        for (int i=mActiveUids.size()-1; i>=0; i--) {
22525            final UidRecord uidRec = mActiveUids.valueAt(i);
22526            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22527                    "Starting update of " + uidRec);
22528            uidRec.reset();
22529        }
22530
22531        mStackSupervisor.rankTaskLayersIfNeeded();
22532
22533        mAdjSeq++;
22534        mNewNumServiceProcs = 0;
22535        mNewNumAServiceProcs = 0;
22536
22537        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22538        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22539
22540        // Let's determine how many processes we have running vs.
22541        // how many slots we have for background processes; we may want
22542        // to put multiple processes in a slot of there are enough of
22543        // them.
22544        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22545                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22546        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22547        if (numEmptyProcs > cachedProcessLimit) {
22548            // If there are more empty processes than our limit on cached
22549            // processes, then use the cached process limit for the factor.
22550            // This ensures that the really old empty processes get pushed
22551            // down to the bottom, so if we are running low on memory we will
22552            // have a better chance at keeping around more cached processes
22553            // instead of a gazillion empty processes.
22554            numEmptyProcs = cachedProcessLimit;
22555        }
22556        int emptyFactor = numEmptyProcs/numSlots;
22557        if (emptyFactor < 1) emptyFactor = 1;
22558        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22559        if (cachedFactor < 1) cachedFactor = 1;
22560        int stepCached = 0;
22561        int stepEmpty = 0;
22562        int numCached = 0;
22563        int numEmpty = 0;
22564        int numTrimming = 0;
22565
22566        mNumNonCachedProcs = 0;
22567        mNumCachedHiddenProcs = 0;
22568
22569        // First update the OOM adjustment for each of the
22570        // application processes based on their current state.
22571        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22572        int nextCachedAdj = curCachedAdj+1;
22573        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22574        int nextEmptyAdj = curEmptyAdj+2;
22575        for (int i=N-1; i>=0; i--) {
22576            ProcessRecord app = mLruProcesses.get(i);
22577            if (!app.killedByAm && app.thread != null) {
22578                app.procStateChanged = false;
22579                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22580
22581                // If we haven't yet assigned the final cached adj
22582                // to the process, do that now.
22583                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22584                    switch (app.curProcState) {
22585                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22586                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22587                            // This process is a cached process holding activities...
22588                            // assign it the next cached value for that type, and then
22589                            // step that cached level.
22590                            app.curRawAdj = curCachedAdj;
22591                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22592                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22593                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22594                                    + ")");
22595                            if (curCachedAdj != nextCachedAdj) {
22596                                stepCached++;
22597                                if (stepCached >= cachedFactor) {
22598                                    stepCached = 0;
22599                                    curCachedAdj = nextCachedAdj;
22600                                    nextCachedAdj += 2;
22601                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22602                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22603                                    }
22604                                }
22605                            }
22606                            break;
22607                        default:
22608                            // For everything else, assign next empty cached process
22609                            // level and bump that up.  Note that this means that
22610                            // long-running services that have dropped down to the
22611                            // cached level will be treated as empty (since their process
22612                            // state is still as a service), which is what we want.
22613                            app.curRawAdj = curEmptyAdj;
22614                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22615                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22616                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22617                                    + ")");
22618                            if (curEmptyAdj != nextEmptyAdj) {
22619                                stepEmpty++;
22620                                if (stepEmpty >= emptyFactor) {
22621                                    stepEmpty = 0;
22622                                    curEmptyAdj = nextEmptyAdj;
22623                                    nextEmptyAdj += 2;
22624                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22625                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22626                                    }
22627                                }
22628                            }
22629                            break;
22630                    }
22631                }
22632
22633                applyOomAdjLocked(app, true, now, nowElapsed);
22634
22635                // Count the number of process types.
22636                switch (app.curProcState) {
22637                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22638                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22639                        mNumCachedHiddenProcs++;
22640                        numCached++;
22641                        if (numCached > cachedProcessLimit) {
22642                            app.kill("cached #" + numCached, true);
22643                        }
22644                        break;
22645                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22646                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22647                                && app.lastActivityTime < oldTime) {
22648                            app.kill("empty for "
22649                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22650                                    / 1000) + "s", true);
22651                        } else {
22652                            numEmpty++;
22653                            if (numEmpty > emptyProcessLimit) {
22654                                app.kill("empty #" + numEmpty, true);
22655                            }
22656                        }
22657                        break;
22658                    default:
22659                        mNumNonCachedProcs++;
22660                        break;
22661                }
22662
22663                if (app.isolated && app.services.size() <= 0) {
22664                    // If this is an isolated process, and there are no
22665                    // services running in it, then the process is no longer
22666                    // needed.  We agressively kill these because we can by
22667                    // definition not re-use the same process again, and it is
22668                    // good to avoid having whatever code was running in them
22669                    // left sitting around after no longer needed.
22670                    app.kill("isolated not needed", true);
22671                } else {
22672                    // Keeping this process, update its uid.
22673                    final UidRecord uidRec = app.uidRecord;
22674                    if (uidRec != null) {
22675                        uidRec.ephemeral = app.info.isInstantApp();
22676                        if (uidRec.curProcState > app.curProcState) {
22677                            uidRec.curProcState = app.curProcState;
22678                        }
22679                        if (app.foregroundServices) {
22680                            uidRec.foregroundServices = true;
22681                        }
22682                    }
22683                }
22684
22685                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22686                        && !app.killedByAm) {
22687                    numTrimming++;
22688                }
22689            }
22690        }
22691
22692        incrementProcStateSeqAndNotifyAppsLocked();
22693
22694        mNumServiceProcs = mNewNumServiceProcs;
22695
22696        // Now determine the memory trimming level of background processes.
22697        // Unfortunately we need to start at the back of the list to do this
22698        // properly.  We only do this if the number of background apps we
22699        // are managing to keep around is less than half the maximum we desire;
22700        // if we are keeping a good number around, we'll let them use whatever
22701        // memory they want.
22702        final int numCachedAndEmpty = numCached + numEmpty;
22703        int memFactor;
22704        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22705                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22706            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22707                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22708            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22709                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22710            } else {
22711                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22712            }
22713        } else {
22714            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22715        }
22716        // We always allow the memory level to go up (better).  We only allow it to go
22717        // down if we are in a state where that is allowed, *and* the total number of processes
22718        // has gone down since last time.
22719        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22720                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22721                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22722        if (memFactor > mLastMemoryLevel) {
22723            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22724                memFactor = mLastMemoryLevel;
22725                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22726            }
22727        }
22728        if (memFactor != mLastMemoryLevel) {
22729            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22730        }
22731        mLastMemoryLevel = memFactor;
22732        mLastNumProcesses = mLruProcesses.size();
22733        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22734        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22735        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22736            if (mLowRamStartTime == 0) {
22737                mLowRamStartTime = now;
22738            }
22739            int step = 0;
22740            int fgTrimLevel;
22741            switch (memFactor) {
22742                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22743                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22744                    break;
22745                case ProcessStats.ADJ_MEM_FACTOR_LOW:
22746                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22747                    break;
22748                default:
22749                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22750                    break;
22751            }
22752            int factor = numTrimming/3;
22753            int minFactor = 2;
22754            if (mHomeProcess != null) minFactor++;
22755            if (mPreviousProcess != null) minFactor++;
22756            if (factor < minFactor) factor = minFactor;
22757            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22758            for (int i=N-1; i>=0; i--) {
22759                ProcessRecord app = mLruProcesses.get(i);
22760                if (allChanged || app.procStateChanged) {
22761                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22762                    app.procStateChanged = false;
22763                }
22764                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22765                        && !app.killedByAm) {
22766                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
22767                        try {
22768                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22769                                    "Trimming memory of " + app.processName + " to " + curLevel);
22770                            app.thread.scheduleTrimMemory(curLevel);
22771                        } catch (RemoteException e) {
22772                        }
22773                        if (false) {
22774                            // For now we won't do this; our memory trimming seems
22775                            // to be good enough at this point that destroying
22776                            // activities causes more harm than good.
22777                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22778                                    && app != mHomeProcess && app != mPreviousProcess) {
22779                                // Need to do this on its own message because the stack may not
22780                                // be in a consistent state at this point.
22781                                // For these apps we will also finish their activities
22782                                // to help them free memory.
22783                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22784                            }
22785                        }
22786                    }
22787                    app.trimMemoryLevel = curLevel;
22788                    step++;
22789                    if (step >= factor) {
22790                        step = 0;
22791                        switch (curLevel) {
22792                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22793                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22794                                break;
22795                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22796                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22797                                break;
22798                        }
22799                    }
22800                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22801                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22802                            && app.thread != null) {
22803                        try {
22804                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22805                                    "Trimming memory of heavy-weight " + app.processName
22806                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22807                            app.thread.scheduleTrimMemory(
22808                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22809                        } catch (RemoteException e) {
22810                        }
22811                    }
22812                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22813                } else {
22814                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22815                            || app.systemNoUi) && app.pendingUiClean) {
22816                        // If this application is now in the background and it
22817                        // had done UI, then give it the special trim level to
22818                        // have it free UI resources.
22819                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22820                        if (app.trimMemoryLevel < level && app.thread != null) {
22821                            try {
22822                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22823                                        "Trimming memory of bg-ui " + app.processName
22824                                        + " to " + level);
22825                                app.thread.scheduleTrimMemory(level);
22826                            } catch (RemoteException e) {
22827                            }
22828                        }
22829                        app.pendingUiClean = false;
22830                    }
22831                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22832                        try {
22833                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22834                                    "Trimming memory of fg " + app.processName
22835                                    + " to " + fgTrimLevel);
22836                            app.thread.scheduleTrimMemory(fgTrimLevel);
22837                        } catch (RemoteException e) {
22838                        }
22839                    }
22840                    app.trimMemoryLevel = fgTrimLevel;
22841                }
22842            }
22843        } else {
22844            if (mLowRamStartTime != 0) {
22845                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22846                mLowRamStartTime = 0;
22847            }
22848            for (int i=N-1; i>=0; i--) {
22849                ProcessRecord app = mLruProcesses.get(i);
22850                if (allChanged || app.procStateChanged) {
22851                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22852                    app.procStateChanged = false;
22853                }
22854                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22855                        || app.systemNoUi) && app.pendingUiClean) {
22856                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22857                            && app.thread != null) {
22858                        try {
22859                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22860                                    "Trimming memory of ui hidden " + app.processName
22861                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22862                            app.thread.scheduleTrimMemory(
22863                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22864                        } catch (RemoteException e) {
22865                        }
22866                    }
22867                    app.pendingUiClean = false;
22868                }
22869                app.trimMemoryLevel = 0;
22870            }
22871        }
22872
22873        if (mAlwaysFinishActivities) {
22874            // Need to do this on its own message because the stack may not
22875            // be in a consistent state at this point.
22876            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22877        }
22878
22879        if (allChanged) {
22880            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22881        }
22882
22883        ArrayList<UidRecord> becameIdle = null;
22884
22885        // Update from any uid changes.
22886        if (mLocalPowerManager != null) {
22887            mLocalPowerManager.startUidChanges();
22888        }
22889        for (int i=mActiveUids.size()-1; i>=0; i--) {
22890            final UidRecord uidRec = mActiveUids.valueAt(i);
22891            int uidChange = UidRecord.CHANGE_PROCSTATE;
22892            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22893                    && (uidRec.setProcState != uidRec.curProcState
22894                           || uidRec.setWhitelist != uidRec.curWhitelist)) {
22895                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22896                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22897                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22898                        + " to " + uidRec.curWhitelist);
22899                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22900                        && !uidRec.curWhitelist) {
22901                    // UID is now in the background (and not on the temp whitelist).  Was it
22902                    // previously in the foreground (or on the temp whitelist)?
22903                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22904                            || uidRec.setWhitelist) {
22905                        uidRec.lastBackgroundTime = nowElapsed;
22906                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22907                            // Note: the background settle time is in elapsed realtime, while
22908                            // the handler time base is uptime.  All this means is that we may
22909                            // stop background uids later than we had intended, but that only
22910                            // happens because the device was sleeping so we are okay anyway.
22911                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22912                                    mConstants.BACKGROUND_SETTLE_TIME);
22913                        }
22914                    }
22915                    if (uidRec.idle && !uidRec.setIdle) {
22916                        uidChange = UidRecord.CHANGE_IDLE;
22917                        if (becameIdle == null) {
22918                            becameIdle = new ArrayList<>();
22919                        }
22920                        becameIdle.add(uidRec);
22921                    }
22922                } else {
22923                    if (uidRec.idle) {
22924                        uidChange = UidRecord.CHANGE_ACTIVE;
22925                        EventLogTags.writeAmUidActive(uidRec.uid);
22926                        uidRec.idle = false;
22927                    }
22928                    uidRec.lastBackgroundTime = 0;
22929                }
22930                final boolean wasCached = uidRec.setProcState
22931                        > ActivityManager.PROCESS_STATE_RECEIVER;
22932                final boolean isCached = uidRec.curProcState
22933                        > ActivityManager.PROCESS_STATE_RECEIVER;
22934                if (wasCached != isCached ||
22935                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22936                    uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22937                }
22938                uidRec.setProcState = uidRec.curProcState;
22939                uidRec.setWhitelist = uidRec.curWhitelist;
22940                uidRec.setIdle = uidRec.idle;
22941                enqueueUidChangeLocked(uidRec, -1, uidChange);
22942                noteUidProcessState(uidRec.uid, uidRec.curProcState);
22943                if (uidRec.foregroundServices) {
22944                    mServices.foregroundServiceProcStateChangedLocked(uidRec);
22945                }
22946            }
22947        }
22948        if (mLocalPowerManager != null) {
22949            mLocalPowerManager.finishUidChanges();
22950        }
22951
22952        if (becameIdle != null) {
22953            // If we have any new uids that became idle this time, we need to make sure
22954            // they aren't left with running services.
22955            for (int i = becameIdle.size() - 1; i >= 0; i--) {
22956                mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22957            }
22958        }
22959
22960        if (mProcessStats.shouldWriteNowLocked(now)) {
22961            mHandler.post(new Runnable() {
22962                @Override public void run() {
22963                    synchronized (ActivityManagerService.this) {
22964                        mProcessStats.writeStateAsyncLocked();
22965                    }
22966                }
22967            });
22968        }
22969
22970        if (DEBUG_OOM_ADJ) {
22971            final long duration = SystemClock.uptimeMillis() - now;
22972            if (false) {
22973                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22974                        new RuntimeException("here").fillInStackTrace());
22975            } else {
22976                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22977            }
22978        }
22979    }
22980
22981    @Override
22982    public void makePackageIdle(String packageName, int userId) {
22983        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22984                != PackageManager.PERMISSION_GRANTED) {
22985            String msg = "Permission Denial: makePackageIdle() from pid="
22986                    + Binder.getCallingPid()
22987                    + ", uid=" + Binder.getCallingUid()
22988                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22989            Slog.w(TAG, msg);
22990            throw new SecurityException(msg);
22991        }
22992        final int callingPid = Binder.getCallingPid();
22993        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22994                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22995        long callingId = Binder.clearCallingIdentity();
22996        synchronized(this) {
22997            try {
22998                IPackageManager pm = AppGlobals.getPackageManager();
22999                int pkgUid = -1;
23000                try {
23001                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23002                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23003                } catch (RemoteException e) {
23004                }
23005                if (pkgUid == -1) {
23006                    throw new IllegalArgumentException("Unknown package name " + packageName);
23007                }
23008
23009                if (mLocalPowerManager != null) {
23010                    mLocalPowerManager.startUidChanges();
23011                }
23012                final int appId = UserHandle.getAppId(pkgUid);
23013                final int N = mActiveUids.size();
23014                for (int i=N-1; i>=0; i--) {
23015                    final UidRecord uidRec = mActiveUids.valueAt(i);
23016                    final long bgTime = uidRec.lastBackgroundTime;
23017                    if (bgTime > 0 && !uidRec.idle) {
23018                        if (UserHandle.getAppId(uidRec.uid) == appId) {
23019                            if (userId == UserHandle.USER_ALL ||
23020                                    userId == UserHandle.getUserId(uidRec.uid)) {
23021                                EventLogTags.writeAmUidIdle(uidRec.uid);
23022                                uidRec.idle = true;
23023                                uidRec.setIdle = true;
23024                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23025                                        + " from package " + packageName + " user " + userId);
23026                                doStopUidLocked(uidRec.uid, uidRec);
23027                            }
23028                        }
23029                    }
23030                }
23031            } finally {
23032                if (mLocalPowerManager != null) {
23033                    mLocalPowerManager.finishUidChanges();
23034                }
23035                Binder.restoreCallingIdentity(callingId);
23036            }
23037        }
23038    }
23039
23040    final void idleUids() {
23041        synchronized (this) {
23042            final int N = mActiveUids.size();
23043            if (N <= 0) {
23044                return;
23045            }
23046            final long nowElapsed = SystemClock.elapsedRealtime();
23047            final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23048            long nextTime = 0;
23049            if (mLocalPowerManager != null) {
23050                mLocalPowerManager.startUidChanges();
23051            }
23052            for (int i=N-1; i>=0; i--) {
23053                final UidRecord uidRec = mActiveUids.valueAt(i);
23054                final long bgTime = uidRec.lastBackgroundTime;
23055                if (bgTime > 0 && !uidRec.idle) {
23056                    if (bgTime <= maxBgTime) {
23057                        EventLogTags.writeAmUidIdle(uidRec.uid);
23058                        uidRec.idle = true;
23059                        uidRec.setIdle = true;
23060                        doStopUidLocked(uidRec.uid, uidRec);
23061                    } else {
23062                        if (nextTime == 0 || nextTime > bgTime) {
23063                            nextTime = bgTime;
23064                        }
23065                    }
23066                }
23067            }
23068            if (mLocalPowerManager != null) {
23069                mLocalPowerManager.finishUidChanges();
23070            }
23071            if (nextTime > 0) {
23072                mHandler.removeMessages(IDLE_UIDS_MSG);
23073                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23074                        nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23075            }
23076        }
23077    }
23078
23079    /**
23080     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23081     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23082     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23083     */
23084    @VisibleForTesting
23085    @GuardedBy("this")
23086    void incrementProcStateSeqAndNotifyAppsLocked() {
23087        if (mWaitForNetworkTimeoutMs <= 0) {
23088            return;
23089        }
23090        // Used for identifying which uids need to block for network.
23091        ArrayList<Integer> blockingUids = null;
23092        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23093            final UidRecord uidRec = mActiveUids.valueAt(i);
23094            // If the network is not restricted for uid, then nothing to do here.
23095            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23096                continue;
23097            }
23098            if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23099                continue;
23100            }
23101            // If process state is not changed, then there's nothing to do.
23102            if (uidRec.setProcState == uidRec.curProcState) {
23103                continue;
23104            }
23105            final int blockState = getBlockStateForUid(uidRec);
23106            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23107            // there's nothing the app needs to do in this scenario.
23108            if (blockState == NETWORK_STATE_NO_CHANGE) {
23109                continue;
23110            }
23111            synchronized (uidRec.networkStateLock) {
23112                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23113                if (blockState == NETWORK_STATE_BLOCK) {
23114                    if (blockingUids == null) {
23115                        blockingUids = new ArrayList<>();
23116                    }
23117                    blockingUids.add(uidRec.uid);
23118                } else {
23119                    if (DEBUG_NETWORK) {
23120                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23121                                + " threads for uid: " + uidRec);
23122                    }
23123                    if (uidRec.waitingForNetwork) {
23124                        uidRec.networkStateLock.notifyAll();
23125                    }
23126                }
23127            }
23128        }
23129
23130        // There are no uids that need to block, so nothing more to do.
23131        if (blockingUids == null) {
23132            return;
23133        }
23134
23135        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23136            final ProcessRecord app = mLruProcesses.get(i);
23137            if (!blockingUids.contains(app.uid)) {
23138                continue;
23139            }
23140            if (!app.killedByAm && app.thread != null) {
23141                final UidRecord uidRec = mActiveUids.get(app.uid);
23142                try {
23143                    if (DEBUG_NETWORK) {
23144                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23145                                + uidRec);
23146                    }
23147                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23148                } catch (RemoteException ignored) {
23149                }
23150            }
23151        }
23152    }
23153
23154    /**
23155     * Checks if the uid is coming from background to foreground or vice versa and returns
23156     * appropriate block state based on this.
23157     *
23158     * @return blockState based on whether the uid is coming from background to foreground or
23159     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23160     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23161     *         {@link #NETWORK_STATE_NO_CHANGE}.
23162     */
23163    @VisibleForTesting
23164    int getBlockStateForUid(UidRecord uidRec) {
23165        // Denotes whether uid's process state is currently allowed network access.
23166        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23167                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23168        // Denotes whether uid's process state was previously allowed network access.
23169        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23170                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23171
23172        // When the uid is coming to foreground, AMS should inform the app thread that it should
23173        // block for the network rules to get updated before launching an activity.
23174        if (!wasAllowed && isAllowed) {
23175            return NETWORK_STATE_BLOCK;
23176        }
23177        // When the uid is going to background, AMS should inform the app thread that if an
23178        // activity launch is blocked for the network rules to get updated, it should be unblocked.
23179        if (wasAllowed && !isAllowed) {
23180            return NETWORK_STATE_UNBLOCK;
23181        }
23182        return NETWORK_STATE_NO_CHANGE;
23183    }
23184
23185    final void runInBackgroundDisabled(int uid) {
23186        synchronized (this) {
23187            UidRecord uidRec = mActiveUids.get(uid);
23188            if (uidRec != null) {
23189                // This uid is actually running...  should it be considered background now?
23190                if (uidRec.idle) {
23191                    doStopUidLocked(uidRec.uid, uidRec);
23192                }
23193            } else {
23194                // This uid isn't actually running...  still send a report about it being "stopped".
23195                doStopUidLocked(uid, null);
23196            }
23197        }
23198    }
23199
23200    final void doStopUidLocked(int uid, final UidRecord uidRec) {
23201        mServices.stopInBackgroundLocked(uid);
23202        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23203    }
23204
23205    /**
23206     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23207     */
23208    void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23209            long duration, String tag) {
23210        if (DEBUG_WHITELISTS) {
23211            Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23212                    + targetUid + ", " + duration + ")");
23213        }
23214
23215        synchronized (mPidsSelfLocked) {
23216            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23217            if (pr == null) {
23218                Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23219                        + callerPid);
23220                return;
23221            }
23222            if (!pr.whitelistManager) {
23223                if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23224                        != PackageManager.PERMISSION_GRANTED) {
23225                    if (DEBUG_WHITELISTS) {
23226                        Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23227                                + ": pid " + callerPid + " is not allowed");
23228                    }
23229                    return;
23230                }
23231            }
23232        }
23233
23234        tempWhitelistUidLocked(targetUid, duration, tag);
23235    }
23236
23237    /**
23238     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23239     */
23240    void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23241        mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23242        setUidTempWhitelistStateLocked(targetUid, true);
23243        mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23244    }
23245
23246    void pushTempWhitelist() {
23247        final int N;
23248        final PendingTempWhitelist[] list;
23249
23250        // First copy out the pending changes...  we need to leave them in the map for now,
23251        // in case someone needs to check what is coming up while we don't have the lock held.
23252        synchronized(this) {
23253            N = mPendingTempWhitelist.size();
23254            list = new PendingTempWhitelist[N];
23255            for (int i = 0; i < N; i++) {
23256                list[i] = mPendingTempWhitelist.valueAt(i);
23257            }
23258        }
23259
23260        // Now safely dispatch changes to device idle controller.
23261        for (int i = 0; i < N; i++) {
23262            PendingTempWhitelist ptw = list[i];
23263            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23264                    ptw.duration, true, ptw.tag);
23265        }
23266
23267        // And now we can safely remove them from the map.
23268        synchronized(this) {
23269            for (int i = 0; i < N; i++) {
23270                PendingTempWhitelist ptw = list[i];
23271                int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23272                if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23273                    mPendingTempWhitelist.removeAt(index);
23274                }
23275            }
23276        }
23277    }
23278
23279    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23280        boolean changed = false;
23281        for (int i=mActiveUids.size()-1; i>=0; i--) {
23282            final UidRecord uidRec = mActiveUids.valueAt(i);
23283            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23284                uidRec.curWhitelist = onWhitelist;
23285                changed = true;
23286            }
23287        }
23288        if (changed) {
23289            updateOomAdjLocked();
23290        }
23291    }
23292
23293    final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23294        boolean changed = false;
23295        final UidRecord uidRec = mActiveUids.get(uid);
23296        if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23297            uidRec.curWhitelist = onWhitelist;
23298            updateOomAdjLocked();
23299        }
23300    }
23301
23302    final void trimApplications() {
23303        synchronized (this) {
23304            int i;
23305
23306            // First remove any unused application processes whose package
23307            // has been removed.
23308            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23309                final ProcessRecord app = mRemovedProcesses.get(i);
23310                if (app.activities.size() == 0
23311                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
23312                    Slog.i(
23313                        TAG, "Exiting empty application process "
23314                        + app.toShortString() + " ("
23315                        + (app.thread != null ? app.thread.asBinder() : null)
23316                        + ")\n");
23317                    if (app.pid > 0 && app.pid != MY_PID) {
23318                        app.kill("empty", false);
23319                    } else {
23320                        try {
23321                            app.thread.scheduleExit();
23322                        } catch (Exception e) {
23323                            // Ignore exceptions.
23324                        }
23325                    }
23326                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23327                    mRemovedProcesses.remove(i);
23328
23329                    if (app.persistent) {
23330                        addAppLocked(app.info, null, false, null /* ABI override */);
23331                    }
23332                }
23333            }
23334
23335            // Now update the oom adj for all processes.
23336            updateOomAdjLocked();
23337        }
23338    }
23339
23340    /** This method sends the specified signal to each of the persistent apps */
23341    public void signalPersistentProcesses(int sig) throws RemoteException {
23342        if (sig != SIGNAL_USR1) {
23343            throw new SecurityException("Only SIGNAL_USR1 is allowed");
23344        }
23345
23346        synchronized (this) {
23347            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23348                    != PackageManager.PERMISSION_GRANTED) {
23349                throw new SecurityException("Requires permission "
23350                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23351            }
23352
23353            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23354                ProcessRecord r = mLruProcesses.get(i);
23355                if (r.thread != null && r.persistent) {
23356                    sendSignal(r.pid, sig);
23357                }
23358            }
23359        }
23360    }
23361
23362    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23363        if (proc == null || proc == mProfileProc) {
23364            proc = mProfileProc;
23365            profileType = mProfileType;
23366            clearProfilerLocked();
23367        }
23368        if (proc == null) {
23369            return;
23370        }
23371        try {
23372            proc.thread.profilerControl(false, null, profileType);
23373        } catch (RemoteException e) {
23374            throw new IllegalStateException("Process disappeared");
23375        }
23376    }
23377
23378    private void clearProfilerLocked() {
23379        if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23380            try {
23381                mProfilerInfo.profileFd.close();
23382            } catch (IOException e) {
23383            }
23384        }
23385        mProfileApp = null;
23386        mProfileProc = null;
23387        mProfilerInfo = null;
23388    }
23389
23390    public boolean profileControl(String process, int userId, boolean start,
23391            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23392
23393        try {
23394            synchronized (this) {
23395                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23396                // its own permission.
23397                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23398                        != PackageManager.PERMISSION_GRANTED) {
23399                    throw new SecurityException("Requires permission "
23400                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23401                }
23402
23403                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23404                    throw new IllegalArgumentException("null profile info or fd");
23405                }
23406
23407                ProcessRecord proc = null;
23408                if (process != null) {
23409                    proc = findProcessLocked(process, userId, "profileControl");
23410                }
23411
23412                if (start && (proc == null || proc.thread == null)) {
23413                    throw new IllegalArgumentException("Unknown process: " + process);
23414                }
23415
23416                if (start) {
23417                    stopProfilerLocked(null, 0);
23418                    setProfileApp(proc.info, proc.processName, profilerInfo);
23419                    mProfileProc = proc;
23420                    mProfileType = profileType;
23421                    ParcelFileDescriptor fd = profilerInfo.profileFd;
23422                    try {
23423                        fd = fd.dup();
23424                    } catch (IOException e) {
23425                        fd = null;
23426                    }
23427                    profilerInfo.profileFd = fd;
23428                    proc.thread.profilerControl(start, profilerInfo, profileType);
23429                    fd = null;
23430                    try {
23431                        mProfilerInfo.profileFd.close();
23432                    } catch (IOException e) {
23433                    }
23434                    mProfilerInfo.profileFd = null;
23435                } else {
23436                    stopProfilerLocked(proc, profileType);
23437                    if (profilerInfo != null && profilerInfo.profileFd != null) {
23438                        try {
23439                            profilerInfo.profileFd.close();
23440                        } catch (IOException e) {
23441                        }
23442                    }
23443                }
23444
23445                return true;
23446            }
23447        } catch (RemoteException e) {
23448            throw new IllegalStateException("Process disappeared");
23449        } finally {
23450            if (profilerInfo != null && profilerInfo.profileFd != null) {
23451                try {
23452                    profilerInfo.profileFd.close();
23453                } catch (IOException e) {
23454                }
23455            }
23456        }
23457    }
23458
23459    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23460        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23461                userId, true, ALLOW_FULL_ONLY, callName, null);
23462        ProcessRecord proc = null;
23463        try {
23464            int pid = Integer.parseInt(process);
23465            synchronized (mPidsSelfLocked) {
23466                proc = mPidsSelfLocked.get(pid);
23467            }
23468        } catch (NumberFormatException e) {
23469        }
23470
23471        if (proc == null) {
23472            ArrayMap<String, SparseArray<ProcessRecord>> all
23473                    = mProcessNames.getMap();
23474            SparseArray<ProcessRecord> procs = all.get(process);
23475            if (procs != null && procs.size() > 0) {
23476                proc = procs.valueAt(0);
23477                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23478                    for (int i=1; i<procs.size(); i++) {
23479                        ProcessRecord thisProc = procs.valueAt(i);
23480                        if (thisProc.userId == userId) {
23481                            proc = thisProc;
23482                            break;
23483                        }
23484                    }
23485                }
23486            }
23487        }
23488
23489        return proc;
23490    }
23491
23492    public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23493            boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23494
23495        try {
23496            synchronized (this) {
23497                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23498                // its own permission (same as profileControl).
23499                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23500                        != PackageManager.PERMISSION_GRANTED) {
23501                    throw new SecurityException("Requires permission "
23502                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23503                }
23504
23505                if (fd == null) {
23506                    throw new IllegalArgumentException("null fd");
23507                }
23508
23509                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23510                if (proc == null || proc.thread == null) {
23511                    throw new IllegalArgumentException("Unknown process: " + process);
23512                }
23513
23514                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23515                if (!isDebuggable) {
23516                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23517                        throw new SecurityException("Process not debuggable: " + proc);
23518                    }
23519                }
23520
23521                proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23522                fd = null;
23523                return true;
23524            }
23525        } catch (RemoteException e) {
23526            throw new IllegalStateException("Process disappeared");
23527        } finally {
23528            if (fd != null) {
23529                try {
23530                    fd.close();
23531                } catch (IOException e) {
23532                }
23533            }
23534        }
23535    }
23536
23537    @Override
23538    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23539            String reportPackage) {
23540        if (processName != null) {
23541            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23542                    "setDumpHeapDebugLimit()");
23543        } else {
23544            synchronized (mPidsSelfLocked) {
23545                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23546                if (proc == null) {
23547                    throw new SecurityException("No process found for calling pid "
23548                            + Binder.getCallingPid());
23549                }
23550                if (!Build.IS_DEBUGGABLE
23551                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23552                    throw new SecurityException("Not running a debuggable build");
23553                }
23554                processName = proc.processName;
23555                uid = proc.uid;
23556                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23557                    throw new SecurityException("Package " + reportPackage + " is not running in "
23558                            + proc);
23559                }
23560            }
23561        }
23562        synchronized (this) {
23563            if (maxMemSize > 0) {
23564                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23565            } else {
23566                if (uid != 0) {
23567                    mMemWatchProcesses.remove(processName, uid);
23568                } else {
23569                    mMemWatchProcesses.getMap().remove(processName);
23570                }
23571            }
23572        }
23573    }
23574
23575    @Override
23576    public void dumpHeapFinished(String path) {
23577        synchronized (this) {
23578            if (Binder.getCallingPid() != mMemWatchDumpPid) {
23579                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23580                        + " does not match last pid " + mMemWatchDumpPid);
23581                return;
23582            }
23583            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23584                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23585                        + " does not match last path " + mMemWatchDumpFile);
23586                return;
23587            }
23588            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23589            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23590
23591            // Forced gc to clean up the remnant hprof fd.
23592            Runtime.getRuntime().gc();
23593        }
23594    }
23595
23596    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23597    public void monitor() {
23598        synchronized (this) { }
23599    }
23600
23601    void onCoreSettingsChange(Bundle settings) {
23602        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23603            ProcessRecord processRecord = mLruProcesses.get(i);
23604            try {
23605                if (processRecord.thread != null) {
23606                    processRecord.thread.setCoreSettings(settings);
23607                }
23608            } catch (RemoteException re) {
23609                /* ignore */
23610            }
23611        }
23612    }
23613
23614    // Multi-user methods
23615
23616    /**
23617     * Start user, if its not already running, but don't bring it to foreground.
23618     */
23619    @Override
23620    public boolean startUserInBackground(final int userId) {
23621        return mUserController.startUser(userId, /* foreground */ false);
23622    }
23623
23624    @Override
23625    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23626        return mUserController.unlockUser(userId, token, secret, listener);
23627    }
23628
23629    @Override
23630    public boolean switchUser(final int targetUserId) {
23631        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23632        int currentUserId;
23633        UserInfo targetUserInfo;
23634        synchronized (this) {
23635            currentUserId = mUserController.getCurrentUserIdLocked();
23636            targetUserInfo = mUserController.getUserInfo(targetUserId);
23637            if (targetUserId == currentUserId) {
23638                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23639                return true;
23640            }
23641            if (targetUserInfo == null) {
23642                Slog.w(TAG, "No user info for user #" + targetUserId);
23643                return false;
23644            }
23645            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23646                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23647                        + " when device is in demo mode");
23648                return false;
23649            }
23650            if (!targetUserInfo.supportsSwitchTo()) {
23651                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23652                return false;
23653            }
23654            if (targetUserInfo.isManagedProfile()) {
23655                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23656                return false;
23657            }
23658            mUserController.setTargetUserIdLocked(targetUserId);
23659        }
23660        if (mUserController.mUserSwitchUiEnabled) {
23661            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23662            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23663            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23664            mUiHandler.sendMessage(mHandler.obtainMessage(
23665                    START_USER_SWITCH_UI_MSG, userNames));
23666        } else {
23667            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23668            mHandler.sendMessage(mHandler.obtainMessage(
23669                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
23670        }
23671        return true;
23672    }
23673
23674    void scheduleStartProfilesLocked() {
23675        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23676            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23677                    DateUtils.SECOND_IN_MILLIS);
23678        }
23679    }
23680
23681    @Override
23682    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23683        return mUserController.stopUser(userId, force, callback);
23684    }
23685
23686    @Override
23687    public UserInfo getCurrentUser() {
23688        return mUserController.getCurrentUser();
23689    }
23690
23691    String getStartedUserState(int userId) {
23692        synchronized (this) {
23693            final UserState userState = mUserController.getStartedUserStateLocked(userId);
23694            return UserState.stateToString(userState.state);
23695        }
23696    }
23697
23698    @Override
23699    public boolean isUserRunning(int userId, int flags) {
23700        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23701                && checkCallingPermission(INTERACT_ACROSS_USERS)
23702                    != PackageManager.PERMISSION_GRANTED) {
23703            String msg = "Permission Denial: isUserRunning() from pid="
23704                    + Binder.getCallingPid()
23705                    + ", uid=" + Binder.getCallingUid()
23706                    + " requires " + INTERACT_ACROSS_USERS;
23707            Slog.w(TAG, msg);
23708            throw new SecurityException(msg);
23709        }
23710        synchronized (this) {
23711            return mUserController.isUserRunningLocked(userId, flags);
23712        }
23713    }
23714
23715    @Override
23716    public int[] getRunningUserIds() {
23717        if (checkCallingPermission(INTERACT_ACROSS_USERS)
23718                != PackageManager.PERMISSION_GRANTED) {
23719            String msg = "Permission Denial: isUserRunning() from pid="
23720                    + Binder.getCallingPid()
23721                    + ", uid=" + Binder.getCallingUid()
23722                    + " requires " + INTERACT_ACROSS_USERS;
23723            Slog.w(TAG, msg);
23724            throw new SecurityException(msg);
23725        }
23726        synchronized (this) {
23727            return mUserController.getStartedUserArrayLocked();
23728        }
23729    }
23730
23731    @Override
23732    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23733        mUserController.registerUserSwitchObserver(observer, name);
23734    }
23735
23736    @Override
23737    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23738        mUserController.unregisterUserSwitchObserver(observer);
23739    }
23740
23741    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23742        if (info == null) return null;
23743        ApplicationInfo newInfo = new ApplicationInfo(info);
23744        newInfo.initForUser(userId);
23745        return newInfo;
23746    }
23747
23748    public boolean isUserStopped(int userId) {
23749        synchronized (this) {
23750            return mUserController.getStartedUserStateLocked(userId) == null;
23751        }
23752    }
23753
23754    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23755        if (aInfo == null
23756                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23757            return aInfo;
23758        }
23759
23760        ActivityInfo info = new ActivityInfo(aInfo);
23761        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23762        return info;
23763    }
23764
23765    private boolean processSanityChecksLocked(ProcessRecord process) {
23766        if (process == null || process.thread == null) {
23767            return false;
23768        }
23769
23770        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23771        if (!isDebuggable) {
23772            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23773                return false;
23774            }
23775        }
23776
23777        return true;
23778    }
23779
23780    public boolean startBinderTracking() throws RemoteException {
23781        synchronized (this) {
23782            mBinderTransactionTrackingEnabled = true;
23783            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23784            // permission (same as profileControl).
23785            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23786                    != PackageManager.PERMISSION_GRANTED) {
23787                throw new SecurityException("Requires permission "
23788                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23789            }
23790
23791            for (int i = 0; i < mLruProcesses.size(); i++) {
23792                ProcessRecord process = mLruProcesses.get(i);
23793                if (!processSanityChecksLocked(process)) {
23794                    continue;
23795                }
23796                try {
23797                    process.thread.startBinderTracking();
23798                } catch (RemoteException e) {
23799                    Log.v(TAG, "Process disappared");
23800                }
23801            }
23802            return true;
23803        }
23804    }
23805
23806    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23807        try {
23808            synchronized (this) {
23809                mBinderTransactionTrackingEnabled = false;
23810                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23811                // permission (same as profileControl).
23812                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23813                        != PackageManager.PERMISSION_GRANTED) {
23814                    throw new SecurityException("Requires permission "
23815                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23816                }
23817
23818                if (fd == null) {
23819                    throw new IllegalArgumentException("null fd");
23820                }
23821
23822                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23823                pw.println("Binder transaction traces for all processes.\n");
23824                for (ProcessRecord process : mLruProcesses) {
23825                    if (!processSanityChecksLocked(process)) {
23826                        continue;
23827                    }
23828
23829                    pw.println("Traces for process: " + process.processName);
23830                    pw.flush();
23831                    try {
23832                        TransferPipe tp = new TransferPipe();
23833                        try {
23834                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23835                            tp.go(fd.getFileDescriptor());
23836                        } finally {
23837                            tp.kill();
23838                        }
23839                    } catch (IOException e) {
23840                        pw.println("Failure while dumping IPC traces from " + process +
23841                                ".  Exception: " + e);
23842                        pw.flush();
23843                    } catch (RemoteException e) {
23844                        pw.println("Got a RemoteException while dumping IPC traces from " +
23845                                process + ".  Exception: " + e);
23846                        pw.flush();
23847                    }
23848                }
23849                fd = null;
23850                return true;
23851            }
23852        } finally {
23853            if (fd != null) {
23854                try {
23855                    fd.close();
23856                } catch (IOException e) {
23857                }
23858            }
23859        }
23860    }
23861
23862    @VisibleForTesting
23863    final class LocalService extends ActivityManagerInternal {
23864        @Override
23865        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23866                int targetUserId) {
23867            synchronized (ActivityManagerService.this) {
23868                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23869                        targetPkg, intent, null, targetUserId);
23870            }
23871        }
23872
23873        @Override
23874        public String checkContentProviderAccess(String authority, int userId) {
23875            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23876        }
23877
23878        @Override
23879        public void onWakefulnessChanged(int wakefulness) {
23880            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23881        }
23882
23883        @Override
23884        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23885                String processName, String abiOverride, int uid, Runnable crashHandler) {
23886            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23887                    processName, abiOverride, uid, crashHandler);
23888        }
23889
23890        @Override
23891        public SleepToken acquireSleepToken(String tag, int displayId) {
23892            Preconditions.checkNotNull(tag);
23893            return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23894        }
23895
23896        @Override
23897        public ComponentName getHomeActivityForUser(int userId) {
23898            synchronized (ActivityManagerService.this) {
23899                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23900                return homeActivity == null ? null : homeActivity.realActivity;
23901            }
23902        }
23903
23904        @Override
23905        public void onUserRemoved(int userId) {
23906            synchronized (ActivityManagerService.this) {
23907                ActivityManagerService.this.onUserStoppedLocked(userId);
23908            }
23909            mBatteryStatsService.onUserRemoved(userId);
23910        }
23911
23912        @Override
23913        public void onLocalVoiceInteractionStarted(IBinder activity,
23914                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23915            synchronized (ActivityManagerService.this) {
23916                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23917                        voiceSession, voiceInteractor);
23918            }
23919        }
23920
23921        @Override
23922        public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23923            synchronized (ActivityManagerService.this) {
23924                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23925                        reasons, timestamp);
23926            }
23927        }
23928
23929        @Override
23930        public void notifyAppTransitionFinished() {
23931            synchronized (ActivityManagerService.this) {
23932                mStackSupervisor.notifyAppTransitionDone();
23933            }
23934        }
23935
23936        @Override
23937        public void notifyAppTransitionCancelled() {
23938            synchronized (ActivityManagerService.this) {
23939                mStackSupervisor.notifyAppTransitionDone();
23940            }
23941        }
23942
23943        @Override
23944        public List<IBinder> getTopVisibleActivities() {
23945            synchronized (ActivityManagerService.this) {
23946                return mStackSupervisor.getTopVisibleActivities();
23947            }
23948        }
23949
23950        @Override
23951        public void notifyDockedStackMinimizedChanged(boolean minimized) {
23952            synchronized (ActivityManagerService.this) {
23953                mStackSupervisor.setDockedStackMinimized(minimized);
23954            }
23955        }
23956
23957        @Override
23958        public void killForegroundAppsForUser(int userHandle) {
23959            synchronized (ActivityManagerService.this) {
23960                final ArrayList<ProcessRecord> procs = new ArrayList<>();
23961                final int NP = mProcessNames.getMap().size();
23962                for (int ip = 0; ip < NP; ip++) {
23963                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23964                    final int NA = apps.size();
23965                    for (int ia = 0; ia < NA; ia++) {
23966                        final ProcessRecord app = apps.valueAt(ia);
23967                        if (app.persistent) {
23968                            // We don't kill persistent processes.
23969                            continue;
23970                        }
23971                        if (app.removed) {
23972                            procs.add(app);
23973                        } else if (app.userId == userHandle && app.foregroundActivities) {
23974                            app.removed = true;
23975                            procs.add(app);
23976                        }
23977                    }
23978                }
23979
23980                final int N = procs.size();
23981                for (int i = 0; i < N; i++) {
23982                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
23983                }
23984            }
23985        }
23986
23987        @Override
23988        public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
23989                long duration) {
23990            if (!(target instanceof PendingIntentRecord)) {
23991                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23992                return;
23993            }
23994            synchronized (ActivityManagerService.this) {
23995                ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
23996            }
23997        }
23998
23999        @Override
24000        public void setDeviceIdleWhitelist(int[] appids) {
24001            synchronized (ActivityManagerService.this) {
24002                mDeviceIdleWhitelist = appids;
24003            }
24004        }
24005
24006        @Override
24007        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24008            synchronized (ActivityManagerService.this) {
24009                mDeviceIdleTempWhitelist = appids;
24010                setAppIdTempWhitelistStateLocked(changingAppId, adding);
24011            }
24012        }
24013
24014        @Override
24015        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24016                int userId) {
24017            Preconditions.checkNotNull(values, "Configuration must not be null");
24018            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24019            synchronized (ActivityManagerService.this) {
24020                updateConfigurationLocked(values, null, false, true, userId,
24021                        false /* deferResume */);
24022            }
24023        }
24024
24025        @Override
24026        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24027                Bundle bOptions) {
24028            Preconditions.checkNotNull(intents, "intents");
24029            final String[] resolvedTypes = new String[intents.length];
24030            for (int i = 0; i < intents.length; i++) {
24031                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24032            }
24033
24034            // UID of the package on user userId.
24035            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24036            // packageUid may not be initialized.
24037            int packageUid = 0;
24038            try {
24039                packageUid = AppGlobals.getPackageManager().getPackageUid(
24040                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24041            } catch (RemoteException e) {
24042                // Shouldn't happen.
24043            }
24044
24045            synchronized (ActivityManagerService.this) {
24046                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24047                        /*resultTo*/ null, bOptions, userId);
24048            }
24049        }
24050
24051        @Override
24052        public int getUidProcessState(int uid) {
24053            return getUidState(uid);
24054        }
24055
24056        @Override
24057        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24058            synchronized (ActivityManagerService.this) {
24059
24060                // We might change the visibilities here, so prepare an empty app transition which
24061                // might be overridden later if we actually change visibilities.
24062                final boolean wasTransitionSet =
24063                        mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24064                if (!wasTransitionSet) {
24065                    mWindowManager.prepareAppTransition(TRANSIT_NONE,
24066                            false /* alwaysKeepCurrent */);
24067                }
24068                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24069
24070                // If there was a transition set already we don't want to interfere with it as we
24071                // might be starting it too early.
24072                if (!wasTransitionSet) {
24073                    mWindowManager.executeAppTransition();
24074                }
24075            }
24076            if (callback != null) {
24077                callback.run();
24078            }
24079        }
24080
24081        @Override
24082        public boolean isSystemReady() {
24083            // no need to synchronize(this) just to read & return the value
24084            return mSystemReady;
24085        }
24086
24087        @Override
24088        public void notifyKeyguardTrustedChanged() {
24089            synchronized (ActivityManagerService.this) {
24090                if (mKeyguardController.isKeyguardShowing()) {
24091                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24092                }
24093            }
24094        }
24095
24096        /**
24097         * Sets if the given pid has an overlay UI or not.
24098         *
24099         * @param pid The pid we are setting overlay UI for.
24100         * @param hasOverlayUi True if the process has overlay UI.
24101         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24102         */
24103        @Override
24104        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24105            synchronized (ActivityManagerService.this) {
24106                final ProcessRecord pr;
24107                synchronized (mPidsSelfLocked) {
24108                    pr = mPidsSelfLocked.get(pid);
24109                    if (pr == null) {
24110                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24111                        return;
24112                    }
24113                }
24114                if (pr.hasOverlayUi == hasOverlayUi) {
24115                    return;
24116                }
24117                pr.hasOverlayUi = hasOverlayUi;
24118                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24119                updateOomAdjLocked(pr, true);
24120            }
24121        }
24122
24123        /**
24124         * Called after the network policy rules are updated by
24125         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24126         * and {@param procStateSeq}.
24127         */
24128        @Override
24129        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24130            if (DEBUG_NETWORK) {
24131                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24132                        + uid + " seq: " + procStateSeq);
24133            }
24134            UidRecord record;
24135            synchronized (ActivityManagerService.this) {
24136                record = mActiveUids.get(uid);
24137                if (record == null) {
24138                    if (DEBUG_NETWORK) {
24139                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24140                                + " procStateSeq: " + procStateSeq);
24141                    }
24142                    return;
24143                }
24144            }
24145            synchronized (record.networkStateLock) {
24146                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24147                    if (DEBUG_NETWORK) {
24148                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24149                                + " been handled for uid: " + uid);
24150                    }
24151                    return;
24152                }
24153                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24154                if (record.curProcStateSeq > procStateSeq) {
24155                    if (DEBUG_NETWORK) {
24156                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24157                                + ", curProcstateSeq: " + record.curProcStateSeq
24158                                + ", procStateSeq: " + procStateSeq);
24159                    }
24160                    return;
24161                }
24162                if (record.waitingForNetwork) {
24163                    if (DEBUG_NETWORK) {
24164                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24165                                + ", procStateSeq: " + procStateSeq);
24166                    }
24167                    record.networkStateLock.notifyAll();
24168                }
24169            }
24170        }
24171
24172        /**
24173         * Called after virtual display Id is updated by
24174         * {@link com.android.server.vr.Vr2dDisplay} with a specific
24175         * {@param vrVr2dDisplayId}.
24176         */
24177        @Override
24178        public void setVr2dDisplayId(int vr2dDisplayId) {
24179            if (DEBUG_STACK) {
24180                Slog.d(TAG, "setVr2dDisplayId called for: " +
24181                        vr2dDisplayId);
24182            }
24183            synchronized (ActivityManagerService.this) {
24184                mVr2dDisplayId = vr2dDisplayId;
24185            }
24186        }
24187
24188        @Override
24189        public void saveANRState(String reason) {
24190            synchronized (ActivityManagerService.this) {
24191                final StringWriter sw = new StringWriter();
24192                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24193                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24194                if (reason != null) {
24195                    pw.println("  Reason: " + reason);
24196                }
24197                pw.println();
24198                mActivityStarter.dump(pw, "  ", null);
24199                pw.println();
24200                pw.println("-------------------------------------------------------------------------------");
24201                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24202                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24203                        "" /* header */);
24204                pw.println();
24205                pw.close();
24206
24207                mLastANRState = sw.toString();
24208            }
24209        }
24210
24211        @Override
24212        public void clearSavedANRState() {
24213            synchronized (ActivityManagerService.this) {
24214                mLastANRState = null;
24215            }
24216        }
24217
24218        @Override
24219        public void setFocusedActivity(IBinder token) {
24220            synchronized (ActivityManagerService.this) {
24221                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24222                if (r == null) {
24223                    throw new IllegalArgumentException(
24224                            "setFocusedActivity: No activity record matching token=" + token);
24225                }
24226                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24227                        r, "setFocusedActivity")) {
24228                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
24229                }
24230            }
24231        }
24232    }
24233
24234    /**
24235     * Called by app main thread to wait for the network policy rules to get updated.
24236     *
24237     * @param procStateSeq The sequence number indicating the process state change that the main
24238     *                     thread is interested in.
24239     */
24240    @Override
24241    public void waitForNetworkStateUpdate(long procStateSeq) {
24242        final int callingUid = Binder.getCallingUid();
24243        if (DEBUG_NETWORK) {
24244            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24245        }
24246        UidRecord record;
24247        synchronized (this) {
24248            record = mActiveUids.get(callingUid);
24249            if (record == null) {
24250                return;
24251            }
24252        }
24253        synchronized (record.networkStateLock) {
24254            if (record.lastDispatchedProcStateSeq < procStateSeq) {
24255                if (DEBUG_NETWORK) {
24256                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24257                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24258                            + " lastProcStateSeqDispatchedToObservers: "
24259                            + record.lastDispatchedProcStateSeq);
24260                }
24261                return;
24262            }
24263            if (record.curProcStateSeq > procStateSeq) {
24264                if (DEBUG_NETWORK) {
24265                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24266                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24267                            + ", procStateSeq: " + procStateSeq);
24268                }
24269                return;
24270            }
24271            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24272                if (DEBUG_NETWORK) {
24273                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24274                            + procStateSeq + ", so no need to wait. Uid: "
24275                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24276                            + record.lastNetworkUpdatedProcStateSeq);
24277                }
24278                return;
24279            }
24280            try {
24281                if (DEBUG_NETWORK) {
24282                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24283                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24284                }
24285                final long startTime = SystemClock.uptimeMillis();
24286                record.waitingForNetwork = true;
24287                record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24288                record.waitingForNetwork = false;
24289                final long totalTime = SystemClock.uptimeMillis() - startTime;
24290                if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24291                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24292                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24293                            + procStateSeq + " UidRec: " + record
24294                            + " validateUidRec: " + mValidateUids.get(callingUid));
24295                }
24296            } catch (InterruptedException e) {
24297                Thread.currentThread().interrupt();
24298            }
24299        }
24300    }
24301
24302    public void waitForBroadcastIdle(PrintWriter pw) {
24303        enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24304        while (true) {
24305            boolean idle = true;
24306            synchronized (this) {
24307                for (BroadcastQueue queue : mBroadcastQueues) {
24308                    if (!queue.isIdle()) {
24309                        final String msg = "Waiting for queue " + queue + " to become idle...";
24310                        pw.println(msg);
24311                        pw.flush();
24312                        Slog.v(TAG, msg);
24313                        idle = false;
24314                    }
24315                }
24316            }
24317
24318            if (idle) {
24319                final String msg = "All broadcast queues are idle!";
24320                pw.println(msg);
24321                pw.flush();
24322                Slog.v(TAG, msg);
24323                return;
24324            } else {
24325                SystemClock.sleep(1000);
24326            }
24327        }
24328    }
24329
24330    /**
24331     * Return the user id of the last resumed activity.
24332     */
24333    @Override
24334    public @UserIdInt int getLastResumedActivityUserId() {
24335        enforceCallingPermission(
24336                permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24337        synchronized (this) {
24338            if (mLastResumedActivity == null) {
24339                return mUserController.getCurrentUserIdLocked();
24340            }
24341            return mLastResumedActivity.userId;
24342        }
24343    }
24344
24345    /**
24346     * An implementation of IAppTask, that allows an app to manage its own tasks via
24347     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24348     * only the process that calls getAppTasks() can call the AppTask methods.
24349     */
24350    class AppTaskImpl extends IAppTask.Stub {
24351        private int mTaskId;
24352        private int mCallingUid;
24353
24354        public AppTaskImpl(int taskId, int callingUid) {
24355            mTaskId = taskId;
24356            mCallingUid = callingUid;
24357        }
24358
24359        private void checkCaller() {
24360            if (mCallingUid != Binder.getCallingUid()) {
24361                throw new SecurityException("Caller " + mCallingUid
24362                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24363            }
24364        }
24365
24366        @Override
24367        public void finishAndRemoveTask() {
24368            checkCaller();
24369
24370            synchronized (ActivityManagerService.this) {
24371                long origId = Binder.clearCallingIdentity();
24372                try {
24373                    // We remove the task from recents to preserve backwards
24374                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24375                            REMOVE_FROM_RECENTS)) {
24376                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24377                    }
24378                } finally {
24379                    Binder.restoreCallingIdentity(origId);
24380                }
24381            }
24382        }
24383
24384        @Override
24385        public ActivityManager.RecentTaskInfo getTaskInfo() {
24386            checkCaller();
24387
24388            synchronized (ActivityManagerService.this) {
24389                long origId = Binder.clearCallingIdentity();
24390                try {
24391                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24392                    if (tr == null) {
24393                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24394                    }
24395                    return createRecentTaskInfoFromTaskRecord(tr);
24396                } finally {
24397                    Binder.restoreCallingIdentity(origId);
24398                }
24399            }
24400        }
24401
24402        @Override
24403        public void moveToFront() {
24404            checkCaller();
24405            // Will bring task to front if it already has a root activity.
24406            final long origId = Binder.clearCallingIdentity();
24407            try {
24408                synchronized (this) {
24409                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24410                }
24411            } finally {
24412                Binder.restoreCallingIdentity(origId);
24413            }
24414        }
24415
24416        @Override
24417        public int startActivity(IBinder whoThread, String callingPackage,
24418                Intent intent, String resolvedType, Bundle bOptions) {
24419            checkCaller();
24420
24421            int callingUser = UserHandle.getCallingUserId();
24422            TaskRecord tr;
24423            IApplicationThread appThread;
24424            synchronized (ActivityManagerService.this) {
24425                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24426                if (tr == null) {
24427                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24428                }
24429                appThread = IApplicationThread.Stub.asInterface(whoThread);
24430                if (appThread == null) {
24431                    throw new IllegalArgumentException("Bad app thread " + appThread);
24432                }
24433            }
24434            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24435                    resolvedType, null, null, null, null, 0, 0, null, null,
24436                    null, bOptions, false, callingUser, tr, "AppTaskImpl");
24437        }
24438
24439        @Override
24440        public void setExcludeFromRecents(boolean exclude) {
24441            checkCaller();
24442
24443            synchronized (ActivityManagerService.this) {
24444                long origId = Binder.clearCallingIdentity();
24445                try {
24446                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24447                    if (tr == null) {
24448                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24449                    }
24450                    Intent intent = tr.getBaseIntent();
24451                    if (exclude) {
24452                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24453                    } else {
24454                        intent.setFlags(intent.getFlags()
24455                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24456                    }
24457                } finally {
24458                    Binder.restoreCallingIdentity(origId);
24459                }
24460            }
24461        }
24462    }
24463
24464    /**
24465     * Kill processes for the user with id userId and that depend on the package named packageName
24466     */
24467    @Override
24468    public void killPackageDependents(String packageName, int userId) {
24469        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24470        if (packageName == null) {
24471            throw new NullPointerException(
24472                    "Cannot kill the dependents of a package without its name.");
24473        }
24474
24475        long callingId = Binder.clearCallingIdentity();
24476        IPackageManager pm = AppGlobals.getPackageManager();
24477        int pkgUid = -1;
24478        try {
24479            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24480        } catch (RemoteException e) {
24481        }
24482        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24483            throw new IllegalArgumentException(
24484                    "Cannot kill dependents of non-existing package " + packageName);
24485        }
24486        try {
24487            synchronized(this) {
24488                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24489                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24490                        "dep: " + packageName);
24491            }
24492        } finally {
24493            Binder.restoreCallingIdentity(callingId);
24494        }
24495    }
24496
24497    @Override
24498    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24499            throws RemoteException {
24500        final long callingId = Binder.clearCallingIdentity();
24501        try {
24502            mKeyguardController.dismissKeyguard(token, callback);
24503        } finally {
24504            Binder.restoreCallingIdentity(callingId);
24505        }
24506    }
24507
24508    @Override
24509    public int restartUserInBackground(final int userId) {
24510        return mUserController.restartUser(userId, /* foreground */ false);
24511    }
24512
24513    @Override
24514    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24515        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24516                "scheduleApplicationInfoChanged()");
24517
24518        synchronized (this) {
24519            final long origId = Binder.clearCallingIdentity();
24520            try {
24521                updateApplicationInfoLocked(packageNames, userId);
24522            } finally {
24523                Binder.restoreCallingIdentity(origId);
24524            }
24525        }
24526    }
24527
24528    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24529        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24530        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24531            final ProcessRecord app = mLruProcesses.get(i);
24532            if (app.thread == null) {
24533                continue;
24534            }
24535
24536            if (userId != UserHandle.USER_ALL && app.userId != userId) {
24537                continue;
24538            }
24539
24540            final int packageCount = app.pkgList.size();
24541            for (int j = 0; j < packageCount; j++) {
24542                final String packageName = app.pkgList.keyAt(j);
24543                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24544                    try {
24545                        final ApplicationInfo ai = AppGlobals.getPackageManager()
24546                                .getApplicationInfo(packageName, 0 /*flags*/, app.userId);
24547                        if (ai != null) {
24548                            app.thread.scheduleApplicationInfoChanged(ai);
24549                        }
24550                    } catch (RemoteException e) {
24551                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24552                                    packageName, app));
24553                    }
24554                }
24555            }
24556        }
24557    }
24558
24559    /**
24560     * Attach an agent to the specified process (proces name or PID)
24561     */
24562    public void attachAgent(String process, String path) {
24563        try {
24564            synchronized (this) {
24565                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24566                if (proc == null || proc.thread == null) {
24567                    throw new IllegalArgumentException("Unknown process: " + process);
24568                }
24569
24570                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24571                if (!isDebuggable) {
24572                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24573                        throw new SecurityException("Process not debuggable: " + proc);
24574                    }
24575                }
24576
24577                proc.thread.attachAgent(path);
24578            }
24579        } catch (RemoteException e) {
24580            throw new IllegalStateException("Process disappeared");
24581        }
24582    }
24583
24584    @VisibleForTesting
24585    public static class Injector {
24586        private NetworkManagementInternal mNmi;
24587
24588        public Context getContext() {
24589            return null;
24590        }
24591
24592        public AppOpsService getAppOpsService(File file, Handler handler) {
24593            return new AppOpsService(file, handler);
24594        }
24595
24596        public Handler getUiHandler(ActivityManagerService service) {
24597            return service.new UiHandler();
24598        }
24599
24600        public boolean isNetworkRestrictedForUid(int uid) {
24601            if (ensureHasNetworkManagementInternal()) {
24602                return mNmi.isNetworkRestrictedForUid(uid);
24603            }
24604            return false;
24605        }
24606
24607        private boolean ensureHasNetworkManagementInternal() {
24608            if (mNmi == null) {
24609                mNmi = LocalServices.getService(NetworkManagementInternal.class);
24610            }
24611            return mNmi != null;
24612        }
24613    }
24614
24615    @Override
24616    public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24617            throws RemoteException {
24618        synchronized (this) {
24619            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24620            if (r == null) {
24621                return;
24622            }
24623            final long origId = Binder.clearCallingIdentity();
24624            try {
24625                r.setShowWhenLocked(showWhenLocked);
24626            } finally {
24627                Binder.restoreCallingIdentity(origId);
24628            }
24629        }
24630    }
24631
24632    @Override
24633    public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24634        synchronized (this) {
24635            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24636            if (r == null) {
24637                return;
24638            }
24639            final long origId = Binder.clearCallingIdentity();
24640            try {
24641                r.setTurnScreenOn(turnScreenOn);
24642            } finally {
24643                Binder.restoreCallingIdentity(origId);
24644            }
24645        }
24646    }
24647}
24648